150 likes | 301 Views
Writing LISP functions. COND. Rule 1: Unless the function is extremely simple, begin with a COND If you can write the function body in one line, do it. If it's more complicated, use COND to break it into cases. NULL.
E N D
COND • Rule 1: Unless the function is extremely simple, begin with a COND • If you can write the function body in one line, do it. • If it's more complicated, use CONDto break it into cases.
NULL • Rule 2: Test for a base case first—this usually means testing for NULL (empty) list • You should always handle the base (simplest) cases first. • When you are working with lists, the simplest case is usually the empty list. • Usually, you recur with the CDR of the list.
Avoid multiple base cases • Rule 2a: Avoid having more than one base case. • You must always recur with a simpler case. • When you are working with lists, the simplest case is usually the empty list. • Usually, you recur with the CDR of the list.
Example: multiple base cases (DEFUN UNION (SET1 SET2) (COND ((NULL SET1) SET2)((NULL SET2) SET1) ; bad idea! ((MEMBER (CAR SET1) SET2) (UNION (CDR SET1) SET2)) (T (CONS (CAR SET1) (UNION (CDR SET1) SET2))) ) ) )
Use CAR, recur with CDR • Rule 3: Do something with the CAR, and recur with the CDR. • Recursion involves doing some nonrecursive work, doing some recursive work, and combining the two. • You typically do the simple work on the CAR and recur with the CDR, then combine.
Deleting elements • Rule 3a: To delete the CAR, just ignore it and recur with the CDR. • Rule 3b: To keep the CAR unchanged, CONS it onto the result of recurring with the CDR. • Extra work: deciding whether to keep the CAR. • Combining results: adding the CAR to the result of recurring with the CDR.
Example:Removing atoms from a list (DEFUN REMATOMS (L) (COND ((NULL L) L) ((ATOM (CAR L)) (REMATOMS (CDR L))) (T (CONS (CAR L) (REMATOMS (CDR L)))) ) ) 1 2 3a 3b
Transforming elements • Rule 3c: To transform the elements of a list, CONS the transformed CAR onto the result of recurring with the CDR. • Extra work: transforming the CAR. • Recur: with the CDR, as usual. • Combine the results with CONS.
Example:Adding one to each element (DEFUN ADDONE (L) (COND ((NULL L) L) (T (CONS (1+ (CAR L)) (ADDONE (CDR L)))) ) ) 1 2 3c
Accumulating information • Rule 4: In each case of a COND you can use the fact that all previous tests have failed. • If you have tested whether a list is empty, later cases can take its CAR and CDR. • If you have decided that the CAR is of no interest, you can ignore it and use the CDR.
Example of accumulating information • In fact, every time you use COND you are accumulating information as you go (DEFUN MEMBER (A LAT) (COND ((NULL LAT) NIL) ((EQ A (CAR LAT)) T) (T (MEMBER A (CDR LAT))) ) ) 4 4
Ending the COND • Rule 5: UseTas the last test in a COND. • If you “flow off the end” of a COND, the result is undefined. This is a Bad Thing. • You want to be sure you cover every case, but sometimes there are unexpected cases. • Not every integer is positive, negative, or zero. • Tprotects you from the forgotten cases.
Example: UNION (DEFUN UNION (SET1 SET2) (COND ((NULL SET1) SET2) ((MEMBER (CAR SET1) SET2) (UNION (CDR SET1) SET2)) (T (CONS (CAR SET1) (UNION (CDR SET1) SET2))) ) ) ) 1 2 3,3a 5, 3, 3b