1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-20 09:55:52 +00:00
PDP-10.its/src/teach/lesson.lambda
2018-10-28 16:47:17 -07:00

144 lines
5.3 KiB
Plaintext
Executable File

.comment -*- Mode:TEXT; -*-
.document LAMBDA - Description of the special form LAMBDA.
.tag LAMBDA
Lesson LAMBDA, Version 3 Kent M. Pitman, 1/22/80
revised by Victoria Pigman, 9/1/82
LAMBDA is not a function. Lists of a certain form which begin with the atom
LAMBDA are specially recognized by Lisp to describe functional operations.
For example, suppose I wanted to describe a function which operated on two
objects and found the sum of their squares. I could describe such a function
in Lisp as follows...
(LAMBDA (OBJECT1 OBJECT2) ; This is a list of the objects
; we are working with...
(+ (* OBJECT1 OBJECT1) ; This is an operation to do
(* OBJECT2 OBJECT2)) ; on the object.
)
The general form of a LAMBDA expression is:
(LAMBDA <bvl> <form1> <form2> ... <formN>)
where <bvl> means "bound variable list". This is a list of the names which
you wish to use locally to refer to the objects to which the function will
be applied. These values to which the function is being applied are called
the `actual parameters' or `actual arguments' or sometimes just `actuals';
the names which you are assigning to them in the bound variable list of the
formal lambda definition are called `formal parameters' or `formal arguments'
or (you guessed it) just `formals.'
<form1> ... <formN> are Lisp expressions which will be evaluated from left to
right, returning the value of the last form.
Be careful, because if you just type (LAMBDA (X Y) (* X Y)) into Lisp you'll
get an error. Lisp will complain that LAMBDA is not a function, since when it
sees a list it looks at the CAR for what to do. Lisp only understands lists
with LAMBDA in the CAR when it wants to apply the list. Just saying
(LAMBDA (VALUE1 VALUE2) (PLUS VALUE1 VALUE2))
is like saying
PLUS
When found in the CAR of a list, they both have special meaning, i.e. they
designate a functional operation, but on their own, they are meaningless.
Try typing these two and see what happens (expect an error ... you will be
asked if you want help with the type of error you got. Look if it interests
you, but then come back to me.)
.try
Functional operators must be applied. Since Lisp applies the CAR of a form to
its CDR, we can use LAMBDA in the same way as you would use any function. Since
you would say
(PLUS 7 B)
(assuming B has a value) you must also put LAMBDA expressions in the CAR of the
list, like so:
((LAMBDA (VALUE1 VALUE2)
(PLUS (* VALUE1 VALUE1)
(* VALUE2 VALUE2)))
7 B)
.eval
(progn
(format t "~&")
(cond ((not (boundp 'B))
(setq b 3)
(format t "(B has been given a value of 3 for your convenience)"))
((not (numberp B))
(format t "You have assigned a non-numeric value to B, ~
so you should pick another value to use instead."))))
.try
A form which contains a LAMBDA expression (which we sometimes call a LAMBDA
operator) applied to some arguments is called a LAMBDA combination.
LAMBDA combinations have the general form:
((LAMBDA <bound-variable-list> <form1> <form2> ...)
<arg1> <arg2> ... )
where the number of <arg>'s must be equal to the number of elements in the
bound variable list.
When a LAMBDA combination is executed, the following steps are taken in this
order:
(1) The actual args, <arg1> ... <argN> in the above example,
are evaluated in order from LEFT to RIGHT.
(2) When all values have been computed, the old values of all
the symbols in the bound variable list (if they had old
values) are saved in a place where they can be gotten back
later. Then the symbols are assigned the new local values
which were gotten by evaluating the actual arguments. This
process is called binding (which is why the list of local
variables is called a bound variable list).
(3) The body of the LAMBDA expression is executed in a context
in which the local variables are bound to these values.
(4) The value returned by the last expression in a LAMBDA
will be returned from a LAMBDA.
(5) Unbeknownst to you (practically), Lisp goes and restores the
old values of the variables in the bound variable list so
that if any other functions had been using them as storage
places, they won't be confused by having called your
function.
Try some of these examples:
((LAMBDA (X) (+ (* X X) (* 2 X) 1)) 3)
((LAMBDA (X) (^ (+ X 1) 2)) 3) ; Does same thing as the one above it
((LAMBDA (A B C)
(PRINT (LIST 'GOT-THE-ARGUMENTS A B C)) ; Print out info
(+ A B C)) ; Return their sum
3 4 5) ; Actual arguments to the function description
.try
LAMBDA expressions do not need to have any variables in their bound variable
list. If they have no variables, they need have no arguments ... Here is an
example ...
((LAMBDA () T))
These may seem useless, but they illustrate an important concept. A LAMBDA
expression is a functional description, and we can describe any kind of
function, including one with no arguments. LAMBDA's are often used when we
wish to build a function to pass to another function which will then use it
for its own purposes; in such a circumstance a function of no arguments can be
useful.
In fact, people rarely use un-named LAMBDA's at all. If you are going to do
an operation more than once, it makes sense to assign it a name and call it by
name. What you want to do now is proceed to (LESSON DEFUN) where you can learn
all about naming your LAMBDA's for later use.
.next DEFUN