[plt-scheme] #%app literal does not match in syntax-case pattern

From: Carl Eastlund (carl.eastlund at gmail.com)
Date: Sat Nov 21 00:14:35 EST 2009

On Fri, Nov 20, 2009 at 8:45 PM, Marco Monteiro <masm at acm.org> wrote:
> On Sat, Nov 21, 2009 at 12:39 AM, Eli Barzilay <eli at barzilay.org> wrote:
>>
>> On Nov 20, Marco Monteiro wrote:
>> > One thing I forgot to mention: define, define-values and lambda in
>> > the code fragments are from the scheme language. If I didn't
>> > code-walk (or expand on the reader), I wouldn't be able to store the
>> > expanded code, right?  The problem, in this case, is hygiene (I
>> > can't replace scheme's define-values because define expands to it)
>> > and the quote: the code inside it is not expanded.
>>
>> Yes, if you want the expanded code then you need to expand it -- but
>> why do you need to walk over the code?  Or maybe you're talking about
>> some compilation step of the expanded code (which is not what code
>> walkers are usually used for in CL, at least IIRC).
>>
>
> It may not be necessary (maybe this is implemented already somewhere
> in the library), but here is what I do:
>
> Given, in a module context:
>
> (define (x) (* x x))
>
> I want to get:
>
> (list 'define-values '(x) (list '#%app '* 'x 'x))
>
> I export #%module-begin from my language that wrap every immediate
> subform in a X macro. The X macro takes the (define-values (x) (* x x)) form
> and returns (list 'define-values '(x) (Y (* x x))). The Y macro code-walks
> the
> forms: it takes (* x y) and returns (list #'app (Y *) (Y x) (Y x)). Finally,
> we get what we
> want. The Y macro uses local-expand.
>
> This is a simplification. The Y macro returns more than symbols and
> lists of symbols. For example, it may expand to an expression
> that builds a syntax tree with location information.
>
> Is there a better way to get the expansion as given in the example above?
> Maybe something that recursively applies local-expand to subforms. If there
> is, I can use that and then traverse all the expanded code in one go.
>
> Thanks.
>
> Marco

Marco (I almost typed "Macro" in place of your name),

Why do you need to use "Y" to perform the recursive expansion?  Why
not just have your #%module-begin run local-expand on a regular
#%module-begin wrapped around the contents, and post-process the fully
expanded result?  You can go from unexpanded code to expanded code in
one non-recursive line of code.  Then you can emit whatever code you
want.  And you don't need to emit lists (in fact, emitting lists will
give you *bad* results with respect to hygienic macro expansion) if
you want "Scheme ASTs".  Syntax objects are Scheme ASTs, and have
source location information -- you might as well just keep the whole
syntax object around.  The only real work you'll need to do is
replacing top level expressions and the bodies of top level
definitions with stubs (calls to void), and that's very shallow
processing.

--Carl


Posted on the users mailing list.