210 likes | 345 Views
ANSI Common Lisp. 5. Control 16 June 2003. Blocks -- progn. progn > (progn (format t “a”) (format t “b”) (+ 11 12)) ab 23 The expressions within its body are evaluated in order, and the last value is returned. Blocks -- progn.
E N D
ANSI Common Lisp 5. Control 16 June 2003
Blocks -- progn • progn > (progn (format t “a”) (format t “b”) (+ 11 12))ab23 • The expressions within its body are evaluated in order, and the last value is returned.
Blocks -- progn • For readability purpose, don’t use progn if there is an alternative (let, cond, …).(if (FOO x) (progn (print “hello”) 23) 34)(cond ((FOO x) (print “hello”) 23) (t 34))
Blocks -- block • A block has a name, which is the first argument of block. • At any point of the block body, return-from can halt evaluation and return a value. (block head (format t “Here we go”) (return-from head ‘idea) (format t “This statement won’t be evaluated”)
Blocks -- block • A block can be named nil, where the return macro, instead of return-from, can return a value.(block nil (return 27)) • Implicit block in defun(defun foo () (return-from foo 27))(block foo (return-from foo 27))
Blocks -- block • Implicit block named nil enclosed in all iterations.(dolist (x ‘(a b c d e)) (format t “~A “ x) (if (eql x ‘c) (return ‘done)))A B CDONE • Neither return-from nor return will work outside of an explicit or implicit block.WRONG CODE:(mapcar #'(lambda (x) (if (eql x 'c) (return 'done) (format t "~A " x))) '(a b c d e))
Context -- let • The let creates a new lexical context (group expressions). Within its body, new variables can be defined. (let ((x 7) (y 2)) (+ x y)) • The variables defined in let body are local to the body. • The variables from outer context are visible the let body.
Context -- let • The let expression is essentially a lambda function call.(let ((x 7) (y 2)) (+ x y))((lambda (x y) (+ x y)) 7 2)
Context -- let • The value of one let-created variable does NOT depend on other variables created by the same let.(let ((x 1)) (let ((x 2) (y (+ x 1))) y))2
Context -- let • If we want the value of one let-created variable does depend on other variables created by the same let, we can use let*.(let ((x 1)) (let* ((x 2) (y (+ x 1))) y))3
Context – destructuring-bind • The destructuring-bind is used to bind tree values to corresponding parts of tree.>(destructuring-bind (w (x y) . z) ‘(a (b c) d e)(A B C (D E))
Conditional – if, when, unless • if(if (oddp that) (format t “odd”)) • when(when (oddp that) (format t “Hmm, that’s odd.”) (+ that 1)) • unless(unless (oddp that) (format t “Hmm, that’s even.”) (+ that 1))
Conditional – cond, case • cond(cond ((predicate 1) expressions 1)) ((predicate 2) (expression2 2)) … (t (expressions N))) • case – compare a value against a series of constants (won’t be evaluated).(case mon ((jan mar may jul aug oct dec) 31) ((apr jun sept nov) 30) (feb (if (leap-year) 29 28)))
Iteration – do, do* • Basic usage(do ((i 1 (+ i 1))) ((> i 5) ‘done) (format t “~A ~A~%” i (* i i)))) • More variable updates(let ((x ‘a)) (do ((x 1 (+ x 1)) (y x x)) ((> x 5)) (format t “(~A ~A) “ x y)))(1 A) (2 1) (3 2) (4 3) (5 4)
Iteration – do, do* • do*(let ((x ‘a)) (do ((x 1 (+ x 1)) (y x x)) ((> x 5)) (format t “(~A ~A) “ x y)))(1 1) (2 2) (3 3) (4 4) (5 5)
Iteration – dolist, dotimes • dolist(dolist (x ‘(a b c d) ‘done) (format t “~A “ x))A B C DDONE • dotimes (iterates from 0 to n-1)(dotimes (x 5 x) (format t “~A “ x))0 1 2 3 45
Iteration – mapc, mapcar • mapcAlways returns its second argument.(mapc #’(lambda (x y) (format t “~A “A “ x y)) ‘(hip flip slip) ‘(hop flop slop))HIP HOP FLIP FLOP SLIP SLOP(hip flip slip) • mapcarTakes a function and one or more lists as arguments, and returns the result of applying the function to elements taken from each list, until some list runs out.(mapcar #’list ‘(1 2 3 4) ‘(a b c))((1 A) (2 B) (3 C))
Multiple Values • In CLISP, a function can return multiple values. • The values function(values ‘a NIL (+ 2 4))ANIL6 • If only one value is expected, all but the first will be discarded.(let ((x (values 1 2 3))) x)1
Multiple Values • The multiple-value-bind can receive multiple values(multiple-value-bind (x y z n) (values 1 2 3) (list x y z n))(1 2 3 NIL) • The multiple-value-call function(multiple-value-call #’+ (values 1 2 3))6 • The multiple-value-list function(multiple-value-list (values ‘a ‘b ‘c))(A B C)
Aborts – catch/throw • catch/throw(defun super () (catch ‘abort (sub) (format t “We’ll never see this.”)))(defun sub () (throw ‘abort 99))>(super)99
Aborts – error, unwind-protect • errorThe error function interrupts execution and pass the control to LISP break loop. • unwind-protectThe unwind-protect function ensures the remaining expressions will be evaluated even if the previous evaluation interrupts execution.The unwind-protect function is useful for clean-up or reset. For example, close the I/O stream when some errors come out.