[plt-scheme] Macro troubles
Hi Killian,
I am a Scheme newbie as well, but have been recently also struggling
through macros :)
What I can tell you immediately that procedure-arity will not work in
macros as expected. In Scheme macro expansion is a phase that precedes
evaluation, and code executed at that phase cannot access the run-time
bindings. So, for code working in the macro stage, foo is always 'foo,
never its value, such as (lambda ...)
Do you really need procedure-arity? Can you give an example of your
macro and what you want it to expand to?
Finally, have you checked syntax-rules and define-macro macros? I find
those simpler than syntax-case.
Bests,
--Anton
On Mon, Jun 23, 2008 at 10:53 PM, Killian McCutcheon <entarter at gmail.com> wrote:
> I'm having a bit of trouble re-implementing a DSL using macros (I'm a macro
> newbie). The DSL is very simple, looks like this:
> (commands
> player "Please Sir! Can I have some more?"
> show-item "soup"
> play-sound "sfx_aghast"
> skip-next-wait
> npc "MORE!?!?"
> show-item "scowl"
> wait-input)
> Its a script for a game, with lists of commands that are performed in
> certain situations. Some of the commands take a string or a number as a
> parameter, others have no parameters. Now, the script is not written by a
> programmer, so to make it easier for the designer, I offered him this syntax
> where there are only parentheses around the whole form, and not around each
> individual command in the list. My solution without macros was to define
> commands as evaluating to symbols of the same name, and just pass all
> arguments to the commands function to a parsing function. It worked well,
> but there was a lot of repetitive code.
> Now as an exercise I'm reimplementing the DSL using macros. The commands are
> defined using a macro, which seems to work fine. Then I try to define
> the commands form like this:
> (define-syntax (commands stx)
> (syntax-case stx ()
> [(_ unary arg rest ...)
> (eq? 1 (procedure-arity (syntax-object->datum (syntax unary))))
> (syntax (cons (unary arg) (_ rest ...)))]
> [(_ nullary rest ...)
> (eq? 0 (procedure-arity (syntax-object->datum (syntax nullary))))
> (syntax (cons (nullary) (_ rest ...)))]
> [(_ '()) (syntax '())]))
>
>
> but that gives me the error:
>
> procedure-arity: expects argument of type <procedure>; given player
> So Im guessing either the definitions of my commands aren't available in the
> compile-environment, or I have to jump through extra syntax hoops to get at
> them. I try to make do with second best:
> (define-syntax (start stx)
> (syntax-case stx ()
> [(_ unary arg rest ...)
> (or (string? (syntax-object->datum (syntax arg)))
> (number? (syntax-object->datum (syntax arg))))
> (syntax (cons (unary arg) (_ rest ...)))]
> [(_ nullary rest ...)
> (syntax (cons (nullary) (_ rest ...)))]
> [(_ '()) (syntax '())]))
> but that gives me the error:
> commands: bad syntax in: commands
> and highlights the recursive call to the macro in the first template. Thing
> is I don't know why, and the Dybvig paper "Writing Hygienic Macros in Scheme
> with Syntax-Case" seems to contain very similar code in the cond macros.
> So basically I'm flummoxed, and any help would be appreciated.
> Cheers,
> Killian
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>