* pending branch: lexical-literals
@ 2011-04-29 15:16 Andy Wingo
2011-05-06 12:17 ` Ludovic Courtès
2011-06-30 11:46 ` Andy Wingo
0 siblings, 2 replies; 4+ messages in thread
From: Andy Wingo @ 2011-04-29 15:16 UTC (permalink / raw)
To: guile-devel
Hi all,
I have a branch that fixes literal matching to actually compare toplevel
bindings, as the RNRS suggest, rather than simply assuming that a
literal that is not lexically bound can be compared symbolically.
(Recall that literals are things like `else' and `=>' in `cond'.)
I send this note because this change increases the coupling between a
macro's definition and the definition of the literals that it
references.
For example, in the past:
scheme@(guile-user)> (cond (else #t))
$1 = #t
Here the `else' is unbound both in the definition of `cond' and at the
use-site, so the literal should match in any case.
scheme@(guile-user)> (define else #f)
scheme@(guile-user)> (cond (else #t))
$2 = #t
Here the `else' is bound at the site of use, but the comparison still
succeeded, because `else' was matched by name (symbolically), not by
binding (lexically).
But now, with this change:
scheme@(guile-user)> (cond (else #t))
$1 = #t
scheme@(guile-user)> (define else #f)
scheme@(guile-user)> (cond (else #t))
scheme@(guile-user)>
`else' did not match, because it was a different binding.
This case has not changed, however:
scheme@(guile-user)> (let ((else #f)) (cond (else #t)))
scheme@(guile-user)>
So whereas before, including something in a literals list did not
specify anything about the toplevel binding, now it does; which
increases the coupling between your macro and your literals.
For example `eval-when' was depending on the bindings of `eval', `load',
`compile', and `expand' at the macro definition and expansion sites. I
didn't want this, so I changed eval-when to match symbolically
instead -- something that is possible with syntax-case, though not
easily facilitated. With that change, Guile recompiled fine, and passed
tests.
This change allows us to bind keywords, and thereby export them from
modules, and have them available for renaming.
See http://article.gmane.org/gmane.lisp.scheme.reports/317 for more
arguments.
I am considering pushing this change to 2.0.x. We will not be binding
literals by default in 2.0.x however, as that would be incompatible. I
am considering doing that in 2.2, though; dunno.
Comments? See the "lexical-literals" branch in git for more.
Cheers,
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: pending branch: lexical-literals
2011-04-29 15:16 pending branch: lexical-literals Andy Wingo
@ 2011-05-06 12:17 ` Ludovic Courtès
2011-05-06 17:39 ` Andy Wingo
2011-06-30 11:46 ` Andy Wingo
1 sibling, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2011-05-06 12:17 UTC (permalink / raw)
To: guile-devel
Hi Andy,
Sorry for the late reply.
Andy Wingo <wingo@pobox.com> writes:
> I have a branch that fixes literal matching to actually compare toplevel
> bindings, as the RNRS suggest, rather than simply assuming that a
> literal that is not lexically bound can be compared symbolically.
>
> (Recall that literals are things like `else' and `=>' in `cond'.)
I think I don’t fully understand the implications yet, partly because it
goes against my idea of what a “literal” is: to me, a literal in
‘syntax-rules’ and ‘syntax-case’ is a symbol, not a binding.
I read the R7RS thread and André Van Tonder does seem to have compelling
arguments, but again, that’s still a bit too disruptive to me. :-)
> I send this note because this change increases the coupling between a
> macro's definition and the definition of the literals that it
> references.
>
> For example, in the past:
>
> scheme@(guile-user)> (cond (else #t))
> $1 = #t
>
> Here the `else' is unbound both in the definition of `cond' and at the
> use-site, so the literal should match in any case.
>
> scheme@(guile-user)> (define else #f)
> scheme@(guile-user)> (cond (else #t))
> $2 = #t
>
> Here the `else' is bound at the site of use, but the comparison still
> succeeded, because `else' was matched by name (symbolically), not by
> binding (lexically).
>
> But now, with this change:
>
> scheme@(guile-user)> (cond (else #t))
> $1 = #t
> scheme@(guile-user)> (define else #f)
> scheme@(guile-user)> (cond (else #t))
> scheme@(guile-user)>
>
> `else' did not match, because it was a different binding.
>
> This case has not changed, however:
>
> scheme@(guile-user)> (let ((else #f)) (cond (else #t)))
> scheme@(guile-user)>
>
> So whereas before, including something in a literals list did not
> specify anything about the toplevel binding, now it does; which
> increases the coupling between your macro and your literals.
OK.
So, with this change, no top-level binding of ‘else’ is /required/, but
/when/ there is one, it prevails over the literal, correct?
But then I don’t understand how the story that you could import/rename
‘else’ fits into this.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: pending branch: lexical-literals
2011-05-06 12:17 ` Ludovic Courtès
@ 2011-05-06 17:39 ` Andy Wingo
0 siblings, 0 replies; 4+ messages in thread
From: Andy Wingo @ 2011-05-06 17:39 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
On Fri 06 May 2011 14:17, ludo@gnu.org (Ludovic Courtès) writes:
> Sorry for the late reply.
No prob; thanks for thinking through it!
> So, with this change, no top-level binding of ‘else’ is /required/, but
> /when/ there is one, it prevails over the literal, correct?
Sorta? This language is imprecise. The real language is in R6RS:
The free-identifier=? procedure returns #t if and only if the two
identifiers would resolve to the same binding if both were to appear
in the output of a transformer outside of any bindings inserted by
the transformer. (If neither of two like-named identifiers resolves
to a binding, i.e., both are unbound, they are considered to resolve
to the same binding.)
Nothing changes in the case that `else' is unbound always.
The change is if it is bound when the macro is defined, but not when it
is used, or vice versa; or, also, if it is bound at both places, but to
different lexical or toplevel variables. In these cases the
lexical-literals branch causes the literals not to match.
OTOH currently a keyword imported under a different name will not match
itself; this branch allows renaming keywords.
> But then I don’t understand how the story that you could import/rename
> ‘else’ fits into this.
I guess basically the summary is "compare literals by identity, not by
name".
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: pending branch: lexical-literals
2011-04-29 15:16 pending branch: lexical-literals Andy Wingo
2011-05-06 12:17 ` Ludovic Courtès
@ 2011-06-30 11:46 ` Andy Wingo
1 sibling, 0 replies; 4+ messages in thread
From: Andy Wingo @ 2011-06-30 11:46 UTC (permalink / raw)
To: guile-devel
Hi,
On Fri 29 Apr 2011 17:16, Andy Wingo <wingo@pobox.com> writes:
> I have a branch that fixes literal matching to actually compare toplevel
> bindings, as the RNRS suggest, rather than simply assuming that a
> literal that is not lexically bound can be compared symbolically.
In the end I think this is too disruptive for stable-2.0, for DSL-style
macros with large literal lists that have relied on symbolic matching.
I will apply it to master though. Perhaps in the future we will bind
`else' and `=>' as well. Also we can add some kind of
#:symbolic-literals option to syntax-case, if that's useful.
Regards,
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-06-30 11:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-29 15:16 pending branch: lexical-literals Andy Wingo
2011-05-06 12:17 ` Ludovic Courtès
2011-05-06 17:39 ` Andy Wingo
2011-06-30 11:46 ` 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).