.comment -*- Mode:TEXT; -*- .comment this file gives basic info about atoms and values and then .comment calls the lesson that introduces lists. .document INTRO - Basic lesson. If you're new, start with this lesson. .tag INTRO Lesson INTRO, version 4 by Robert Kerns and Victoria Pigman 9/1/82 IF YOU NEED HELP, just type (HELP). If nothing happens, try typing control-G (^G) first. ^G is the magic quit character which will reset every thing to normal. If things don't work,try ^G, then retry.... --- SYMBOLS, NUMBERS, and things --- For the purposes of this course, LISP has two basic kinds of objects-- ATOMS and LISTS. The first group includes such things as variable names (called SYMBOLS), numbers (called FIXNUMS, FLONUMS, or BIGNUMS for integers, floating-point numbers, and HUGE integers), files, arrays, and several other types of objects. The second group, LISTS, are composites. A list consists of a (possibly empty) list of atoms or other lists. Hence: A -- is an atom. ATOM -- is an atom. (A) -- is the list of the atom A. (A ATOM) -- is the list of the atoms A and ATOM. NIL -- is the empty list. Oddly enough, NIL is also an atom (because you cannot get any smaller-- just like A can't). () -- Another way of writing NIL (the null list). (()) -- The list of the null list. (NIL) -- The list of the null list. (NIL A) -- The list of the null list and A. ((A B) C (D E)) -- See if you can figure this one out. There are other kinds of atoms besides things like A and (), such as numbers, but for the moment we shall deal with () and those atoms called SYMBOLS. It is SYMBOLS that we use for what other languages use variables for. However, in LISP they are put to a lot of other uses as well. This is part of what makes LISP such an interesting language. .pause --- Talking to LISP --- Before you can try any of this out, you must first know about what Lisp tries .if (status feature ITS) to do. When you do :TEACH;LISP (or LISP^K--but use :TEACH;LISP please) LISP .if (status feature TOPS-20) to do. When you do XTEACH (or LISP -- but use XTEACH please) LISP .end-if sits listening for a form to evaluate. You cannot just type A, because it will try to evaluate A and A doesn't have a value until you give it one. To get around that we use the magic function QUOTE. QUOTE, when applied to something, just returns what it was applied to without evaluating it. [To apply something, just put parentheses around it and its argument. More on this in a bit.]. Hence, (QUOTE FOO) evaluates to FOO, (QUOTE (FOO BAR STUFF)) evaluates to (FOO BAR STUFF) (QUOTE QUOTE) evaluates to QUOTE, and (QUOTE (QUOTE FOO)) evaluates to (QUOTE FOO). However, it is a pain to be always typing (QUOTE ), so an easier way was invented-- the character "'". It is used like this: 'FOO When this is read, it becomes: (QUOTE FOO), which is then evaluated normally, giving: FOO. Thus, the expression: '(FOO BAR STUFF) will evaluate to (FOO BAR STUFF). (Always remember that when typing atoms one must end with a space or CR. This is not necessary when ending a list, however.) .try --- LIST functions --- Now let's analyze some list structure. Consider: ((THIS IS) A (LIST OF STUFF)) .eval (setq this-stuff '((this is) a (list of stuff)) apple '(apple) fish '(can fly) pig '(alive future-pork-of-america) pork '(chops) pie '(cherry lemon apple) dog '(terrier afghan poodle runt) cat '(siamese purrrsian alley tiger purring pussy cheshire) man '((complex) (entity called) man (is (a many (leveled) beast)))) "THIS-STUFF" has been given a value. Find out "THIS-STUFF"'s value, by typing: THIS-STUFF followed by a space. .try The following symbols have been given values for you to use in the following questions: APPLE FISH PIG PORK PIE DOG CAT MAN There are two basic functions to take lists apart into their pieces. The first of these is called CAR for historical reasons. Now find out the value of (CAR this-stuff) .try As you saw, CAR gets you the first part of the list. It is illegal to try to take the CAR of something other than a list. The other operation gets you the rest of the list; that is, all of the list except the CAR. Try taking the CDR of "THIS-STUFF" now, by typing (cdr this-stuff) Note that upper/lower case do not matter. .try As we have seen, each list is composed of exactly two parts,the CAR and the CDR. Each of these parts may be composed of many parts. For example, take the CAR of both the CAR and the CDR of "THIS-STUFF" via (car (car this-stuff)) and (car (cdr this-stuff)) .try Now take the CDR of the CDR of the CDR and note that the operation CDR always gives a list. That isn't quite always true, but for our purposes, we can say that the CDR of a list is always a list. .try --- CONS --- There is only one operation really needed to construct lists, and it is called CONS. CONS takes two arguments. The first argument becomes the CAR of the new list while the second becomes the CDR. Note that this means that the second argument must always be a list. Now create a few lists. Don't forget to quote the arguments if you don't want their values instead... Of course, you can CONS things with "THIS-STUFF" or FOO. (Be careful with FOO, it has no value yet!) .try Now do: (CONS 'FOO THIS-STUFF) and then find out the value of "THIS-STUFF". .try Notice that this did not have any effect on the value of "THIS-STUFF". CONS returns an entirely NEW OBJECT, which points to FOO and the same thing that THIS-STUFF points to. .try --- Number functions --- Now we are ready to learn about numbers. We shall stick to integers for now. Type 5 and see what happens. Don't forget the space after it! .try Numbers do not need to be quoted, because they evaluate to themselves. Now find the value of: (CONS 5 '(6)) But note that just because 6 evaluates to itself doesn't mean that (6) does! .try Ok, numbers can be elements of lists just like anything else. But let's do some number things with numbers. Type (+ 5 6). .try I'll bet you expected that one. Now try the following functions: \, //, *, - on the numbers 7 and 23 and any others you want. .try OK, now did you get them? // is the division operator, dividing the first argument by the second; \ is the remainder from this division: (\ 5 7) ==> 7; * multiplies, and - subtracts. Now, for a surprise, try: (+ 1 2 3 4). .try See, we can add a bunch at a time. We can also do this for multiplication: (* 5 6 9). .try --- DEFUN --- Now for a brief introduction to DEFUN. Later on there is another lesson (DEFUN) that explains about DEFUN in more detail, but that can wait until you know a bit more. We can now do a few useful things, so let's learn how to define a new function. We do this with a function called DEFUN. DEFUN is another magic function, which doesn't evaluate any of its arguments. See if you can guess what this function does: .eval-print (DEFUN TWICE (A) (* 2 A)) Now that you have made your guess, let's give it a try. Use it on a few numbers (one at a time, please--it doesn't know what to do with more). If you didn't guess, the function is called twice, and has been defined for you already, so you can just say (twice 2) or whatever. .try OK, let me explain what that did. The first part given to a DEFUN is the name of the new function, (TWICE in this case). The second part is a list of variable names. In this case there is just one, "A", but there could have been many (that's why you use a list, so that it can tell whether you want just one or many.) The last part is what you want the function to do. When this part is evaluated, any occurences of a variable which is in the list of variable names before it, are replaced with the corresponding argument. Thus (TWICE 2) means (* 2 2), (TWICE 5) means (* 2 5), etc. A is sometimes called a bound variable, or is said to be "bound" to 2 or 5, respectively. The second argument to DEFUN is called the BOUND-VARIABLE-LIST. Now try to write a function which computes A+5*B where A and B are the first and second arguments, respectively. (Hint: use a bound variable list with TWO elements... you don't have to call them A and B if you don't want. .try Did it look something like this? (The function below has also been defined for you.) .eval-print (DEFUN POLY (A B) (+ A (* 5 B))) This is the way LISP "programs" are written. They are functions which when evalutated do the desired task. Before we can do anything really useful, we have to be able to do something one time, but not another. Hence (LESSON PRED) will make this lesson seem much more useful..... .next eval