Lisp EN -- Laboratory 2 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 1 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 2 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 3 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 4 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 5 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 6 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Laboratory 7 -- 2006-2007 -- info.uvt.ro
- Lisp EN -- Test -- 2006-2007 -- info.uvt.ro
Variables, parameters and constants
- It defines a variable with the given name.
- It assigns the variable with the given value, only if the variable was not assigned early.
(defvar <name> [<initial-value> [documentation]])
(defvar var-1 1 "variable 1") (print var-1) => 1
(defvar var-1 2) (print var-1) => 1
- It defines a variable with the given name.
- It assigns the variable with the given value, regardless of the variable state (newly defined or old one). Thus it overwrites the old value.
(defparam <name> <initial-value> [documentation])
(defparameter param-1 1 "param-1") (print param-1) => 1
(defparameter param-1 2) (print param-1) => 2
- It defines a constant (in fact a variable) with the given name.
- It assigns the constant with the given value, regardless of the constant state (just like defparameter) but it this case it issues a warning.
- As a convention the constants start and end with *.
(defconstant <name> <initial-value> [documentation])
(defconstant const-1 1 "const-1") (print const-1) => 1 and a warning
(defconstant const-1 2) (print const-1) => 2
- It checks if the given symbol is a constant name or if the given argument is considered to be a constant.
(constantp 'var-1) => nil (constantp 'param-1) => nil (constantp 'const-1) => t (constantp 1) => t
(constantp var-1) => ? (constantp param-1) => ?
- It assigns a variable with a given value.
- It takes an even number of parameters which represent the variable, and the value respectively to assign.
- It executes sequentially.
(setq <variable> <value>) (setq <variable-1> <value-1> <variable-2> <value-2> ... <variable-n> <value-n>)
(setq a 1) a => 1 (setq a 1 b 2) a => 1 b => 2 (setq a b b a) a => 2 b => 2
- It has the same semantic as setq except that when used with multiple pairs, in which case the assignments are performed in parallel.
(psetq <variable-1> <value-1> <variable-2> <value-2> ... <variable-n> <value-n>)
(setq a 1 b 2) (psetq a b b a) a => 1 b => 2
- It assigns a value to a place.
- Like setq it can take multiple pairs of places and values.
- Like setq it executes the assignments sequentially.
- A place is in fact an expression accessing a field of a data structure. (See examples section.)
(setf <place> <value>) (setf <place-1> <value-1> <place-2> <value-2> ... <place-n> <value-n>)
(setq l '(1 2 3)) l => (1 2 3) (setf (car l) 'a) l => (a 2 3) (setf (cdr l) '(5 6)) l => (a 5 6) (setf (nth 1 l) 'b) l => (a b 6)
- It has the same semantic as setf, but, as with psetq, it executes all the assignments in parallel.
- Circular lists
(setq l '(1 2 3)) (setq (cdddr l) l) => infinite loop
Forms and functions
- A form is an executable entity which has the control over the evaluation of it's arguments.
- A function is an executable entity which has no control over the evaluation of it's arguments, they are evaluated just before calling the function.
- All the control statements are forms.
(if <condition> <then-statement> [else-statement])
(if t 1 2) => 1 (if nil 1 2) => 2 (if t 1) => 1 (if nil 1) => nil
- If the condition is true it executes all the statements, and returns the value of the last statement, or nil in case of a false condition)
(when <condition> <statement-1> ... <statement-n>)
(when t (print 1) (print 2)) => 2 and 1, 2 is printed on the console. (when t 1 2 3) => 3 (when nil 1 2 3) => nil
- It has the same semantic as when except that the statements are executed if the condition is not true.
(unless <condition> <statement-1> ... <statement-n>)
(unless t 1 2 3) => nil (unless nil 1 2 3) => 3
- This is the Lisp's equivalent of switch in C, or the if ... else-if ... else-if ... else ...
- It takes a list of cases and searches for a matching case. When it finds one it returns the value of the last statement in it.
- A case is composed from a condition and some statements.
- Usually we put a catch all case, with t as a condition.
(cond (<condition-1> <statement-1-1> ... <statement-1-n1>) (<condition-2> <statement-2-1> ... <statement-2-n2>) ... (<condition-m> <statement-m-1> ... <statement-m-nm>) (t <statement-t-1> ... <statement-t-nt>))
(defun int-test (n) (cond ((not (integerp n)) "non-integer") ((evenp n) "even") ((oddp n) "odd") (t "error"))) (int-test 1) => "odd" (int-test 2) => "even" (int-test "a") => "non-integer"
- Naming conventions
- Names which are composed from multiple words are written lower case separated by -
- Constants are pre- and postfixed with *
(if short-cond short-then short-else) (if cond then else) (when short-cond short-result) (unless short-cond short-result) (when cond statement-1 statement-2) (unless cond statement-1 statement-2) (cond (cond-1 result-1) (cond-2 result-2))
Recursive function cases
- Termination (or exit) case
- Recursive call
(defun my-expt (m n) (cond ((zerop n) 1) (t (* m (my-expt m (- n 1)))) ))
(defun fibonacci (n) (cond ((= n 0) 0) ((= n 1) 1) (t (+ (fibonacci (- n 1)) (fibonacci (- n 2)))) ))
(defun count-atoms (l) (cond ((null l) 0) ((atom l) 1) (t (+ (count-atoms (car l)) (count-atoms (cdr l))) ))
This assignment is due next Wednesday (2007-03-14) at 24:00, and should be sent by email.
When you send the email please include in the subject [LISP-EN-2] First_name Last_name for the second year and [LISP-EN-3] First_name Last_name for the third year. Please paste the code inside the email, DO NOT ATTACH any files.
Write 6 recursive functions:
- 3 dealing with numbers and arithmetic operations.
- 3 dealing with list processing.
The functions must be followed by 2 or 3 representative test cases.
These functions must be different than the ones presented in the lab.
Ciprian Dorin Craciun