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: Mark H Weaver
Subject: Re: problems with syntax-case and with-syntax
Date: Sun, 27 Aug 2017 20:36:53 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux)

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



reply via email to

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