.comment -*- Mode:TEXT; -*- .comment Documentation about DEFUN. .document DEFUN - How to use DEFUN to make your own functions. .tag DEFUN Lesson DEFUN, Version 3 Kent M. Pitman 1/22/80 revised by Victoria Pigman 9/1/82 You may find it very advantageous to assign names to LAMBDA's. The mechanism for doing this in Lisp is called DEFUN. If you have not read about LAMBDA's yet, you should definitely kill this lesson right now and do (LESSON LAMBDA) before proceeding... The form of a DEFUN is similar to that of LAMBDA -- (DEFUN ...) This associates the lambda expression (LAMBDA ...) with in a way that Lisp's evaluator knows how to find when you put in the CAR of a list. Thus if you do (DEFUN X-PLUS-ONE-SQUARED (X) (+ (* X X) (* X 2) 1.)) you will get back X-PLUS-ONE-SQUARED (DEFUN always returns the name of the function it has defined) and from then on (until/unless you redefine this function) you will be able to just say (X-PLUS-ONE-SQUARED 3) ; Returns 4 squared, or 16 See if you can type in that definition and get it to work on a few numbers. .try Note also that you can try it on more complicated expressions -- (X-PLUS-ONE-SQUARED (X-PLUS-ONE-SQUARED 1)) for example, will return (I hope) 25 ... I haven't tried this function -- maybe you should check it out for me. .try Here's a really interesting idea which will get touched again in other lessons. It's a key feature of Lisp -- the ability to do recursion (or allow functions to reference themselves). For example, suppose someone asked you how to climb to the top of a staircase of a specified number of stairs. You might, if you'd read (LESSON DO), reply to him ... .eval-print (DEFUN CLIMB-STAIRS (NUMBER-OF-STAIRS) (DO ((I 0 (+ 1 I))) ((= I NUMBER-OF-STAIRS)) (PRINT '(CLIMB UP A STAIR))) (PRINT '(WE MUST BE DONE))) This function has been defined for you, so try running it on some small number of stairs. .try That's one way to do it, I guess. Another way to formulate the same problem is this one ... .eval-print (DEFUN CLIMB-STAIRS-ANOTHER-WAY (NUMBER-OF-STAIRS) (COND ((= NUMBER-OF-STAIRS 0) (PRINT '(WE MUST BE DONE))) (T (PRINT '(CLIMB UP A STAIR)) (CLIMB-STAIRS-ANOTHER-WAY (- NUMBER-OF-STAIRS 1))))) Do you see how this works? If we're at the top, we should just stop. Otherwise, we'll put off figuring out how to do the real task for a minute -- just climb one stair for now -- and then we'll go and climb one less stair ... How do we do that? The same way as we've just described ... before we know it, we're at the top! (This one has also been defined for you.) .try Here is another simple recursive function to try: Write a function which makes a list of the numbers 1 through N and returns it. Remember that a list of no numbers is NIL and that you can add a new number to a list by doing (CONS number old-list). Don't come back until you've given up! .try Did it look something like this...? .eval-print (DEFUN MAKE-LIST-N-LONG (N) (COND ((= N 0) NIL) (T (CONS N (MAKE-LIST-N-LONG (- N 1)))))) This function has been defined for you, so run it. Do you notice something funny about the result it returns? What might you do to fix that problem? (Hint: You might want to re-write this idea to use two functions instead of one.) .try The solution to this problem is to make two functions. They might look like these that I've written for you -- .eval-print (DEFUN MAKE-LIST-N-LONG (N) (REVERSE (MAKE-BACKWARDS-LIST-N-LONG N))) .eval-print (DEFUN MAKE-BACKWARDS-LIST-N-LONG (N) (COND ((= N 0) NIL) (T (CONS N (MAKE-BACKWARDS-LIST-N-LONG (- N 1)))))) .next OUTPUT