Macros and Function Generators CS 480/680 – Comparative Languages.

Presentation on theme: "Macros and Function Generators CS 480/680 – Comparative Languages."— Presentation transcript:

Macros and Function Generators CS 480/680 – Comparative Languages

Macros2 List Structures  When we have a list like this: ’(1 2 3 4) we know the structure looks like this:  Likewise, when you create code like this: (+ 2 3) you end up with a structure like this: 1234+23

Macros3 Creating Code  A powerful feature of Scheme is the ability to create code on the fly: (define a ‘(+ 3 2)) (list a a a) >> ((+ 2 3) (+ 2 3) (+ 2 3)) (eval (cons ‘begin (list a a a))) >> 5  begin only returns the result of the last subform evaluated. However, here (+ 2 3) was evaluated three times

Macros4 Macros  A Scheme macro is a function that: Produces a list, and then Evaluates the list  Differs from an ordinary function, in that the list that is produced is evaluated The macro returns whatever the evaluated list returns

Macros5 Macro Shortcuts  Within a macro, you can use a list template: Starts with a backquote: ` Inside the template: ,symbol – replaced by a macro parameter ,@symbol – replaced by a spliced parameter. That is, a parameter with the outer set of parentheses removed

Macros6 A simple example  Arguments to lambda are collected in the list: ((display “hi”) (newline))  Template creates: (begin (display “hi”) (newline) (display “hi”) (newline) (display “hi”) (newline)) (require (lib ”defmacro.ss”)) (define-macro do3 (lambda code `(begin,@code,@code,@code))) (do3 (display "hi") (newline)) hi Notice the lack of quotes!

Macros7 A more complicated example  Suppose we wanted a function called “when”, that would take as arguments a test and multiple subforms If the test is true, all the subforms are executed Like ‘if’, but: (if (test) (begin (form1) (form2) (form3)… ) )

Macros8 A more complicated example (when (< (pressure tube) 60) (open-valve tube) (attach floor-pump tube) (depress floor-pump 5) (detach floor-pump tube) (close-valve tube)) Test Subforms

Macros9 A more complicated example (define-macro when (lambda (test. branch) (list 'if test (cons 'begin branch)))) (when (< (pressure tube) 60) (open-valve tube) (attach floor-pump tube) (depress floor-pump 5) (detach floor-pump tube) (close-valve tube))

Macros10 A more complicated example (define-macro when (lambda (test. branch) (list 'if test (cons 'begin branch)))) test = (when (< (pressure tube) 60) branch = ((open-valve tube) (attach floor-pump tube) (depress floor-pump 5) (detach floor-pump tube) (close-valve tube))

Macros11 A more complicated example (define-macro when (lambda (test. branch) (list 'if test (cons 'begin branch)))) test = (< (pressure tube) 60) branch = ((open-valve tube) (attach floor-pump tube) (depress floor-pump 5) (detach floor-pump tube) (close-valve tube)) >> (if (< (pressure tube) 60) (begin (open-valve tube) … )

Macros12 Variable Capture  Since a macro is a textual translation, it does not introduce a new local scope!  If a macro uses a local variable name (via let) that is the same as a variable of a higher scope, the higher scoped variable cannot be passed as a macro parameter Can leave quite a mess  Solution – (gensym) creates a unique symbol name that can be used with,name in a template