Download presentation
Presentation is loading. Please wait.
Published byJody Wilkins Modified over 9 years ago
1
CSE 341 -- S. Tanimoto Lisp-6 - 1 Defining Macros in Lisp Extensibility: A language is extensible if the language can be extended. New Lisp control structures can be created using macros. A macro form is evaluated in a special way: First the macro form is expanded by applying the macro-expansion function (given in the definition) to the arguments. Then the resulting expression is evaluated again.
2
CSE 341 -- S. Tanimoto Lisp-6 - 2 Example: PUSH (actually built-in) > (defmacro push (element stack) (list 'if (list 'null stack) (list 'setq stack (list 'quote (list element))) (list 'setq stack (list 'cons element stack)) ) )
3
CSE 341 -- S. Tanimoto Lisp-6 - 3 Macro Expansion The macro expansion function is applied to the macro arguments. We can see these intermediate results if we use the built-in function MACROEXPAND. > (macroexpand '(push 5 s)) (IF (NULL S) (SETQ S '(5)) (SETQ S (CONS 5 S))) T ;2nd value is T since a macro form was expanded
4
CSE 341 -- S. Tanimoto Lisp-6 - 4 Full Macro-form Evaluation First the form is fully expanded, and then the resulting form is evaluated. > (setq s nil) NIL > (push 5 s) (5) > (push '(next element) s) ((NEXT ELEMENT) 5)
5
CSE 341 -- S. Tanimoto Lisp-6 - 5 Example: SET-TO-ONE Takes any number of arguments, which must be symbols, and gives each the value 1. > (defmacro set-to-one (&rest symbols) (append '(progn) (mapcar #'(lambda (s) (list 'setq s 1)) symbols))) > (macroexpand '(set-to-one x y z)) (PROGN (SETQ X 1) (SETQ Y 1) (SETQ Z 1)) T > (set-to-one x y z) 1 > y 1
6
CSE 341 -- S. Tanimoto Lisp-6 - 6 Example: TWICE Takes any number of forms and evaluates them all once and then all again. > (defmacro twice (&rest forms) (append '(progn) forms forms) ) TWICE > (twice (format t "Macros are powerful~%") (format t "Aren’t they?~%") ) Macros are powerful Aren’t they? Macros are powerful Aren’t they? NIL >
7
CSE 341 -- S. Tanimoto Lisp-6 - 7 Backquote and Comma Syntax Allows the body of a macro to look like the expanded form. > (defmacro push (element stack) ‘(if (null,stack) (setq ',stack '(,element)) (setq,stack (cons,element,stack)) ) ) >(macroexpand '(push 5 s)) (IF (NULL S)(SETQ 'S '(5))(SETQ S (CONS 5 S))) T Backquote is like QUOTE but it allows subexpressions preceded by a comma to be evaluated.
8
CSE 341 -- S. Tanimoto Lisp-6 - 8 Example: ENQUEUE Like PUSH, but puts the new element at the end of the list. > (defmacro enqueue (item lst) ‘(if (null,lst) (setq ',lst '(,item)) (nconc,lst (list,item)) ) ) > (setq q ‘(a b c)) (A B C) > (enqueue ‘d q) (A B C D)
9
CSE 341 -- S. Tanimoto Lisp-6 - 9 Example: SELECT Each clause is a list that begins with a value that might equal that of OBJECT. These value are tested in turn, and the first one that is equal to OBJECT has its remaining clause elements evaluated, and the value of the last of these is returned. > (select 5 (4 "too small") (5 "just right" "five") (6 "six") ) "five"
10
CSE 341 -- S. Tanimoto Lisp-6 - 10 Example: SELECT Note that the backquote doesn’t have to be at top-level. Also note the use of the dot (.) which means that the list that follows should be spliced into the current list. (defmacro select (object &rest clauses) (append '(cond) (mapcar #'(lambda (clause) `((equal (first ',clause),object).,(rest clause)) ) clauses)))
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.