95.501 | 2000 |
6 Macros |
6.1 Quote |
(quote a)
=> a
(quote #(a b c)) =>
#(a b c)
(quote (+ 1 2)) =>
(+ 1 2)
(quote datum) may be abbreviated as 'datum. The two notations are equivalent in all respects.
'a
=> a
'#(a b c) =>
#(a b c)
'()
=> ()
'(+ 1 2) =>
(+ 1 2)
'(quote a) =>
(quote a)
''a
=> (quote a)
Numerical constants, string constants, character constants, and boolean constants evaluate "to themselves"; they need not be quoted.
'"abc" =>
"abc"
"abc" =>
"abc"
'145932 => 145932
145932 => 145932
'#t
=> #t
#t
=> #t
6.2 Quasiquote |
`(list ,(+ 1 2) 4) => (list 3 4)
(let ((name 'a))
`(list ,name ',name))
=> (list
a (quote a))
`(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)
=> (a
3 4 5 6 b)
Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the same nesting level as the outermost backquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation.
`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
=> (a
`(b ,(+ 1 2) ,(foo 4 d) e) f)
(let ((name1 'x)
(name2 'y))
`(a `(b ,,name1 ,',name2 d) e))
=> (a
`(b ,x ,'y d) e)
6.3 Macros |
(WHILE (> x 10)
(display x)
(display " ")
(set! x (- x 1))
ENDWHILE)
(BLOCK a-block-name
(if (= x 10)
(return 10)
(display "hello"))
ENDBLOCK)
(FOR (i=0) (i < 10) (+ i 1)
(display i)
ENDFOR)
6.4 Macros in MIT Scheme |
adds a new keyword (FOO) to <some syntax table> with the obvious
meaning.
6.5 Simple Increment Macro |
(define (my-incr-helper form)
(list 'set! form (list '+ 1 form)))
(syntax-table-define system-global-syntax-table 'my-incr
(macro (arg) (my-incr-helper arg)))
(my-incr i) => results in i being set to 2
6.6 Iff ... then ... else ... endif Macro |
(define (objects-after anObject aList)
(if (null? aList)
'()
(if (equal? (car aList) anObject)
(cdr aList)
(objects-after anObject (cdr aList)))))(define (objects-before anObject aList)
(if (null? aList)
'()
(if (equal? (car aList) anObject)
'()
(cons (car aList)
(objects-before anObject (cdr aList))))))
(define (iff-helper args)
; it is useful to include the followin line if you
want to see what your helper function is processing
;(display args)
(let ((predicate (car args))
(true-part (between 'then 'else args))
(false-part (between 'else 'endif args)))
`(if ,predicate ,@true-part
,@false-part)))
(iff-helper iff-test)
=> (if (< i 10)
(display "x < 10") (display "x >= 10"))
(eval (iff-helper iff-test) (the-environment))
=> x < 10
(iff (< i 10) then (display "x < 10") else (display "x >= 10")
endif)
=> x < 10