Major Points
Each node can store a pointer to another node or to an "atom" or to another list.
| | _____V_____ <==> (X.Y) | | | |/___|___\| where X and Y are ____/ \____ "atoms." |X | | Y| |__| |__|
I.e., in C++, we would write (diagram) a list as:
_______ _______ _______ | | | | | | | | /| --->| X | -|-->| Y | -|-->| Z | / | |___|___| |___|___| |___|/__|In LISP, we would diagram this (more correctly) as:
_______ _______ _______ | | | | | | | | | _____ --->| | -|-->| | -|-->| | -|-->|_NIL_| |_|_|___| |_|_|___| |_|_|___| | | | _V_ _V_ _V_ |_X_| |_Y_| |_Z_|and this structure is a tree, i.e., when you rotate it clockwise 45o, you get a tree with no contents in the interior (non-leaf) nodes.
| / \ X / \ Y / \ Z nilThis structure is written as
EXAMPLE 1 - (X Y) EXAMPLE 2 - ((X Y ) Z) EXAMPLE 3 - (X.((Y.(Z.NIL)).NIL))
If we examine any list, one operation that we can imagine is the operation which removes the head of a list from the list (like POPping a stack implemented as a linked list). Another operation would be to take a list and give the rest (or tail) of the list minus the head node. A third operation would take a node and join it to another node by constructing a dotted pair node.
The three LISP functions which correspond to these operations are CAR, CDR, and CONS.
(In many LISP interpreters, commands may be entered either in UPPERCASE or lowercase characters.)
(CAR list) [Contents of Address Register - cf. IBM 704] returns first element of the list. (CDR list) [Contents of Decrement Register] returns tail of the list AS A LIST, i.e. the rest of the list with the CAR removed. [pronounced "could-ur"] (CONS s-exp s-exp) returns a new node, i.e. dotted pair, out of the two s-expressions given. [abbreviation of CONStruct] E.g., CAR (A B C) --> A CDR (A B C) --> (B C) CONS A, (B C) --> (A.(B C)) = (A B C)Since CAR and CDR are used often in conjunction with each other, there is a standard way to abbreviate compositions of these functions:
(C....R list) where .... can be either A's or D's is the standard abbreviation for repeated uses of CAR and CDR.Using Kyoto Common Lisp on the math HP Unix server, a maximum of five intermediate A's or D's are permitted between the initial C and final R.
For example,
(CDAR list) <=> (CDR (CAR list)) (CDDDR list) <=> (CDR (CDR (CDR list)))
+ <==> addition * <==> multiplication SETQ <==> assignment of values, or := QUOTE or ' <==> leaves the following s-expression UNevaluated, i.e., a literal.To use functions in LISP, one write the desired expression:
LISP is free format, so that it is up to the programmer to determine how much or how little is put on a line and whether or not to use indentation. As a matter of style, it is always good to indent substructures, and put new expressions on new lines.
(CAR '(A B C)) (+ 2 3) (* 3 4) (SETQ A 2)One can always "nest" functions, e.g.,
(SETQ A (+ (* 2 3) (* 5 2)))
(+ x y) returns x+y [OTHER LISPs may use PLUS] (* x y) returns x*y [OTHER LISPs may use TIMES] (- x y) returns x-y [OTHER LISPs may use DIFFERENCE] (/ x y) returns x/y [OTHER LISPs may use QUOTIENT]NOTE: With Kyoto LISP, if both x and y are integers, the result from a division is given as an integer or as an integer fraction. To convert the value to a real number, one needs to multiply it by 1.0 or use real numbers as arguments.
(1+ x) returns x+1 [OTHER LISPs may use ADD1] (1- x) returns x-1 [OTHER LISPs may use SUB1] (SETQ atom value) set atom to value and returns value (QUOTE s-exp) or 's-exp forces NON-evaluation of s-exp, i.e. s-exp is retained in literal form.
(LIST a b c ... d) returns the list (a b c ... d) (LAST list) returns last dotted pair of list (LENGTH list) returns the length of list (NCONC a b) concatenates a and b together into one list, destroying the old a and b. (APPEND a b) creates a new list which is the concatenation of a and b without changing a and b. (REVERSE list) creates a new list which is the reverse of list. (NREVERSE list) reverses pointers in old list -- old list is destroyed. (RPLACA list y) replaces (CAR list) with y. (RPLACD list y) replaces (CDR list) with y.
(ODDP n) returns T if n is an odd integer. (ATOM a) returns T if a is an atom, i.e. not an s-expression or a list. (NUMBERP a) returns T if a is a number. (ZEROP n) returns T if n = 0. (PLUSP n) returns T if n > 0. (NULL a) returns T if a = NIL. (MEMBER x list) if x is an element of list, this returns a list in which x is the first element. (EQ x y) returns T if x and y are EXACTLY the same object, i.e., if they point to the same memory locations. (EQUAL x y) returns T if x and y have the same structure (e.g., same appearance when printed out).
(> x y) returns T if number x is greater than number y (>= x y) returns T if number x is greater than or equal to number y (< x y) returns T if number x is less than number y (<= x y) returns T if number x is less than or equal to number y (= x y) return T if number x and y are equal
(EVAL a) interprets (i.e. evaluates) a (an s-expression) as if it were a top level command.
(COND (condition1 action1) (condition2 action2) (condition3 action3) ... (condition-m action-m) )The first condition that evaluates to T has its action performed-- all others are ignored.
(DEFUN function_name input_var_list action)This defines a new function. Equivalent to DEFINE or DEF in other implementations. COMMON LISP allows more than one action here also--merely list them in order.
(PROG local_variable_list action1 action2 ... action-m)One way (older LISP) of associating many actions where only one was allowed by definition. This somewhat imitates the BEGIN...END construction in Pascal which is needed where the language only allows one statement, and more than one is desired by the code. PROG returns NIL as its value unless one uses a RETURN function inside (see next entry).
(RETURN a) returns the value of a as the value of the PROG expression in which it is found. If RETURN is NOT used within a PROG construction, then the final value returned by the PROG is a NIL. (GO loop) GO TO statement. loop is the label placed immediately before the action referred to. GO can be used ONLY within a PROG expression.
(DO ( (var_1 init_val_1 step_1) (var_2 init_val_2 step_2) ... (var_n init_val_n step_n) ) ( end_test end_action_1 end_action_2 ... end_action_k return_value ) body_action_1 body_action_2 ... body_action_m )This DO construct is common in most dialects of MACLISP and Common LISP. It is a looping structure which eliminates the need for the PROG and GO structures of "ancient" LISP.
The DO construct consist of three major sections:
(DOTIMES (loop_var end_value opt_return_value) body_action_1 body_action_2 ... body_action_m )This DOTIMES construct is available in most dialects of Common LISP. It is a counted loop in which the actions indicated in the body of the loop are performed the number of times determined by the limit indicated for the loop_var. When the actions in the loop are being executed, the value of loop_var begins with 0 and goes up to but does not include end_value. As soon as loop_var reaches the value of end_value the structure is exited with the value of the structure being that of opt_return_value (which is optional).
The WHERE construct's structure is as follows:
(WHERE predicate_expression (RETURN return_value))The predicate_expression could be any test that evaluates to T or NIL.
The LOOP contruct itself has this structure:
(LOOP body_action_1 body_action_2 ... body_action_m )The LOOP executes all body_actions in the order listed repeatedly. One of the body_actions must be some sort of test (such as the WHERE) in order to break out of the loop.
(PRINT a) prints the value of a (on the terminal) (TERPRI) induces a carriage return (on the terminal)To OPEN file FOO.LSP in your directory and prepare it as an INPUT file:
(SETQ IN1 (OPEN "FOO.LSP" :DIRECTION :INPUT)) where IN1 can be any local atom.Then to READ from file FOO.LSP, use:
(READ IN1) reads one s-expression (READ-CHAR IN1) reads one characterTo CLOSE the file:
(CLOSE IN1)To OPEN file BAR.LSP in your directory and prepare it as an OUTPUT file:
(SETQ OUT1 (OPEN "BAR.LSP" :DIRECTION :OUTPUT))Then to PRINT to BAR.LSP, use:
(PRINT s-exp OUT1) prints in form which can later be used by READ with a preceding NEWLINE and followed by SPACE (i.e., with escape characters). (PRIN1 s-exp OUT1) prints in form which can later be used by READ without any surrounding spaces (i.e., with escape characters). (PRINC s-exp OUT1) like PRIN1 except special characters are printed without other marks (i.e., NO escape characters). (TERPRI OUT1) forces a carriage return in file OUT1.
(SETF (GET x z) y) (gives x the z-property value of y. [OTHER LISPs may use (PUTPROP x y z)] If x and z are atoms (used as names), they should be preceeded by a quote mark. (GET x z) gets the value of the z-property of x. If x and z are atoms (used as names), they should be preceeded by a quote mark.
(LOAD "FOO.LSP")-->COMMENTS: use ; and rest of the line is ignored.
-->TO EXIT:
(BYE)-->TO RESET after errors:
:q-->To force a GARBAGE COLLECTION:
(GBC NIL) (to collect cells only) --or-- (GBC T) (to collection everything)
This page is maintained by Dennis C. Smolarski, S.J.
© Copyright 1998, 1999 Dennis C. Smolarski, SJ, All rights reserved.
Last changed: 8 April 1999.