Fri 25 Sep 2009 03:38:45 AM UTC, comment #11:
I've just done a build and tested both the original bug reported by Brian Mastenbrook and the simpler one that Taylor reported in comment #3. Both seem to be reporting the correct answers (errors) now. I've attached a transcript. Taylor, are those answers what you expected now? If so, please go ahead and close the bug.
Thanks!
(file #18770)
|
Thu 24 Sep 2009 05:24:17 PM UTC, comment #10:
I think this should be fixed now, at least the issue that Arthur originally reported. I don't know what Chris meant about synthetic identifiers being completely broken.
|
Thu 17 Sep 2009 08:34:15 PM UTC, comment #9:
Edit: `Note that this affects any macros, not just SYNTAX-RULES macros, that [introduce] DEFINE forms with synthetic identifiers...'
|
Thu 17 Sep 2009 08:32:40 PM UTC, comment #8:
Yes, I'm beginning to see now.
The reason this is relevant to syntax-rules is that it's the only user of synthetic identifiers. But the treatment of synthetic identifiers is completely broken (and not just in syntax-output).
Please hold off then, until I push my changes.
|
Thu 17 Sep 2009 08:29:16 PM UTC, comment #7:
Note that this affects any macros, not just SYNTAX-RULES macros, that DEFINE forms with synthetic identifiers. After all, the purpose of binding synthetic identifiers is to make bindings that are private to the macros that introduced them. The problem is just more serious for SYNTAX-RULES macros, because procedural macros -- ER, SC, &c. -- can generated uninterned symbols, while SYNTAX-RULES macros cannot.
I don't think that syntax-rules.scm is relevant, by the way: I think the problem has to be solved in syntax-output.scm, where the macro engine reduces the generated names in the output as much as it can -- and where in the process, the macro engine turns macro-generated synthetic identifiers in definitions into symbols.
|
Thu 17 Sep 2009 08:02:05 PM UTC, comment #6:
Sorry, I should have realized we were talking only about syntax-rules and not other macro mechanisms.
I've made only slight changes to syntax-rules.scm and don't plan to do more. So feel free to hack in there; I'll merge if needed.
|
Thu 17 Sep 2009 07:53:33 PM UTC, comment #5:
Nobody writes SYNTAX-RULES macros that introduce top-level bindings visible to their users with names that the users did not supply in the macro's input. Some SYNTAX-RULES macros, however, need to introduce private top-level bindings. See, for instance, <http://mumble.net/~campbell/darcs/scheme-cml/s48-pessimistic-record.scm>: %CONSTRUCTOR and OBJECT.LOCK are private to each instance of the DEFINE-LOCKED-RECORD-TYPE macro. The workaround for MIT Scheme is currently <http://mumble.net/~campbell/darcs/scheme-cml/mit-mutex-syntax.scm>.
There is also a related, but independent, problem with these macros, by the way, which is that the obvious definition, in s48-pessimistic-record.scm, doesn't let users use DEFINE-LOCKED-RECORD-TYPE with fields named LOCK, in some Scheme systems. (Scheme48 allows this, but MIT Scheme wouldn't.) This is because DEFINE-RECORD-TYPE puts the fields into a QUOTE, rather than a SYNTAX-QUOTE, and thereby strips them of distinguishing hygiene information. This is a different problem, though, and independent of the issue at hand.
|
Thu 17 Sep 2009 07:37:53 PM UTC, comment #4:
Please don't do any work on this at the moment. I am working on the core syntax code and will check in my changes in the next few days. I'm mainly refactoring and simplifying, and the changes have been pretty pervasive, so merging will be difficult.
Also, I'd like to better understand what you mean to do. Will this affect existing macros that introduce visible top-level bindings? Or will it only affect macros that are introducing private top-level bindings?
|
Thu 17 Sep 2009 04:40:30 PM UTC, comment #3:
Correction: Hygiene is partially broken. I partially fixed this problem four years ago, and, because the partial fix worked for my purposes at the time, I never finished the partial fix.
This is a problem because macros need to be able to introduce top-level bindings visible to no one but the macro, just like they need to introduce local bindings visible to no one but the macro, whether with DEFINE or LET -- and, more importantly, they need to be able to do this in such a way that multiple invocations of the macro don't clobber one another. My partial fix made this last property hold, which was why I didn't pursue it further (I might not have even noticed that it was only a partial fix at the time).
Completing the partial fix requires changing the logic that tries to prettify the output of the macro expander by limiting the number of generated names -- it needs to avoid unmapping names in top-level bindings introduced by macros. Doing this nicely, and avoiding unmapping only those names, requires extra infrastructure to convey the information of which names to avoid unmapping, which is not obvious in the COMPUTE-SUBSTITUTION code of syntax-output.scm. Short of that, a provisional fix is to comment out the loop in COMPUTE-SUBSTITUTION/BINDER -- which rather defeats the purpose of the whole substitution computation, but which is simple to do.
There is, by the way, another bug in all that code: lone definitions, outside open blocks, are handled incorrectly. Uninterned symbols shouldn't occur in the output of the syntaxer, but:
(define-syntax a
(syntax-rules ()
((_) (define b 1))))
;Value: a
(a)
;Value 12: #[uninterned-symbol 12 b]
|
Fri 11 Sep 2009 07:05:12 PM UTC, comment #2:
| I don't get it: that's the behavior I'd expect. What's wrong with this?
Okay, that makes me feel better. It looks right to me, too, but I'm such a novice at `syntax-rules' that I thought I must have misunderstood how it's supposed to work. I shouldn't have filed this bug until I understood better.
Brian later explained his claim by saying:
| `b' is an introduced binding. It should not be visible outside of the
output of the macro transformer.
But it is not a binding introduced by the macro transformer, so I disagree with his conclusion.
I'm going to mark this bug Invalid and Closed.
Sorry for the false alarm.
|
Fri 11 Sep 2009 06:53:21 PM UTC, comment #1:
I don't get it: that's the behavior I'd expect. What's wrong with this?
|
Fri 11 Sep 2009 05:46:46 PM UTC, original submission:
From Brian Mastenbrook's message on <r6rs-discuss>
(<http://lists.r6rs.org/pipermail/r6rs-discuss/2009-September/005152.html>):
MIT Scheme's implementation of hygiene is broken:
1 ]=> (define-syntax a
(syntax-rules ()
((_)
(begin
(define-syntax b
(syntax-rules ()
((_) 1)))
(define-syntax c
(syntax-rules ()
((_) 2)))))))
;Value: a
1 ]=> (a)
;Unspecified return value
1 ]=> (b)
;Value: 1
|