cse 341 -- s. tanimoto macros 1 defining macros in scheme extensibility: a language is extensible if...

24
CSE 341 -- S. Tanimoto 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme 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 procedure or transformer (given in the definition) to the arguments. Then the resulting expression is evaluated.

Upload: gerald-lyons

Post on 17-Jan-2016

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

1

Defining Macros in Scheme

Extensibility: A language is extensible if the language can be extended.

New Scheme 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 procedure or transformer (given in the definition) to the arguments.

Then the resulting expression is evaluated.

Page 2: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

2

Two Styles of Macros in DrScheme

“Lispish” macros.Obtained using DEFINE-MACRO, which is now available in a library.They use full Scheme as the language for writing macros, rather than a specialized pattern language. They are more powerful but somewhat more dangerous than hygienic macros.

“Hygienic” macros.Obtained with DEFINE-SYNTAX and SYNTAX-RULES.They have built-in help for avoiding “variable-capture” bugs, but they are less powerful.

Page 3: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

3

Using Lispish Macros in DrScheme

(require (lib "defmacro.ss"))

This makes DEFINE-MACRO available.Works in DrScheme version 201.

Page 4: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

4

Example: NULLIFY

> (define x 5)5> x5> (define-macro (nullify symbol)

(list 'set! symbol ''nil) )

> (nullify x)> xNIL

Page 5: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

5

Macro Expansion for NULLIFYBy defining the macro NULLIFY, we have actually defined a procedure, but it’s not named NULLIFY. It’s called the macro expansion function or transformer for NULLIFY.

When the macro NULLIFY is called, its transformer is applied to the macro argument. And then that result is evaluated. We can see a representation of the intermediate result if we use the procedure MACROEXPAND (to be defined shortly).

> (macroexpand '(nullify total))(SET! TOTAL 'NIL)

Page 6: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

6

Macro Call Evaluation(nullify total)

1. The arguments (unevaluated) are passed to the macro expansion function.

SYMBOL gets as its binding the symbol TOTAL.

2. The expansion procedure is applied.Any macro forms within the expansion are themselves expanded.

(SET! TOTAL 'NIL)

3. The result of expansion is itself evaluated.

Page 7: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

7

MACROEXPAND in DrScheme

(define (macroexpand expr) (syntax-object->datum (expand expr)) )

1. EXPAND transforms the expression (presumably a macro call) by applying the macro’s transformer. Any macro calls within the expansion are also expanded. An object of type SYNTAX is returned.

2. The syntax object is converted into an S-expression by SYNTAX-OBJECT->DATUM.

Page 8: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

8

Example: IF-N-Z-P> (define-macro (if-n-z-p numexpr negform zeroform posform)(list 'cond (list (list '< (eval numexpr) 0) negform) (list (list '= (eval numexpr) 0) zeroform) (list (list '> (eval numexpr) 0) posform) (list t '(print 'error)) ) )

Page 9: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

9

Macro Expansion: IF-N-Z-P> (macroexpand '(if-n-z-p (* 3 -5) -35 'zero 37))Produces code approximately equivalent to:(IF (< -15 0) -35 (IF (= -15 0) 'ZERO (IF (> -15 0) 37 (PRINT 'ERROR))))

Note that COND, which is implemented as a macro in GCL, was expanded, too.

The macro expansion process for this macro is a little inefficient, because the numerical expression is always evaluated 3 times. We could rewrite the macro to perform the expansion once, save the value in a local variable, and access it three times. But, what should we name the variable?The safe thing to do is use GENSYM to synthesize a unique symbol and use it. (An optional exercise - and fairly tricky).

Page 10: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

10

Example: PUSH

> (define-macro (push element stack)(list 'if (list 'null? stack) (list 'set! stack (list 'quote (list element))) (list 'set! stack (list 'cons element stack)) ) )

Page 11: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

11

Macro Expansion for PUSH

> (macroexpand '(push 5 s))(IF (NULL? S) (SET! S '(5)) (SET! S (CONS 5 S)))

Page 12: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

12

Full Macro-form Evaluation

First the form is fully expanded, and then the resulting form is evaluated.

