Saturday, June 26, 2010

Simple Macros in Scheme

Simple Macros in Scheme

Simple Macros in Scheme

As I mention elsewhere, there are a number of macro systems for Scheme. The Scheme standard R5RS specifies one called syntax-rules that most Scheme implementations include. It is quite simple relative to its power. But if you want to start making macros as quickly as possible, especially if you just want to get call-by -reference, -name or -need semantics, you can use the following even simpler (but less powerful) system. Just load the definition provided at the end into any Scheme implementation that has syntax-rules.

Using the Simple-Syntax System

The syntax for defining macros in this system is similar to that for defining functions. In fact if the macro has a fixed number of arguments the syntax is identical. For example:
; Define a simple macro to add a value to a variable.
;
(define-simple-syntax (+= variable value)
(set! variable (+ variable value)))

; Use it.
;
(define v 2)
(+= v 7)
v ; => 9
For a fixed number of arguments followed by an unknown number of arguments we use ... after a single argument to represent the unknown number (possibly zero) of arguments. For example, let's revise our definition of += to allow zero or more values to be added:
; Define a simple macro to add a zero or more values to a variable
;
(define-simple-syntax (+= variable value ...)
(set! variable (+ variable value ...)))

; Use it
;
(define v 2)
(+= v 7)
v ; => 9
(+= v 3 4)
v ; => 16
(+= v)
v ; => 16
Simple-syntax allows more advanced handling of arguments based on their structure: you can require a certain structure and rearrange the components. The definition of for is a good start (though it doesn't actually rearrange any components). But if you start using structured arguments seriously you may need to read about patterns and templates in syntax-rules.

Implementation of the Simple-Syntax System

; Syntax for defining macros in a simple style similar to function definiton,
;  when there is a single pattern for the argument list and there are no keywords.
;
; (define-simple-syntax (name arg ...) body ...)
;
(define-syntax define-simple-syntax
(syntax-rules ()
((_ (name arg ...) body ...)
(define-syntax name (syntax-rules () ((name arg ...) (begin body ...)))))))

No comments: