mirror of
https://github.com/PDP-10/its.git
synced 2026-03-24 17:36:15 +00:00
103 lines
4.0 KiB
Plaintext
Executable File
103 lines
4.0 KiB
Plaintext
Executable File
.comment -*- Mode:TEXT; -*-
|
|
.comment shows them how to write FIB and FACT and talks about recursion
|
|
.comment and scope of variable bindings.
|
|
.document FIB - Examples of how to write two simple recursive Lisp functions.
|
|
.tag FIB
|
|
Lesson FIB, Version 2 Revised by Victoria Pigman, 9/1/82
|
|
|
|
This lesson is designed to give you an introduction to writing actual
|
|
programs in Lisp. The first example we shall use is the Fibonacci
|
|
function. Later we shall play with Factorial. Aren't we lucky!
|
|
|
|
|
|
--- FIBONACCI ---
|
|
|
|
Just as a reminder as to what the Fibonacci function is, (which I shall
|
|
call FIB from here on...) let me give the definition:
|
|
|
|
FIB (0) = 1
|
|
FIB (1) = 1
|
|
FIB (N) = FIB (N-1) + FIB (N-2)
|
|
|
|
This type of definition is called RECURSIVE, becuase FIB is defined in
|
|
terms of previous values of FIB until it gets to a value it knows (1 or 0).
|
|
|
|
We have defined for you a function FIB which will do this in a similar manner.
|
|
|
|
.eval-print
|
|
(DEFUN FIB (N)
|
|
(COND ((= N 0) 1)
|
|
((= N 1) 1)
|
|
(T (+ (FIB (1- N))
|
|
(FIB (- N 2))))))
|
|
|
|
[Note: The function = returns T if its arguments are equal (they must be
|
|
integer numbers) and NIL otherwise. The function 1- returns one less
|
|
than its argument. (1- n) could have been written (- n 1)]
|
|
|
|
|
|
Play with this for a while to convince yourself it does what it claims. If
|
|
you have difficulty, try it out in pieces. That is, pick an n for yourself
|
|
and decide whether:
|
|
(= n 0)
|
|
is true, and if so, say 1. If you've decided that was false, then decide about
|
|
(= n 1)
|
|
and again say 1 if it returns T. Otherwise, start on
|
|
(fib (1- n))
|
|
etc. until it becomes clear. In other words, play computer and follow through
|
|
the algorithm.
|
|
.try
|
|
|
|
Note that the function doesn't get confused when you call it from itself. In
|
|
languages like FORTRAN this would not be the case (in FORTRAN it would even get
|
|
confused trying to return and would loop endlessly). The reason it doesn't get
|
|
confused is that every atom on the bound variable list gets a new value that
|
|
merely OBSCURES the old one; it doesn't destroy the old one. The new value goes
|
|
away when the function is exited. In other words, the SCOPE of the value is
|
|
just inside the call to the function. So, if you say (FIB 0) after FIB returns
|
|
1, N will have the same value it had before (FIB 0) was called. If it had been
|
|
previously undefined, it will still be undefined.
|
|
|
|
|
|
--- FACTORIAL ---
|
|
|
|
Now let's play with FACTORIAL. (Let's call it FACT for short.) To remind you
|
|
of what factorial does, here's its definition:
|
|
|
|
FACT (0) is 1
|
|
FACT (1) is 1
|
|
FACT (N) is N*FACT (N-1)
|
|
|
|
Since you've seen how we go from the definition of FIB to the actual program,
|
|
it's your turn to try on factorial.
|
|
|
|
Please don't continue until you think you have got it, as I will give the
|
|
solution in the next section.
|
|
.try
|
|
|
|
Did it look something like this?
|
|
.pp
|
|
(DEFUN FACT (N)
|
|
(COND ((= N 0) 1) ; necessary for the case n=0...
|
|
((= N 1) 1) ; is this one necessary at all?
|
|
(T (* N (FACT (-1 N))))))
|
|
|
|
|
|
Note that it is possible for one function to call another, and indeed all
|
|
large programs are written like this. This is the basis behind structured
|
|
programming, i.e. you write a program and wherever you need to do something
|
|
complicated, you just say (PERFORM-HAIRY-OPERATION-ON <ARGUMENTS>) and then
|
|
when you are done, you write a function PERFORM-HAIRY-OPERATION-ON which is
|
|
simpler than writing the whole big problem, and the hard parts you just call
|
|
a function to do and write that function later. You don't write the smaller
|
|
functions until you know exactly what they have to do, and you can call them
|
|
in your definitions of the larger operation just like they were pre-defined
|
|
functions. But don't forget to write them before you are done! The system will
|
|
complain about functions which are not defined when you actually try to use the
|
|
function.
|
|
|
|
OK, that's the end of this lesson. There will be more of them soon, and we
|
|
will get into some more ways of writing programs and just how to handle more
|
|
complicated objects and problems.
|
|
.next MEMQ
|