[racket] Problem with macro
Thank you, Neil.
I really appreciate your answer. I've just started programming with syntax-rules and I see now that I have lot to learn further about these scheme-way macros.
Unfortunately, i'm currently unable to produce this macro with syntax-rules or syntax-case.
But i have done it in classic, "old fasioned" way:
#lang racket
(require mzlib/defmacro (for-syntax racket))
(define-macro (automaton init-state transitions)
(let* ([curr-state (gensym)]
[make-transition (lambda (transition)
(let ([state (first transition)]
[endstate (third transition)])
`((,state) (set! ,curr-state ,endstate) ,(if (eq? endstate 'END)
''endstate
''ok))))]
[make-state (lambda (state-def)
(let ([state-name (first state-def)]
[transitions (cddr state-def)])
`(,state-name
(lambda (symbol)
(case symbol
,@(map make-transition transitions)
(else 'transition-error))))))])
`(letrec ([,curr-state null]
[END
(lambda (symbol)
'read-past-end-error)]
,@(map make-state transitions))
(set! ,curr-state ,init-state)
(lambda (c)
(,curr-state c)))))
(define mydfa
(automaton start
((start : (c -> more))
(more : (a -> more)
(d -> more)
(r -> END)))))
By the way, i have created stateful dfa purposely (by using variable curr-state as DFA's state) so that i can "feed" it with symbols, one by one, i.e.
> (mydfa 'c)
ok
> (mydfa 'a)
ok
> (mydfa 'd)
ok
> (mydfa 'r)
endstate
Shriram's approach (described here: http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk-automata-macros/paper.pdf ) forces us to give input all in one take.
Racket Noob
> Date: Fri, 12 Aug 2011 10:22:18 -0400
> From: neil at neilvandyke.org
> To: racketnoob at hotmail.com
> CC: users at racket-lang.org
> Subject: Re: [racket] Problem with macro
>
> 1. Without trying it, I'm pretty sure this particular syntax
> transformation can be done in "syntax-rules", but I'm not certain it can
> be done using only the power of "..." in "syntax-rules", without a
> helper macro. Your life might be easier if you do this particular
> transformation in "syntax-case" rather than "syntax-rules".
>
> 2. If you use "syntax-rules" instead of "syntax-case", three tips: (1)
> break it up into mutiple macros, so you can have secret recursive helper
> macros that have arguments for lists of input that you haven't processed
> and arguments for lists of output from that processing, such as for
> assembling lists of "letrec" or "case" clauses; (2) instead of
> "process-state", you can have your helper macros assemble some of the
> ultimate code *bottom-up*, so that, for example, things like the
> "letrec" clauses (or "case" clauses, or parts of "case" clauses) get
> assembled first, and only after all the clauses are assembled do the
> "letrec" and other unchanging stuff around them get assembled; and (3)
> it's good to expand to "case"/"if"/"and"/"or" for control flow, but
> avoid expanding to "cond", because it's syntactic-sugary, and you'd have
> to worry about "else" and "=>" appearing in your macro input.
>
> 3. You've picked a somewhat tricky macro for "syntax-rules" -- harder
> than most "syntax-rules" macros you'll usually want to implement. But
> once you can implement this macro, I think you'll then have the tools to
> implement most any other "syntax-rules" macro you want to in the
> future. If you get stuck on this one, try simpler ones that isolate a
> single tricky part. For example, contrive a programming exercise of a
> macro that's a thin veneer around "case", and implement your macro using
> a recursive helper macro rather than "...", to assemble each "case"
> clause, one clause per recursion step. (Or just use "syntax-case", and
> be done with it.)
>
> 4. Before you spend too much time writing a macro for that particular
> transformation, you might want to experiment some more with that example
> you gave of code you're trying to transform to. See whether your state
> transitions can simply can use tail calls to your "letrec" bindings for
> the state closures, so that you need neither the "curr-state" variable
> not the "ok" and "endstate" values. That would be more
> Racket-idiomatic, the compiler might be able to optimize the code
> better, and it might make your macro easier to implement.
>
> (Pardon the writing in enumerations, but someone erroneously put caf
> coffee in the decaf coffee carafe.)
>
> --
> http://www.neilvandyke.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110812/b53543c2/attachment.html>