[plt-scheme] Macro troubles

From: Anton Tayanovskyy (anton.tayanovskyy at gmail.com)
Date: Mon Jun 23 16:15:49 EDT 2008

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.



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

Posted on the users mailing list.