Beginner Lisp Slides 1: Welcome to Lisp
- Lisp source code is made up of Symbolic Expressions, or S-Expressions. Each S-expressions is either:
- a list
- an atom
'(2 3 4)
-> (2 3 4)'(("red" 0) ("white" 1) ("blue" 2))
-> (("red" 0) ("white" 1) ("blue" 2))'(a "b" :c (1 2 3 "four"))
-> (a "b" :c (1 2 3 "four"))'a
-> a"b"
-> "b":c
-> :c
- Prefix notation.
(fn arg1 arg2 arg3 "..." argN)
-> some-return-value(+ 2 3 4)
-> 9(fn1 (fn2 arg1 arg2) (fn3 arg3 arg4) arg5)
-> some-return-value(* (- 7 1) (- 4 2) 2)
-> 24
- That's really all there is to know about the syntax of the language
- It is as clean and simple as you can get.
- No ambiguities, no special cases
- A welcome relief from the syntax of other popular languages such as Perl, C++, etc...
- When S-exps are to be evaluated at runtime, certain rules apply:
- Symbols evaluate as variables
*print-length*
-> nil - Other atoms (numbers, strings, keyword symbols, quoted symbols) evaluate to themselves
42
-> 42:key-1
-> :key-1'a
-> a - Unquoted lists evaluate as function calls or macro-expansions, driven by the symbol at the beginning of the list
(+ 1 2)
-> 3(string-upcase "hey now")
-> "HEY NOW"(string-upcase (with-open-file (in "/tmp/data.in") (read in)))
-> "[first S-exp in text of file]"
- If any of the arguments are themselves expressions they are evaluated in the same manner
- The sub-expression (i.e. expression nested within another expression) is evaluated, and its result is passed as an argument
- (fn1 (fn2 arg1 arg2) (fn3 arg3 arg4) arg5)
(* (- 7 1) (- 4 2) 2)
-> 24
- In Lisp - because of prefix notation
(+ 1 2 3 4 5 6 7)
-> 28 - No ambiguity or precedence rules to remember regarding Order of Operations
- Functions potentially can take any number of arguments (including zero)
(+)
-> 0(+ 1)
-> 1 - Functions can also have certain required arguments
(/ 2)
-> 1/2(- 2)
-> -2 - Most modern CL development environments (e.g. Slime) will tell you what are the required arguments (if any) when you insert a function name.
- (+ 1 2) evaluates to 3
- Sometimes you want to turn off expression evaluation
- (quote (+ 1 2)) evaluates to (+ 1 2)
- Common Lisp defines ' as an abbreviation for quote
- '(+ 1 2) evaluates to (+ 1 2)
- Note that quote is one of a few special operators in Common Lisp (you can see that it is not an ordinary function, otherwise it would evaluate its arguments).
- Note also that lists returned by quote (unlike lists returned by list) may be assumed to be immutable -- that is, you should never modify them in place using any destructive operators (no need to worry about this for now).
- Usual Data Types in Other Languages
- Numbers
- Strings
- Fundamental Lisp Data Types
- Symbols
- Lists
- Symbols are OBJECTS
- They are NOT simply strings.
- They have a name, and can have a value, function and property-list
- 'Red evaluates to Red, the Symbol Name of the symbol named ``Red''
- When the Lisp Reader encounters a Symbol for the first time, it interns (creates) this symbol in its internal Symbol Table.
- Two references to "MyBigLongString" and "MyBigLongString" refer to different strings
- 'MySymbol and 'MySymbol are both represented by the same symbol
- eql is the most basic equality function in Lisp, testing whether its arguments refer to the same actual Object (memory location), while string-equal compares two strings for equality, character-by-character.
- Comparing symbols for equality is much faster than comparing strings, since simple eql can be used instead of string-equal
(string-equal "Mybiglongstring" "Mybiglongstring")
-> t(eql 'MySymbol 'MySymbol)
-> t - Symbols turn out to be a very useful concept, and one of the distinguishing features of the Lisp language.
- More on this later
- Lists are fundamental to LISP - LISt Processing
- Lists are zero or more elements enclosed by parentheses
- You have to quote a literal list for it to be evaluated as such; otherwise Lisp will assume you are trying to call a function
'(red green blue)
-> (red green blue)
- Lisp programs are themselves Lists
- It is very easy for Lisp programs to generate and execute Lisp code
- This is NOT true of most other languages
(defun hey-now () (print "Hey Now"))
-> hey-now
- A literal list with single-quote (elements are not evaluated)
'(this is a list)
-> (this is a list) - Using the ``List'' function (evaluates all arguments)
(list '(+ 1 2) 'is (+ 1 2))
-> ((+ 1 2) is 3)
- first list
(first '(a b c))
-> a - second list
(second '(a b c))
-> b - third list
(third '(a b c))
-> c - rest list
(rest '(a b c))
-> (b c) - nth idx list
(nth 2 '(a b c))
-> c
- nil represents falsehood,
nil
-> nil - as well as the empty list.
(list)
-> nil - nil evaluates to itself
- listp item
(listp '(pontiac cadillac chevrolet))
-> t(listp 99)
-> nil - nil represents FALSE
(listp nil)
-> "???"
- defun name arg-list forms
(defun hey-now () (print "Hey Now"))
-> hey-now(hey-now)
-> "[prints] Hey Now"(defun square (x) (* x x))
-> square(square 4)
-> 16
- Read using indentation.
- You can generally let your eyes skip over the parenthesis
(defun my-first-lisp-fn () (list 'hello 'world))
-> my-first-lisp-fn - Try to read the preceding example as:
(defun my-first-lisp-fn ( )(list 'hello world) )
- Now try to read it as:
defun my-first-lisp-fn () list 'hello 'world
- Close all parentheses together on the line. Dangling parenthesis are generally frowned upon in finished code.
'(united-states (ohio (toledo) indiana michigan (detroit (rennaissance-center (200-tower (fifth-floor (suite-20)))))))
- Compare the above example to:
'(united-states (ohio (toledo) indiana michigan (detroit (rennaissance-center (200-tower (fifth-floor (suite-20) ) ) ) ) ) )
- (no need for these dangling parentheses)
- New local variables are bound (introduced) using Let.
- let variable-assignments body
(let ((quantity 20) (excess 10)) (+ quantity excess))
-> 30
- In Lisp we use setq instead of =, :=, etc.
(let ((quantity 20) (excess 10)) (setq quantity 30) (+ quantity excess))
-> 40 - Global variables can be set with defparameter and changed with setq.
(defparameter *todays-temp* 101.5)
-> *todays-temp*(setq *todays-temp* 99)
-> 99*todays-temp*
-> 99 - It is a long-standing Lisp convention to use Asterisks (``*'') to signify Global Variables (parameters). This is convention only, and the Asterisks have no meaning to Lisp itself.
- Setf is used to set ``locations'' resulting from a function call:
(setq *operating-systems* (list "NT" "Solaris" "Irix" "HP-UX" "AIX"))
-> ("NT" "Solaris" "Irix" "HP-UX" "AIX")(setf (first *operating-systems*) "Linux")
-> "Linux"*operating-systems*
-> ("Linux" "Solaris" "Irix" "HP-UX" "AIX")
- dolist, dotimes
- dolist (variable-name list &optional return-value)
(let ((result 0)) (dolist (elem '(4 5 6 7) result) (setq result (+ result elem))))
-> 22 - dotimes (variable-name upper-limit &optional return-value)
(let ((result 1)) (dotimes (n 10 result) (setq result (+ result n))))
-> 46
Copyright © 2012 Genworks®International and Delft University of Technology.