> (define mystack () )> (push 5 mystack )> (push '(next element) mystack )> mystack((NEXT ELEMENT) 5)

Page 13: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

13

Example: TWICETakes any number of forms and evaluates them all once and then all again.

> (define-macro (twice . forms) (append '(begin) forms forms) )> (twice (display "Macros are powerful") (newline) (display "Aren’t they?") (newline) )Macros are powerfulAren’t they?Macros are powerfulAren’t they?

Page 14: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

14

Example: AVERAGETakes two numeric arguments and returns the mean.> (define-macro (average num1 num2) (list '/ (list '+ (eval num1) (eval num2)) 2) )> (macroexpand '(average 2 (* 5 4)))(/ (+ 2 20) 2)or, in DrScheme (uses top-level env’t):(#%app (#%top . /) (#%app (#%top . +) (#%datum . 2) (#%datum . 20)) (#%datum . 2))

> (average 2 (* 5 4))11Arguments to macros are not automatically evaluated, as they are in function calls.

Page 15: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

15

Example: SET-TO-ONETakes any number of arguments, which must be symbols, and gives each the value 1.

> (define-macro (set-to-one . symbols) (append '(begin) (map (lambda (s) (list 'set! s 1)) symbols)))> (macroexpand '(set-to-one x y z))(BEGIN (SET! X 1) (SET! Y 1) (SET! Z 1))> (define x 0)> (define y 0)> (define z 0)> (set-to-one x y z)> y1

Page 16: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

16

Backquote and Comma Syntax

Allows the body of a macro to look like the expanded form.

> (define-macro (push element stack)‘(if (null? ,stack) (set! ',stack '(,element)) (set! ,stack (cons ,element ,stack)) ) )

>(macroexpand '(push 5 s))(IF (NULL? S)(SET! 'S '(5))(SET! S (CONS 5 S)))

Backquote is like QUOTE but it allows subexpressions preceded by a comma to be evaluated.

Page 17: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

17

Example: ENQUEUE

Like PUSH, but puts the new element at the end of the list.

> (define-macro (enqueue item lst)‘(if (null? ,lst) (set! ',lst '(,item)) (nconc ,lst (list ,item)) ) )

> (define q '(a b c))> (enqueue 'd q)> q(A B C D)

Page 18: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

18

Procedure NCONCDestructively concatenate two lists by creating a pointer from the CDR of the last cons in the first list to the first cons of the second list.

> (define (nconc l1 l2) (cond ((null? l1) ()) ((pair? (cdr l1)) (nconc (cdr l1) l2)) (#t (set-cdr! l1 l2)) ) )

> (define lst1 '(a b c))> (define lst2 ‘(d e f))> (nconc lst1 lst2)> lst1(A B C D E F)

Page 19: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

19

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 20: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

20

Example: SELECTNote that the backquote doesn’t have to be at top-level. Also note the use of the dot (.) in the body which means that the list that follows should be spliced into the current list.

(define-macro (select object . clauses) (append '(cond) (map (lambda (clause) `((equal? (car ',clause) ,object) . ,(cdr clause)) ) clauses)))

Page 21: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

21

Using DEFINE-SYNTAX and SYNTAX-RULES in DrScheme

We do not need to use(require (lib "defmacro.ss"))

Instead of DEFINE-MACRO we use DEFINE-SYNTAX and SYNTAX-RULES. This creates a hygienic macro and requires that we use a pattern language.

Works in DrScheme version 201.

Page 22: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

22

WHEN

(define-syntax when (syntax-rules () ((_ condition form ...) (if condition (begin form ...)) ) ) )> (define n 2)> (when (= n 2) (display n)(newline))2

Page 23: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

23

WHEN … EXCEPT> (define-syntax when (syntax-rules (except) ((_ condition form except c) (if (and condition (not c)) (begin form)) ) ((_ condition form ...) (if condition (begin form ...)) ) ) )> (define n 18)> (when (even? n) (display 'not-prime) except (= n 2))NOT-PRIME> (set! n 2)> (when (even? n) (display 'not-prime) except (= n 2))(nothing)Note … must occur at the end of a list.

Page 24: CSE 341 -- S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures

CSE 341 -- S. Tanimoto Macros

24

Language ExtensionA new control structure, such as SELECT, is a good example of extending a language.

Most languages allow user-defined functions, which provide a first level of language extension.

By providing a coherent set of extensions to Lisp, typically containing both macro and function definitions, you can create an embedded language (EL).

If you need a domain-specific language, an EL may be the way to go, because: The EL takes advantage of its host language, Lisp, for its basic syntax, parsing, and for handling lots of generic functionality.

Example domains: knowledge representation, automatic theorem proving, text-processing, combinatorics, gene sequence processing.