Writing Lisp Functions

Download Report

Transcript Writing Lisp Functions

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
• 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
1
((NULL L) L)
2
3a ((ATOM (CAR L)) (REMATOMS (CDR L)))
3b (T (CONS (CAR L) (REMATOMS (CDR L)))) ) )
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)
1
(COND
((NULL L) L)
2
(T (CONS (1+ (CAR L))
3c
(ADDONE (CDR L)))) ) )
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
(DEFUN MEMBER (A LAT)
(COND
((NULL LAT) NIL)
4
((EQ A (CAR LAT)) T)
(T (MEMBER A (CDR LAT))) ) )
4
• In fact, every time you use COND you are
accumulating information as you go
Ending the COND
• Rule 5: Use T as 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.
• T protects you from the forgotten cases.
Example: UNION
(DEFUN UNION (SET1 SET2)
1
(COND
((NULL SET1) SET2)
2
((MEMBER (CAR SET1) SET2)
3,
3a
(UNION (CDR SET1) SET2))
5, 3, 3b (T (CONS (CAR SET1)
(UNION (CDR SET1) SET2))) ) ) )
The End