CSE 341 -- S. Tanimoto Lisp-6 - 1 Defining Macros in Lisp Extensibility: A language is extensible if...

10
CSE 341 -- S. Tanimoto 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.

Transcript of CSE 341 -- S. Tanimoto Lisp-6 - 1 Defining Macros in Lisp Extensibility: A language is extensible if...

Page 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.

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.

Page 2: 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.

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)) ) )

Page 3: 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.

CSE 341 -- S. Tanimoto Lisp-6 -

3

Macro ExpansionThe 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

Page 4: 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.

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)

Page 5: 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.

CSE 341 -- S. Tanimoto Lisp-6 -

5

Example: SET-TO-ONETakes 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> y1

Page 6: 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.

CSE 341 -- S. Tanimoto Lisp-6 -

6

Example: TWICETakes 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 powerfulAren’t they?Macros are powerfulAren’t they?NIL>

Page 7: 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.

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.

Page 8: 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.

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)

Page 9: 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.

CSE 341 -- S. Tanimoto Lisp-6 -

9

Example: SELECTEach 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"

Page 10: 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.

CSE 341 -- S. Tanimoto Lisp-6 -

10

Example: SELECTNote 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)))