Lisp
Background on LISP
- Background:
- LISP = LISt Processing
- (or Lots of Insipid Silly Parentheses)
- John McCarthy -
- AI: theorem proving and natural language processing
- More history
Running LISP
- On rucs2: /usr/bin/gcl
- or try this: /usr/local/gnu/bin/gcl
- gcl = Gnu Common Lisp
- Interpreter evaluates input expressions and prints results
- Exit gcl: either (quit) or ctrl-D
- Load a file: (load "fn.ext")
LISP is Functional
- A program is a function
- Execute a program by applying the function to its argument(s)
- Example of function application:
- executing sqrt(4) applies function sqrt to argument 2
- Informally we say: sqrt(4) returns 2
- Note: this is NOT legal LISP
- Traditionally: no assignment
- gcl has setq, but we won't use it
Syntax for Evaluating Functions
- Wite f(x) as (f x)
- Write f(x, y) as (f x y)
- No parentheses
More Arithmetic Operators: - and *
Numeric Types
- Built in numeric types are integer, float, ratio, complex, ...
- (+ 2.2 3.3)
- (+ 2.0 3)
- (/ 5.0 2)
- (/ 5 2)
Composition of Function Calls
(* (/ 2 4) (/ 1 3) ) → 1/6
- (* 4 (+ 5 2)) → 28
- (* 4 (/ 5.0 2)) → 10.0
- (* 4 (/ 5 3)) → 20/3
Some Math Functions
- (abs -3) [seen above]
- (sqrt 5)
- (sqrt 9)
- (sqrt (abs -3))
- (min 3 2)
- (expt 2 3)
- What about other exponents ??
Variable Number of Parameters
- (+ 2 3 4) → 9
- (min 5 2 3 6 33) → 2
- (+ 2)
- (sqrt 2 3) → error
Some Errors
- Need space: (+2 3 4)
- Need operations: (+)
- Need operands: (min)
- Need parens: min
- Need parens: +
- No operation: (1)
Syntax
- Can put extra spaces and newlines
(
+
2
3
)
NOT case sensitive: (+ (abs -1) (ABS -1))
Comments: characters after ; are ignored
Strings
- Strings are available, but we won't use them
- Example: (print "Hello world!")
Boolean Type
- nil is false
- nil is the empty list
- nil also represented as ()
- any other value (eg 1 or t) is true
- Relational operators evaluate to:
- either nil, which is false
- or to T, which is a true value
Numeric Comparison
- Functions: <, >, <=, >=, =, /=
- (< 2 3) → T
- (> 2 3) → nil
- (= 2 3) → nil
- all of these are true:
- (= 2 2 2)
- (/= 2 2 3)
- (< 2 3 4 5)
Logical Operators: and, or, not
- (and t nil) → nil
- (or t nil) → T
- (or (< 1 2) (> 3 4) (< 1 1) ) → t
- Remember: Anything except nil is true:
- (or 1 2 3) is true [later we'll see it evaluates to 1]
- not
- (not nil) → T
- (not T) → nil
- (not '(1 2) ) → nil [haven't discussed ' yet, but it's not nil!)
- Other predicates are listed in a table below called "Other Functions"
Functions and, or are Short Circuit
- Short circuit operators: Only evaluate operands if necessary
- Operators AND and OR are short circuit
- Example:
- (/ 1 0) crashes
- Neither of these crash:
- (or T (/ 1 0)) → T
- (and nil (/ 1 0)) → nil
Functions and, or, Return Last Evaluated Function
- AND and OR return the value of final expression that was evaluated
- (or 1 2 3) → 1
- (or nil 2 3) → 2
- (and t 2 3) → 3
- (and t 2 nil 4) → nil
Print
- Print outputs a value and returns a value
- Examples:
- (print 3) → 3 3
- (print 3 4) → error
- Print has a side effect:
- (or (print 3) (print 4) ) → 3 3
- (and (print 3) (print 4) ) → 3 4 4
If Evaluates to a Value
-
If
is written as a function
-
If
evaluates to a value
- Example: (if (< 2 3) 4 5) means:
if 2 < 3 then
return 4
else
return 5
end if
(if T 4 5) → 4
(if nil 4 5) → 5
If Does Not Evaluates Both Parts
- if will not evaluate both then and else part
- Contrast these:
- (if T 4 (/ 1 0) )
- (if nil (/ 1 0) 4)
- Later we'll learn that
if
is a macro:
If: Some Syntax
- If does not need an else:
- (if (> 2 1) 3) evaluates to 3
- (if (< 2 1) 3) evaluates to nil
- If requires a then part:
- (if T ) is a syntax error
Lists
- A list is anything enclosed in parens
- Examples:
- Function calls are lists too:
- Lists can be nested:
- The empty list is represented as () or nil
List Functions: First Look
- Lisp has 3 list functions:
- car = head
- cdr = tail
- cons = construct a list by appending on front
- BUT, before we can understand them we must learn:
- How lists are evaluated [eg evaluating (+ 2 3) ]
- What "self-evaluating" means [ie evaluates as itself]
- How "quote" is evaluated [quote returns its argument
unevaluatd. Shorthand: ']
Evaluating a List
- To understand lisp, you MUST understand how lists are evaluated
- To evaluate a list, first examine the
first element:
- First element determines if list is either:
- a function
- in a function call, all of the remaining list elements
are evaluated
and passed to the function as arguments
- Examples:
- Numbers are self-evaluating
- Meaning: Numbers evaluate AS themselve
- Incorrect: they evaluate themselves
- or a special form or macro
- For special forms and macros,
- whether the remaining list elements are evaluated depends on what the first is
- Examples:
- if evaluates condition and either then or else part:
- (if T 2 (/ 1 0)) ; never evaluates last arg
- AND and OR evaluate until result is known:
- (and T 1 () 2 3) ; never evaluates 2 or 3
- (or nil 1 2 3) ; never evaluates 2 or 3
- Later we will see other examples: quote, defun, cond
- Which is this: (1 2 3)) ; an error
- Important point: some list elements may not be evaluated
Self-Evaluating Forms
- A self-evaluating form evaluates as itself
- Examples - these are all self evaluating forms:
- The interpreter evaluates each of these forms as itself.
- That is, the interpreter evaluates:
- 3 as 3
- nil as nil
- () as nil (or () )
- t as t
- T as T
- "abc" as "abc"
- More precisely: when the interpreter evaluates a self-evaluating
form, the result is the form itself.
- Note: "self-evaluating" does NOT mean that it evaluates itself - it
means that it is evaluated AS itself
- Note: Sometimes we say "evalutes to itself" instead of "evaluates
as itself"
Quote
- Quote makes an expression act like a self-evaluating form
- (quote X) evaluates to X for any X
- Examples:
- Evaluating (1 2 3) gives an error
- Evaluating (quote (1 2 3)) gives (1 2 3)
- (quote 1) → 1
- (quote (+ 1 2)) → (+ 1 2)
- (quote (a b c)) → (A B C)
- (quote x) → X
- Contrast (print x) → error with (print (quote x)) → X X
- Print evaluates its arguments
- Quote is not a function:
- It does not evaluate the second list element
- It RETURNS the second list element, unevaluted
Quote Shorthand
- 'X is a shorthand for (quote X)
- '(1 2 3) → (1 2 3)
- '(a b c) → (A B C)
- 'X → X
- (print 'x) → X X
- '(quote x) → 'X
- ''x → 'X
- (quote (quote x)) → 'X
- Quote is best understood in the context in which it's needed
Quote and Car
- Remember car: returns the head of a list
- Car always evaluate the rest of the list:
- (car (1 2 3)) ; want 1, get error
- (car 1 2 3) ; doesn't work either
- Quote solves the problem:
- (car (quote (1 2 3)) ) → 1
- Quote shortcut is easier to read:
- (car '(1 2 3) ) → 1
- (car '(a b c) ) → A ; doesn't matter what A is
Car, Cdr, Cons
- Car and cdr: head and tail
- Head is the first element. Tail is the list with the first element removed
- (car '( (1 2 3) 4 5 6) → ?
- (cdr '(1 2 3)) → ?
- (cdr '(1 2 3)) → ?
- (cdr '( (1 2 3) 4 5 6) → ?
- Use cons to build lists:
- (cons 1 '(2 3)) → (1 2 3)
- Cons returns a list whose head is cons's first argument, and whose tail is cons's second argument
- How would we get: ( (1 2) (3 4) )
- Remember: car, cdr, and cons all evaluate their arguments
CDR
- cdr - tail of the list
- (cdr '(a b c d))
- (cdr '(a))
- (cdr nil) is nil
- (cdr (cdr '(a b c d)))
- (cdr (cdr (cdr '(a b c d))))
- (cdddr '(a b c d))
- (cddddr '(a b c d))
More Examples with CAR and CDR
- (car 1)
- (car 'a)
- (car nil) is nil
- (car (car '(a b c))
- (car '( (a b c) d e f))
- (car (car '((a b c) d e)))
- (cdr (car '((a b c) d e)))
- (cdr '( (a b c) d e f))
- (car (cdr '((a b c) d e)))
- (cdr (cdr '((a b c) d e)))
- (car (cdr (cdr '((a b c) d e))))
- (caddr '((a b c) d e))
- Two more examples:
- (car '(cdr (a b c d)) )
- (cdr '(cdr (a b c d)) )
Cons
- Examples
- (cons 'a '(b c d))
- (cons '(a b c) '(d e))
- (cons 'a 'b) ??
- (car (cons 'a '(b c d)))
- (cdr (cons 'a '(b c d)))
- (cons 'a '() )
- Implementation
- (cons 1 '(2 3))
- (cons '(1 2) '(3 4))
- (cons 1 nil)
More on Quote
- (cons 'x ' ' (a b c))
- (cdr '(cdr '(a b c)))
Defining New Functions
- defun: defines a new
function
- Example: Function sq: (sq 3) → 9
- (defun sq (x) (* x x) )
- (sq 3)
- are x and (* x x) evaluated?????
- Example: function EVEN
(defun even (x)
(if (= 0 (mod x 2) )
t
nil
)
)
Version 2: ( defun even (x) ( = 0 (mod x 2) ) )
what about a function for odd?
Recursion
- Recursive Functions:
- (defun factorial (x) ( ... ))
- (defun len (x) ( ... ))
- (defun reverse (x) ( ... ))
Other Functions
Evaluate
to t
|
Evaluate to nil
|
(numberp 55)
|
(numberp 'a)
|
|
|
(symbolp 'a)
|
(symbolp '(a b))
|
(symbolp 'nil) |
(symbolp ''nil)
|
(symbolp '()) |
|
(symbolp nil) |
|
|
|
(listp '(a))
|
(listp 'a)
|
(listp ()) |
|
(listp nil) |
|
(listp 'nil) |
|
(listp '()) |
|
(listp ''()) |
|
|
|
(atom 'a) |
(atom '(a)) |
(atom 3) |
|
(atom nil) |
|
(atom 'nil)
|
|
(atom ())
|
|
|
|
(null nil)
|
(null 'a)
|
(null () )
|
(null '(a))
|
(null 'nil)
|
(null ''nil) |
Cond
Length Function Using Cond
- (defun len (x)
(cond
(...)
(...)
(...)
)
)
More on Cond
- May have multiple conditions that are true. First one is
used and rest are ignored.
- A final clause of the form (t s7) is typical, but not required
- If no clause evaluates to t, then the entire expression evaluates to nil
- Can have multiple clauses controlled by one condition:
- Example: (s1 s2 s3 s4)
- If s1 evaluates to t, then s2, s3, s4 are evaluated in order
and the entire expression evaluates to the value of s4
- Cond is a macro
Member Function
(defun member (x l)
(
... what goes here?
)
)
Comparisons with Function Equal
- The relop = compares only numbers. How do we compare other things?
- Both functions eq and equal compare bothkatoms and lists
- Look first at Functions equal
- Equal compares values
- Equal is a function - evaluates arguments
- All of the following, except three, yields T
- (equal 1 1)
- (equal 1 2)
- (equal 'a 'a)
- (equal 'a 'b)
- (equal '(1 2) '(1 2))
- (equal nil nil)
- (equal nil 'nil)
- (equal nil ''nil)
Equal and Eq
- Equal compares values while eq compares pointers:
- Two lists with the same values, but different pointers:
(Equal '(1 2) '(1 2)) → t
(Eq '(1 2) '(1 2)) → nil
- Atoms are the same when compared with eq (or equal):
- (Eq 1 1) → t
- (Eq 'a 'a) → t
- (Eq (quote a) 'a) → t
Equal and Member
- Remember: Function equal compares value and eq compares pointers
- Function member uses eq
- For tests with atoms, this does not matter. For example:
- (member 'a '(a b c)) returns true
- For tests with lists as member of lists, this matters. Consider this example:
- (member '(a b) '( c (a b) d))
- this example returns false even though (a b) is a member of
the second list
- If you want member to use equal, then you can either
- define member yourself, or
- tell member to use equal for its test:
- (member '(a b) '(c (a b) d) :test #'equal)
- the example above returns ((a b) d) as a result
Eval
- Function that evaluates its argument
- Evaluates to the last value evaluated
- Can be used to create and evaluate expressions on the fly
- Can be used to write a Lisp interpreter
- McCarthy wrote a one page interpreter for an early version of
Lisp
Map and Lambda
- mapcar creates a list by applying a function to each element of a
list
- (mapcar 'abs '(-1 2 -3))) → (1 2 3)
- maplist applies a function to its list argument and to successive cdrs of this list, and makes a
list of the results
- (maplist '(lambda (x) (cons 'foo x)) '(a b c d)) →
- ((FOO A B C D) (FOO B C D) (FOO C D) (FOO D))
- lambda creates a function without giving it a name
Functional Languages and Referential Transparency
- Functional Languages provide referential transparency
- An expression always evaluates to the same value, no matter
what the context
- Example: the expression (myfun somelist) ALWAYS evaluates to the same result
- Does not matter where the expression occurs
- This is similar to mathematics
- Not true for procedural languages (or any language with side effects)
- Referential transparency greatly increases the ability to analyze programs and
to write correct programs
Setq and Prog and Loop and Do and Case and ...
- Some non-functional features are available in most LISP implementations
- Example: setq - set the value of a symbol:
>x
ERROR: The variable X is unbound.
>(setq x 'hello)
HELLO
>x
HELLO
>(equal x 'hello)
T
>(setq x '(+ 3 4))
(+ 3 4)
>x
(+ 3 4)
>(eval x)
7
>(equal x 'hello)
NIL
These break referential transparency:
- y evaluates to different values depending on surrounding statements
Do not use these for your assignment
These are macros and special forms