[racket] Macro Help
On 02/26/2012 07:39 PM, Neil Van Dyke wrote:
> Helmut Rohrbacher wrote at 02/26/2012 07:18 PM:
>> What macro voodoo do I need to harness in order to be able to
>> implement the first definition syntax where the /args ... -> body/
>> segments need not be wrapped in parens?
>
> I think that the difficulty is due to using old "syntax-rules".
> Nowadays, "syntax-rules" is a hobby for the patient, like building model
> ships in bottles.
Ships in bottles? Great fun! [1]
This one isn't so hard if you allow yourself some helper macros. The
idea is to walk over the body, searching for the literal -> followed by
the value expression. As you walk, accumulate what precedes the ->, and
when you find it, create a list of the accumulator and the value
expression and accumulate it into another list of pattern/value lists.
When you run out of body, pass that pattern/value list accumulator to a
third macro.
As always, DrRacket's macro stepper is very useful for these kinds of
macros.
Here it is in code:
(define-syntax function
(syntax-rules ()
((_ body ...)
(function-accumulate () () (body ...)))))
(define-syntax function-accumulate
(syntax-rules (->)
[(_ () (pattern/value-list ...) ())
(function^ pattern/value-list ...)]
[(_ (pattern ...) (pattern/value-list ...) (-> value body ...))
(function-accumulate ()
(pattern/value-list ...
[(pattern ...) value])
(body ...))]
[(_ (pattern ...) (pattern/value-list ...) (pattern-expr body ...))
(function-accumulate (pattern ... pattern-expr)
(pattern/value-list ...)
(body ...))]))
(define-syntax function^
(syntax-rules ()
((_ [(pattern ...) value] ...)
(match-lambda* [(list pattern ...) value] ...))))
[1] http://www.youtube.com/watch?v=TzqYgEObfB4
--
Brian Mastenbrook
brian at mastenbrook.net
http://brian.mastenbrook.net/