1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-03 07:20:35 +00:00
Files
PDP-10.its/src/teach/lesson.defun
2018-10-28 16:47:17 -07:00

110 lines
3.7 KiB
Plaintext
Executable File

.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 <function-name> <bvl> <form1> <form2> ...)
This associates the lambda expression
(LAMBDA <bvl> <form1> <form2> ...)
with <function-name> in a way that Lisp's evaluator knows how to find when
you put <function-name> 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