guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: problems with syntax-case and with-syntax


From: Matt Wette
Subject: Re: problems with syntax-case and with-syntax
Date: Sun, 27 Aug 2017 20:48:29 -0700

> On Aug 27, 2017, at 5:36 PM, Mark H Weaver <address@hidden> wrote:
> 
> Matt Wette <address@hidden> writes:
> 
>> Q1) The code below creates two macros.  One called `define-foo' which 
>> generates a new identifier and 
>> then defines that to #t.  The other, `define-foo/p', generates the same 
>> identifier (lexical issue?) 
>> and another identifier, then "calls" define-foo and then uses both 
>> identifiers in a `define'.  When
>> executed I get this error:
>> 
>> scheme@(guile-user)> (define-foo/p abc)
>> ;;; <stdin>:2:0: warning: possibly unbound variable `wrap-abc'
>> <unnamed port>:2:0: <unnamed port>:2:0: In procedure module-lookup: Unbound 
>> variable: wrap-abc
>> 
>> What am I doing wrong here?
> 
> The problem is that in Guile 2.2, whenever (define <id> ...) is found in
> the expanded code, where <id> was introduced by a macro (i.e. not passed
> as an explicit argument to the macro), Guile will rewrite the <id> into
> a new name based on the hash of the entire definition form.
> 
> I don't know of any way to make this work without passing 'wrap-abc'
> explicitly as an argument to the 'define-foo' macro.
> 
> FWIW, I've always been opposed to these non-standard semantics, but they
> were included in Guile 2.2 over my strenuous objections:
> 
>  https://lists.gnu.org/archive/html/guile-devel/2014-01/msg00061.html
>  https://lists.gnu.org/archive/html/guile-devel/2011-11/msg00021.html
>  https://lists.gnu.org/archive/html/guile-devel/2011-11/msg00042.html
> 
>> Q2) Also with respect to the code below.  Is there any way to pull the
>> definitions for stx->str and gen-id out of the define-syntax body to
>> make them general purpose?
> 
> Yes, you can wrap the definitions of 'stx->str' within 'eval-when', like
> this:
> 
>  (eval-when (expand load eval)
>    (define (stx->str stx)
>      ...)
>    (define (gen-id tmpl-id . args)
>      ...))
> 
> above the macro definitions that use them.
> 
> One more thing:
> 
>> (define-syntax define-foo
>>  (lambda (x)
>>    (define (stx->str stx)
>>      (symbol->string (syntax->datum stx)))
>>    (define (gen-id tmpl-id . args)
>>      (datum->syntax
>>       tmpl-id
>>       (string->symbol
>>      (apply string-append
>>             (map (lambda (ss) (if (string? ss) ss (stx->str ss))) args)))))
>>    (syntax-case x ()
>>      ((_ name)
>>       (with-syntax ((wrap (gen-id x "wrap-" #'name)))
>>       #'(begin
>>           (define wrap #t)))))))
> 
> Here, the 'tmpl-id' that is being passed to 'datum-syntax' is not
> actually an identifier, but rather a compound syntax object.  Although
> we do not currently raise an error in this case (we probably should), it
> is against the spec and likely to cause problems in the future, if not
> today.  You should pass an actual identifier as 'tmpl-id'.
> 
>     Regards,
>       Mark
> 

Thanks.  Things look much better now.

I just added a case for define-foo syntax with an extra arg for wrap, so I can 
pass it.
I wrapped gen-id in the eval-when.  (Yay!)
I replaced `(gen-id x "wrap-" #'name)' with `(gen-id #'name "wrap-" #'name)'.
(I used to write the last step that way but picked up a bad habit at some time.)

Matt




reply via email to

[Prev in Thread] Current Thread [Next in Thread]