From: Jean Abou Samra <jean@abou-samra.fr>
To: guile-user@gnu.org
Subject: Inconsistencies with free-identifier=? and bound-identifier=?
Date: Fri, 21 Jul 2023 02:20:03 +0200 [thread overview]
Message-ID: <008f724d79b871ce1d68121402bbcbcdd25ec270.camel@abou-samra.fr> (raw)
[-- Attachment #1: Type: text/plain, Size: 4142 bytes --]
Hi,
Consider the following test program.
(define-syntax foo-test
(lambda (sintax)
(let ((foo1 (let ((foo 'bar))
(syntax foo)))
(foo2 (let ((foo 'bar))
(syntax foo))))
(display "free-identifier=? ")
(display (free-identifier=? foo1 foo2))
(newline)
(display "bound-identifier=? ")
(display (bound-identifier=? foo1 foo2))
(newline)
(with-syntax ((foo1 foo1) (foo2 foo2))
(syntax
(let ((foo2 'not-shadowed))
(let ((foo1 'shadowed))
(display foo2) (newline))))))))
(foo-test)
Result on Guile 3.0:
free-identifier=? #f
bound-identifier=? #t
4.5/home/jean/tmp/tmp.scm.go
shadowed
Result on Chez Scheme:
free-identifier=? #f
bound-identifier=? #t
shadowed
Result on Kawa:
free-identifier=? #t
bound-identifier=? #t
not-shadowed
Result on Racket:
free-identifier=? #t
bound-identifier=? #t
shadowed
Who's right?
First, it makes little sense in Kawa that bound-identifier=?
returns #t, yet foo1 does not shadow foo2. That seems like
it's contradicting the whole purpose of bound-identifier=?.
In Racket, they're said to be bound-identifier=? and shadowing
happens, which is at least consistent.
I don't understand why Racket and Kawa say they're
free-identifier=? . They clearly don't refer to the same
binding.
But putting that apart, is shadowing supposed to happen in the
first place?
R6RS-lib 12.5 page 54 says:
(bound-identifier=? id1 id2)
Id1 and id2 must be identifiers. The procedure bound-
identifier=? returns #t if a binding for one would capture
a reference to the other in the output of the transformer,
assuming that the reference appears within the scope of
the binding, and #f otherwise. In general, two identi-
fiers are bound-identifier=? only if both are present in
the original program or both are introduced by the same
transformer application (perhaps implicitly—see datum->
syntax). Operationally, two identifiers are considered
equivalent by bound-identifier=? if and only if they have
the same name and same marks (section 12.1).
As far as I understand, the marks of these two identifiers
are indeed expected to be the same, because marks are applied
on inputting a syntax object to a macro transformer and
receiving its output. foo1 and foo2 are both created and
used within the same macro transformer application, so
they bear no marks, so Guile and Chez are right.
On the other hand, I thought that bound-identifier=? implied
free-identifier=?, but that is not the case according to
Guile, Chez Scheme and this interpretation of R6RS. Yet this
is written on
https://www.scheme.com/tspl2d/syntax.html
Is that page incorrect?
In Dybvig's paper "Syntactic Abstraction in Scheme", which I think
historically introduced the algorithm used by most Scheme implementations
today, it is written on page 12
Two identifiers that are bound-identifier=? are also free-identifier=?, but
two identifiers that are free-identifier=? may not be bound-identifier=?.
https://legacy.cs.indiana.edu/~dyb/pubs/LaSC-5-4-pp295-326.pdf
And later on page 24:
Two identifiers i1 and i2 are free-identifier=? if and only if resolve(i1 ) =
resolve(i2 ). Two identifiers i1 and i2 are bound-identifier=? if and only if
resolve(subst(i1 , i2 , s)) = s for a fresh symbol s.
Dybvig is among the editors of R6RS and that paper is cited in the R6RS
(reference [9] in r6rs.pdf).
If you look at the definition of the resolve and subst functions, the
definition of bound-identifier=? says that i1 and i2 are bound-identifier=?
iff they have the same marks *and they resolve to the same binding*.
Modulo possible shenanigans around things like #:rename for modules,
that sounds like it's equivalent to being "strict R6RS" bound-identifier=?
*and free-identifier=?*.
To me, that behavior is more intuitive.
Then, should this be considered a bug in the R6RS spec? Or a bug in the
paper?
(And is there a better place to discuss these things than this mailing list?)
Jean
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next reply other threads:[~2023-07-21 0:20 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-21 0:20 Jean Abou Samra [this message]
2023-07-21 9:08 ` Inconsistencies with free-identifier=? and bound-identifier=? Jean Abou Samra
2023-07-27 18:28 ` Timothy Sample
2023-07-27 22:10 ` Timothy Sample
2023-07-28 10:08 ` Jean Abou Samra
2023-07-28 10:09 ` Jean Abou Samra
2023-07-29 4:37 ` Timothy Sample
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=008f724d79b871ce1d68121402bbcbcdd25ec270.camel@abou-samra.fr \
--to=jean@abou-samra.fr \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).