unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* [bug #31472] Probable psyntax bug with multiple defininitions in the macro expansion
@ 2010-10-26 20:42 Andreas Rottmann
  2011-02-27 12:33 ` Andy Wingo
  0 siblings, 1 reply; 4+ messages in thread
From: Andreas Rottmann @ 2010-10-26 20:42 UTC (permalink / raw)
  To: Andreas Rottmann, bug-guile


URL:
  <http://savannah.gnu.org/bugs/?31472>

                 Summary: Probable psyntax bug with multiple defininitions in
the macro expansion
                 Project: Guile
            Submitted by: rottmann
            Submitted on: Tue 26 Oct 2010 10:42:27 PM CEST
                Category: None
                Severity: 3 - Normal
              Item Group: None
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any

    _______________________________________________________

Details:

Given the following library:

(library (unbound-bug)
  (export define-foo)
  (import (rnrs))

  (define-syntax define-foo
    (lambda (x)
      (syntax-case x ()
        ((_ name)
         (identifier? #'name)
         #'(begin
             (define t '#(1 2 3))
             (define (name) t)))))))


I get this (what I deem faulty) behavior:

scheme@(guile-user)> (import (unbound-bug))
scheme@(guile-user)> (define-foo bar)
scheme@(guile-user)> (bar)
<unnamed port>:2:1: In procedure module-lookup:
<unnamed port>:2:1: Unbound variable: t

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> 

If one modifies the original macro slightly, it works as expected:

  (define-syntax define-foo
    (lambda (x)
      (syntax-case x ()
        ((_ name)
         (identifier? #'name)
         (with-syntax ((t (datum->syntax #'name 't)))
           #'(begin
               (define t '#(1 2 3))
               (define (name) t))))))))

scheme@(guile-user)> (define-foo bar)                                        
                 
scheme@(guile-user)> (bar)
$1 = #(1 2 3)

Also (with the original macro), this works:

scheme@(guile-user)> (let () (define-foo bar) (bar))                         
                 
$1 = #(1 2 3)





    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?31472>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug #31472] Probable psyntax bug with multiple defininitions in the macro expansion
  2010-10-26 20:42 [bug #31472] Probable psyntax bug with multiple defininitions in the macro expansion Andreas Rottmann
@ 2011-02-27 12:33 ` Andy Wingo
  2011-05-21 13:46   ` Göran Weinholt
  0 siblings, 1 reply; 4+ messages in thread
From: Andy Wingo @ 2011-02-27 12:33 UTC (permalink / raw)
  To: Andreas Rottmann, Andy Wingo, bug-guile

Follow-up Comment #1, bug #31472 (project guile):

Hi Andreas,

I have thought about this one a fair amount this weekend.  The issues are
twofold.  One, as you note, the modules are getting resolved wrongly -- the
expansion makes the procedure scope "t" in the macro's module, not the
expansion module.  The question is, what should happen?

According to all the hygiene folk I hear from, the (define t #(1 2 3))
shouldn't actually create a binding for "t" in any module.

A simpler case is the following:

  (define-syntax define-x
    (syntax-rules ()
       ((_) (define x 0))))

The issue is, what should happen when you (define-x) ?  Should you later -- in
the REPL, say -- be able to access a binding named "x" in the current module?

Hygiene people say no.  Hygiene people say that since the identifier "x" was
introduced by the macro, it should be visible only within the macro --- and
since it's not used elsewhere in the macro, effectively it's invisible. 
Though you can't really know its extent of course.  And, in Guile, if we were
to gensym a name for it -- a wild thing to think about doing, serializing a
useless (define x_21234113132 0) into a .go file -- it would still take up
"space" in the module (and the .go file), every time you (define-x) you would
be adding useless, inaccessible bindings to your image.  It doesn't seem like
a great idea.

So, unless I misunderstand the issues or am overlooking a solution, I think
that Guile will continue to bind "t" in the expanding module, as indeed
happens in this macro.

The second problem thus "resolved", we need to make the procedure in the
expansion scope its "t" according to the "t" it introduces.  This only happens
when expanding a toplevel sequence -- chi-top-sequence, in psyntax.scm.  I
have recently refactored that procedure to be able to know what bindings it
introduces before going to expand the expressions.  So your mission, should
you choose to accept it, is to distructively mutate the toplevel ribcage
before going in to expand the sub-expressions in chi-top-sequence.

Good luck!

Andy

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?31472>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug #31472] Probable psyntax bug with multiple defininitions in the macro expansion
  2011-02-27 12:33 ` Andy Wingo
@ 2011-05-21 13:46   ` Göran Weinholt
  2011-06-09 16:48     ` Stefan Israelsson Tampe
  0 siblings, 1 reply; 4+ messages in thread
From: Göran Weinholt @ 2011-05-21 13:46 UTC (permalink / raw)
  To: Andreas Rottmann, Andy Wingo, Göran Weinholt, bug-guile

Follow-up Comment #2, bug #31472 (project guile):

Hello guilers,

I want to note some problems that I suspect are caused by this bug. In
this example it looks like (define-foo foo1) and (define-foo foo2) use
the same identifier for `t' (the latter definition overrides the
first):

GNU Guile 2.0.1.79-a02a
Copyright (C) 1995-2011 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> (library (temporaries-bug)
                       (export foo1 foo2)
                       (import (rnrs))

                       (define-syntax define-foo
                         (lambda (x)
                           (syntax-case x ()
                             ((_ name)
                              (identifier? #'name)
                              #'(begin
                                  (define t '(foo name))
                                  (define (name) t))))))

                       (define-foo foo1)
                       (define-foo foo2))
scheme@(temporaries-bug)> ,m (guile-user)
scheme@(guile-user)> (import (temporaries-bug))
scheme@(guile-user)> (foo1)
$1 = (foo foo2)
scheme@(guile-user)> (foo2)
$2 = (foo foo2)

One can workaround this issue by using generate-temporaries. But that
doesn't work when (name) is syntax. Here I expect the library to
export syntax that can be used as (foo3), which would evaluate to the
list (foo foo3):

scheme@(guile-user)> (library (temporaries2-bug)
                       (export foo3 foo4)
                       (import (rnrs))

                       (define-syntax define-foo
                         (lambda (x)
                           (syntax-case x ()
                             ((_ name)
                              (identifier? #'name)
                              (with-syntax (((t) (generate-temporaries
#'(name))))
                                #'(begin
                                    (define t '(foo name))
                                    (define-syntax name
                                      (lambda (x)
                                        (syntax-case x ()
                                          ((_) #'t))))))))))

                       (define-foo foo3)
                       (define-foo foo4))
scheme@(temporaries2-bug)> ,m (guile-user)
scheme@(guile-user)> (import (temporaries2-bug))
scheme@(guile-user)> (foo3)
;;; <stdin>:7:0: warning: possibly unbound variable `#{ g238}#'
<unnamed port>:6:0: In procedure #<procedure 1e50a00 at <current input>:7:0
()>:
<unnamed port>:6:0: In procedure module-lookup: Unbound variable: #{ g238}#

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> 


    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?31472>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug #31472] Probable psyntax bug with multiple defininitions in the macro expansion
  2011-05-21 13:46   ` Göran Weinholt
@ 2011-06-09 16:48     ` Stefan Israelsson Tampe
  0 siblings, 0 replies; 4+ messages in thread
From: Stefan Israelsson Tampe @ 2011-06-09 16:48 UTC (permalink / raw)
  To: Andreas Rottmann, Andy Wingo, Göran Weinholt,
	Stefan Israelsson Tampe, bug-guile

Follow-up Comment #3, bug #31472 (project guile):

I'm trying to understand useful ideoms where this is useful.

One main is to store a state, t, shared by different users 
that are published in an interface. This can be solved by,

(library 
 (temporaries-bug)
 (export foo1 foo2)
 (import (rnrs))

 (define-syntax define-foo
   (lambda (x)
     (syntax-case x ()
       ((_ name)
	(identifier? #'name) 
	#'(begin
	    (define (name) #t)
	    (let ((t '(foo name)))
	      (set! name (lambda () t))))))))

 (define-foo foo1)
 (define-foo foo2))

Any more ideoms?

/Stefan

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?31472>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-06-09 16:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-26 20:42 [bug #31472] Probable psyntax bug with multiple defininitions in the macro expansion Andreas Rottmann
2011-02-27 12:33 ` Andy Wingo
2011-05-21 13:46   ` Göran Weinholt
2011-06-09 16:48     ` Stefan Israelsson Tampe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).