280 likes | 394 Views
“And now for something completely different…”. Announcements. Web site is coming up Office hours Allegro for Windows Next few weeks Today and Tuesday: Lisp (Micros/Macros/CLOS) Thursday: Review of 250/350 final, plan on planning Tuesday (4/13): Read Chapters 11 & 12. Today’s Topics.
E N D
“And now for something completely different…” CS251: Intro to AI/Lisp II
Announcements • Web site is coming up • Office hours • Allegro for Windows • Next few weeks • Today and Tuesday: Lisp (Micros/Macros/CLOS) • Thursday: Review of 250/350 final, plan on planning • Tuesday (4/13): Read Chapters 11 & 12 CS251: Intro to AI/Lisp II
Today’s Topics • More Lisp • Macros • Micros CS251: Intro to AI/Lisp II
Micros • “Micros are Lisp runtime objects that have dynamic type resolution and support multiple dispatch, but otherwise do very little.” (Guy Steele) • When should you use micros? • Good when you don’t have much to do • Lots of examples from the reading CS251: Intro to AI/Lisp II
A Quick Quiz • Give two examples where micros are useful • When should you use micros, and when are macros appropriate instead? • Do micros support inheritance? CS251: Intro to AI/Lisp II
Just Kidding April Fools! CS251: Intro to AI/Lisp II
Lisp, Lisp & More Lisp • Common Lisp can do a lot for you, but… … what if you need another language? • Functions just don’t cut it • when is this true? CS251: Intro to AI/Lisp II
Extending Lisp • Lisp is a “programmable programming language” (John Foderaro) • Build your own language with macros • Macros let you treat data as code CS251: Intro to AI/Lisp II
Functions vs. Macros • Evaluate all its arguments • Produce expressions CS251: Intro to AI/Lisp II
How Macros Work • At toplevel, Lisp recognizes macro • Builds the macro expression inline • Evaluates the expression inline CS251: Intro to AI/Lisp II
The defmacro Jam • Use defmacro to create new macros (just like defun) > (defmacro nil! (var) (list `setq var nil)) NIL! CS251: Intro to AI/Lisp II
“Big, Fat, Hairy Deal!” (Garfield) • Everybody and their dog has a macro language • How Lisp works • Parser reads Lisp source, sends its output to the… • Compiler, which compiles it for • Execution • Parser sends a list of Lisp objects CS251: Intro to AI/Lisp II
Macros in the Middle • Macros work between the parser and compiler • Output a list of Lisp objects, so compiler doesn’t notice • An expanding macro has access to all of Lisp Cool, isn’t it? CS251: Intro to AI/Lisp II
Macros, Evaluation and You • Argument evaluation • Remember the quote? > ‘(a b c) (A B C) > (quote (a b c) • Now we’ve got backquote CS251: Intro to AI/Lisp II
Backquote • Backquote lets you control evaluation • Backquote (`) stops evaluation • Comma (,) starts it up again • Comma-at (,@) starts it with a list > (setq a 1 b 2 c 3) 3 > `(a ,b c) ??? > `(a (b ,c)) ??? CS251: Intro to AI/Lisp II
Backquotes & Commas • One comma balances one backquote • Don’t worry unless you have nested backquotes > ‘(a ,(b ,c)) CS251: Intro to AI/Lisp II
Where’s Waldo? • Use defmacro to create new macros (just like defun) • Backquote is used for making lists, but there are other ways > (defmacro nil! (var) (list `setq var nil)) NIL! CS251: Intro to AI/Lisp II
nif With and Without > (defmacro nif (expr pos zero neg) (list ‘case (list ‘truncate (list ‘signum expr)) (list 1 pos) (list 0 zero) (list -1 neg))) > (defmacro nif (expr pos zero neg) `(case (truncate (signum ,expr)) (1 ,pos) (0 ,zero) (-1 ,neg))) CS251: Intro to AI/Lisp II
And the macro expansion is... (nif x ‘p ‘z ‘n) expands into... (case (truncate (signum x)) (1 ‘p) (0 ‘z) (-1 ‘n)) CS251: Intro to AI/Lisp II
Back to the Comma • Turn evaluation back on > (setq b ‘(1 2 3)) (1 2 3) > `(a ,b c) ??? > `(a ,@b c) • Comma-at splices an expression into a list • Insert and remove the ()’s CS251: Intro to AI/Lisp II
When is ,@ Handy? • Macros that take an indeterminate number of arguments • Pass them on to functions or macros that also take an indeterminate number of arguments • Example: Code blocks like progn • Remember when? CS251: Intro to AI/Lisp II
Splicing Away • Doing when our way (defmacro our-when (test &body body) `(if ,test (progn ,@body))) CS251: Intro to AI/Lisp II
Macro Expansion • Why is macro expansion special? > (pprint (macroexpand-1 ‘(our-when (able) (laugh) (laughAgain)))) (if (able) (progn (laugh) (laughAgain))) CS251: Intro to AI/Lisp II
Macro Headaches • Variable capture • Macro variable names collide with the variable names of the expansion context (defmacro ntimes (n &rest body) `(do ((x 0) (+ x 1))) ((>= x ,n)) ,@body)) CS251: Intro to AI/Lisp II
What happens here? > (let ((x 10)) (ntimes 5 (setf x (+ x 1))) x) ??? CS251: Intro to AI/Lisp II
Finding the Problem • Expand the macro (let ((x 10)) (do ((x 0) (+ x 1))) ((>= x 5)) (setf x (+ x 1))) x) (defmacro ntimes (n &rest body) `(do ((x 0) (+ x 1))) ((>= x ,n)) ,@body)) CS251: Intro to AI/Lisp II
A Name to Call Our Own • Generate a new symbol • Use gensym CS251: Intro to AI/Lisp II
A Macro Recipe • Figure out what you’re starting with • Break it down into small chunks • Reassemble the chunks into what you need CS251: Intro to AI/Lisp II