Fear of Macros

Contents:
1 Preface
I learned Racket after 25 years of mostly using C and C++.
Some psychic whiplash resulted.
"All the parentheses" was actually not a big deal. Instead, the first +
Contents:
1 Preface
I learned Racket after 25 years of mostly using C and C++.
Some psychic whiplash resulted.
"All the parentheses" was actually not a big deal. Instead, the first mind warp was functional programming. Before long I wrapped my brain around it, and went on to become comfortable and effective with many other aspects and features of Racket.
But two final frontiers remained: Macros and continuations.
I found that simple macros were easy and understandable, plus there @@ -105,8 +105,8 @@ transformer can rearrange the syntax – rewrite the code – at compile time. The pieces of syntax are moved around, but they aren’t actually evaluated until run time.
Here is one way to do this:
> (define-syntax (our-if-v2 stx) (define xs (syntax->list stx)) (datum->syntax stx `(cond [,(cadr xs) ,(caddr xs)] [else ,(cadddr xs)])))
> (our-if-v2 #t (display-and-return "true") (display-and-return "false")) true
"true"
> (our-if-v2 #f (display-and-return "true") (display-and-return "false")) false
"false"
That gave the right answer. But how? Let’s pull out the transformer function itself, and see what it did. We start with an example of some -input syntax:
> (define stx #'(our-if-v2 #t "true" "false")) > (displayln stx) #<syntax:32:0 (our-if-v2 #t "true" "false")>
1. We take the original syntax, and use syntax->datum to -change it into a plain Racket list:
> (define xs (syntax->datum stx)) > (displayln xs) (our-if-v2 #t true false)
2. To change this into a Racket cond form, we need to take +input syntax:
> (define stx #'(our-if-v2 #t "true" "false")) > (displayln stx) #<syntax:32:0 (our-if-v2 #t "true" "false")>
1. We take the original syntax, and use syntax->list to +change it into a list of syntax objects:
> (define xs (syntax->list stx)) > (displayln xs) (#<syntax:32:0 our-if-v2> #<syntax:32:0 #t> #<syntax:32:0 "true"> #<syntax:32:0 "false">)
2. To change this into a Racket cond form, we need to take
the three interesting pieces—
`(cond [,(cadr xs) ,(caddr xs)] [else ,(cadddr xs)])
3. Finally, we change that into syntax using diff --git a/index.html b/index.html index 6582f28..49fad5a 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,3 @@
Fear of Macros |
Fear of Macros

Contents: