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: n...@neilvandyke.org > To: racketn...@hotmail.com > CC: users@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/
_________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users