Basic definitions: lists, functions, and evaluation.

• Lisp programs are run through an interpreter.

• The Lisp prompt is an special character or string of characters to inform the user that the Lisp interpreter is awaiting for an expression:
ACL: < cl > or < COMMON-MUSIC >
GCL: > or COMMON-MUSIC>
MCL:	?

• The Lisp interpreter is engaged in what we call an infinite read-eval-print loop. Once one expression is entered, the interpreter evaluates it according to the semantics of Lisp, prints out the result, and display the prompt for the next expression to be entered.

• Some valid symbolic-expressions:
78
-31
(- 78 31)
(/ (+ 33 12) (- 21 10))
(* (- 23 (+ 4 58)) (/ 36 2) 7.0)

The Lisp forms tree

__________T__________
/                     \
List             _______Atom________
/                   \
Symbol       ________Number________
/	       |          \
___Rational___    Float      Complex
/              \
Integer           Ratio
• A Lisp expression may be an atom (e.g. numeric constant, symbol, etc.) or a list (a collection of atoms and lists bracketed by parenthesis). Anything that is not a list is an atom.

Evaluation

• In Lisp, numeric constants evaluate to themselves, they are examples of self-evaluating forms.

• Symbols evaluate to the values to which they are bound. Initially most symbols are unbound and thus have no value.

• Lisp evaluates lists as function calls in prefix notation (Cambridge-Polish notation):
function
\
(+ 35 48 96 32 1 15 3.0 -65)
\_____arguments________/

• All the arguments of a function are evaluated recursively before they are passed to the function:
(/ (+ 2 3)(- 7 2))
\_____/\_____/
(/    5      5   )
\________________/
1

• Functions can take variable number of arguments (as the mathematical functions +, -, *,/)

• Because Lisp functions are invoked by lists, can operate on lists, and are represented as lists, it is possible (and very common) to write Lisp functions that create or modify other Lisp functions. Thus, Lisp exploits the equivalence of programs and data.

Symbols and Special Forms

• Lisp symbols allows us to label data with names. You can use almost all the characters of the keyboard to create a symbol.

• Since most Lisp interpreters are case insensitive, Lisp programmers use the - character to separate words in symbols:
sampling-rate
output-file

• Symbols are initially unbound (have no value), except for special pre-defined symbols. Try to evaluate this unbound symbol:
new-symbol

• Things goes different if you try to evaluate this pre-bound symbol:
pi

• The defvar macro can be used to define a global variable and bind it to a value:
(defvar A-4 440)

Note that defvar evaluates to its first argument. Now, if we evaluate our new variable:

A-4

• Defvar is a special form it does not follow the usual rules of evaluation. Specifically, defvar does not evaluate its first argument. Each time the interpreter encounters a symbol, it first checks to see if that symbol is a special form.

• Now that A-4 is defined, it can be freely used in other expressions:
(defvar A-5 (* A-4 2))

• The defparameter macro is a twin of defvar, it is also used to define and bind new global variables (symbols).

Preventing and forcing Evaluation.

• Suppose you want to bind the symbol F-maj to the list (F-4 A-4 C-5). You might tempted to try the following:
(defvar F-maj (F-4 A-4 C-5))

This produces an error because the interpreter is trying to evaluate the list (F-4 A-4 C-5) as a function call, interpreting the symbol F-4 as a function and the rest as its arguments. We have to tell the interpreter to not evaluate this list and to assign it as the value for the symbol F-maj.

• We can prevent evaluation using the special form quote to wrap the expressions that are not to be evaluated with it:
(defvar F-maj (quote (F-4 A-4 C-5)))

• As quote is used so frequently in Lisp there is a shorthand for it; this involves prefixing the expression to be "quoted" with the single-quote character. The following expression is equivalent to the previous one:
(defvar F-maj '(F-4 A-4 C-5))

• Now, suppose we want our chord to be one octave lower:
(defvar F-maj '(F-3 A-3 C-4))

• Note that defvar has no effect if the variable represented by its first argument has already been defined:
F-maj

• The setf macro lets us change a symbol's binding:
(setf F-maj '(F-3 A-3 C-4))

Note that setf evaluates to its second argument. Now the symbol F-maj is bound to its new value:

F-maj

• The setf macro can be used to instantiate multiple bindings of symbols and values:
(setf F-3 174.61 A-3 (/ A-4 2) C-4 261.62 A-1 (/ A-3 2))

Note that you can use setf to create new variables too.

• Odd-numbered arguments are not evaluated and even-numbered arguments are evaluated; the odd-numbered arguments represent the symbols that are to be bound to the even-numbered arguments. The way setf evaluates its arguments is called sequential fashion, that's why we can use the in-line defined variable A-3 to define A-1.

• The special form setq does the same work as setf. It is mostly use as a simple variable assignment statement in contrast to setf that is used as a general assignment statement. This difference is a matter of style: to change the value of a global variables setf is used and for simple or local variables setq is used.

• The function set behaves the as setf and setq but it evaluates its first argument.

Acknowledgment:

Portions of this page come from Todd Feldman's handouts for CS 193L.

Back to LispWorkshop main page.