unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* hygiene and macro-introduced toplevel bindings
@ 2011-02-27 21:37 Andy Wingo
  2011-02-27 22:02 ` Hans Aberg
  2011-02-28  0:15 ` Andreas Rottmann
  0 siblings, 2 replies; 12+ messages in thread
From: Andy Wingo @ 2011-02-27 21:37 UTC (permalink / raw)
  To: guile-devel

Hello all,

Andreas has been struggling with a nonstandard behavior of Guile's
recently, and we should discuss it more directly.

The issue is in expressions like this:

  (define-syntax define-accessor
    (syntax-rules ()
      ((_ getter setter init)
       (begin
         (define val init)
         (define getter (lambda () val))
         (define setter (lambda (x) (set! val x)))

  (define-accessor get-x set-x! 0)

The issue is, what happens when this expression is expanded?

Within a let or a lambda, it expands to an three internal definitions:
`val', `getter', and `setter', where `val' is only visible to within the
`getter' and `setter' procedures.

At the top level, it expands to three definitions: "val", the getter,
and the setter.  However in this case the "val" binding is global to the
module, and can be referenced by anyone.

This is what happens in Guile.  I know that some other Schemes do
different things.  Chez, as far as I understand it, binds "val" in the
module, but under a gensym'd name.  It can do this because its modules
are syntactic: the bindings in a module are not serialized to disk as
simple symbol-binding pairs, but rather the whole expansion-time ribcage
is also written out.  That's how I understand it anyway; I could be
getting things wrong there.

Anyway, in Guile our modules have always been first-class entities.  We
never intern gensym'd names in modules, because who would do that?  You
put a name in a module because you want to be able to name it, either
internally or externally, and gensym'd names don't make any sense
without some sort of translation table, and Guile's first-class modules
have no such table.

Furthermore, gensyms at the top-level have a cost that they do not have
lexically.  When you introduce a lexical binding in a macro and cause a
new name to be allocated to it, that binding only exists within the
scope of that form -- if the form is an expression, it exists during the
dynamic extent of that expression, and if it is a definition, its extent
is bound to the extent of the binding of some /other/ name---the
top-level name.

But when you introduce a generated name to the top-level, you create
some trash "val-12345543" binding which will always be there, and you
don't know why.  It can never be removed by normal means, because
top-level bindings are never removed, and its name is invisible to all
other code -- it has infinite extent.

And that's the thing that really bothers me about generated top-level
names: they are only acceptable if you plan on never changing your
mind.  You're not bothered by the trash name, because you'll never
expand that expression again.

So!  That's my rant.  But this is, even more than usual, a case in which
I could simply be wrong; so if you really want to defend generated
top-level names, now would be a great time to do so ;-)

Cheers,

Andy
-- 
http://wingolog.org/



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

end of thread, other threads:[~2011-04-04 13:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-27 21:37 hygiene and macro-introduced toplevel bindings Andy Wingo
2011-02-27 22:02 ` Hans Aberg
2011-02-28  0:15 ` Andreas Rottmann
2011-02-28 21:28   ` Andy Wingo
2011-02-28 21:49     ` Noah Lavine
2011-03-08 22:33       ` Andy Wingo
2011-02-28 22:32     ` Ludovic Courtès
2011-03-08 22:37     ` Andy Wingo
2011-03-09  9:33       ` Hans Aberg
2011-03-09 20:14         ` Andy Wingo
2011-04-04 13:48           ` Hans Aberg
2011-04-01  8:52       ` Andy Wingo

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).