Macros for Patzers By A Patzer

Earl Spillar

2011-07-27 Sun

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 1 / 25 Outline

1 Lisp Macro System

2 Uses

3 Macro Pathologies

4 Scheme Macros

5 In Closing

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 2 / 25 Macros as Substitutions

Most simply, macros are pre-compile time substitutions, programmable in lisp Example: (from “”):

(defmacro nil! (var) (list ’setq var nil))

expands as follows:

(nil! aVar) => (setq aVar nil)

Paraphrased in English, this definition tells Lisp: “Whenever you see an expression of the form (nil! var), turn it into one of the form (setq var nil) before compiling/evaluating it.”

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 3 / 25 Some Basics

This happens at macro expansion time, before compile/interpret time It’s essential that we have (something like) lists to enable this Homoiconic: “the primary representation of programs is also a data structure in a primitive type of the language itself”

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 4 / 25 Said another way

Macros are essentially allowing you to write “arbitrary” lisp code which operates on the s-expressions before they are passed to the “There are no semantics behind the syntax” of the s-expr we are munging Multiple macros will be handled recursively (repeatedly). Execution/runtime based on the macro-expanded code. Each chunk code may be run many times.

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 5 / 25 Tools “for” macros

Lisp has several tools useful in macros (It took me a while to realize some of these could be used outside of macros!) It would be painful to build lists using things like (list . . . ) Of course forward quote make literal lists more succinct.

(list a c d) ’(a b c d)

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 6 / 25 Back Quotes and Splicing

In a macro, we frequently want to evaluate some lisp to create the list we are forming at macro expanstion time. Back quotes with comma splices give us a way to evaluate things within a list: ‘(1 2 3 ,(+ 2 2)) => (1 2 3 4) In words, Create the list we are as if it were literal, but evaluate the sexpr after the comma at macro expansion time using the full majesty that is lisp!

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 7 / 25 Splicing

Sometimes we would like to “splice in” a whole list: use ,@ splice

(defparameter b ’(4 5 6)) ‘(1 2 3 ,@b) (1 2 3 4 5 6) Implement like this:

(defmacro sum ( &body body) ‘( + ,@body )) Yields: (sum 1 2 30) => 33 (sum 4 5 1 4 2) => 16

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 8 / 25 Conventional Uses

We’ll discuss each in turn: Providing cosmetics- simplifying code Introducing binding constructs Implementing “control operators”, i.e., ones that alter the order of evaluation Defining Domain Specific Languages (DSLs)

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 9 / 25 Simplification of Code

An example from Land of Lisp: get rid of one layer of parens:

(defmacro let1 (var val &body body) ‘(let ((,var ,val)) @body))

This allows us to do things like this:

(let1 a 2 (+ (* a 3) 4)) => 10

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 10 / 25 Anaphoric macros- macros that create new variables

Macros can do some “prep work” for functions that you feed them Anaphoric macros create some new variables used by the body function: (defmacro split (val fun) ‘(let ((1st (car ,val)) (2nd (cdr ,val))) fun))

(split (cons 4 5) (* 1st 2nd)) => 20

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 11 / 25 Introducing New Control and Data Structures

There are many examples given of doing things like re-creating cond or other structures Basically, you are able to “re-call” the compiler at “run-time”, and change the parsing We are doing things at “run time” that (most) languages only do at “compile time” Rather than an example, lets look in the Quick Reference for examples-

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 12 / 25 Domain Specific Languages

Macros can be used to re-arrange syntax and create little languages that are appropriate for a particular problem domain

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 13 / 25 Stepping Through Expansions

( macroexpand arg) expands it’s argument and returns the expanded argument. (macroexpand ’(split (cons 3 4) (* 1st 2nd))) (LET ((1ST (CAR (CONS 3 4))) (2ND (CDR (CONS 3 4)))) (* 1ST 2ND)) (macroexpand-1) only does the first expansion, rather than performing recursives subsitutions like macroexpand

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 14 / 25 Variable Capture

You may accidentally create an “extra version” of a variable inside you macro.

(defmacro for ((var start stop) &body body) ‘(do ((,var ,start (1+ ,var)) (limit ,stop)) ((> ,var limit)) @body))

(macroexpand ’(for (limit 1 5) princ limit)) => (do ((limit 1 (1+ limit)) (limit 5)) ((> limit limit)) (princ limit))

We have a variable name clash!!

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 15 / 25 Variable Capture Continued

Note anaphoric macros use this “problem” to good effect! One solution is to use something like gensym to create a new name automagically: ( gensym ) -> #:G3422 (a unique variable name) Hygnic macros solve this, to a certain extent- see Scheme Macros

(defmacro split (val yes no) (let1 g (gensym) ‘(let1 ,g ,val (if ,g (let ((head (car ,g)) (tail (cdr ,g))) ,yes) no))))

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 16 / 25 Obscurity

Macros are more difficult to write then functions They (can) change syntax in unusual ways. So, other programmers (and even you!) will have a harder time understanding your code. Sometimes you DO want to create “your own language,” these languages are called DSLs: Domain Specific Languages

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 17 / 25 Quick tour of basic scheme Macros

The scheme community is moving ahead quickly on more advanced macro schemes I will discuss the simplest R5RS scheme macro system Chez Scheme and others are more advanced! Unfortunately, this leads to a little balkanization

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 18 / 25 define-syntax, let-syntax, letrec-syntax

These three are similar except for - Top level, let like, and letrec like. They define that a sexpr with a particular head will be expanded How they will expand is defiend by the (next)

;; define-syntax creates a top-level binding (define-syntax macro-head )

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 19 / 25 syntax-rules (1)

syntax-rules transform the sexpr templates make the changes easier Simplest version:

(define-syntax first (syntax-rules () (( _ aCons) (car aCons))))

> ( first (cons 1 2)) 1

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 20 / 25 syntax-rules (2)

Multiple templates are allowed-

(define-syntax first-2 (syntax-rules () (( _ aCons) (car aCons)) (( _ aCons bCons) (car bCons)) )) > (first-2 (cons 1 2) (cons 3 4)) 3 > (first-2 (cons 1 2)) 1

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 21 / 25 syntax-rules (3)

Keywords can be included as follows:

(define-syntax first-2 (syntax-rules (sec) (( _ aCons) (car aCons)) (( _ aCons bCons) (car bCons)) (( _ sec aCons bCons) (cdr bCons)) ))

> (first-2 sec (cons 1 2) (cons 3 4)) 4

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 22 / 25 Macros are Hygenic!

The “local variables” in the macros are “Hygenic” That is, they WILL NOT shadow variables in the expression being expanded Essentially the (gensym) is “baked in”

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 23 / 25 Questions for the Crowd

Why do folks say Haskell can get away without macros? What are the objects that macros are manipulating? Symbols? Strings?

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 24 / 25 References

All available on line! On Lisp: advanced techniques for Common Lisp. . http://www.paulgraham.com/onlisptext.html. Common Lisp Quick Reference http://clqr.berlios.de/ Scheme Macros http://blog.willdonnelly.net/2008/09/04/a-scheme- syntax-rules-primer/ Automata via Macros http://www.cs.brown.edu/˜sk/Publications/Papers/Published/sk- automata-macros/paper.pdf Scheme Macros http://www.scheme.com/tspl4/

Earl Spillar () Macros for Patzers By A Patzer 2011-07-27 Sun 25 / 25