Summary
Symbol lookup fails in modules in conjunction with renaming macros
Metadata
- Id: 71bceb9463c475f3d25a83dbb6d20e4cbb8a68fb
- Trac id: 444
- Type: defect
- Reporter: syn
- Owner: felix
- Cc:
- Status: closed
- Component: expander
- Estimated difficulty:
- Resolution: fixed
- Priority: major
- Milestone: 4.9.0
- Version: 4.6.x
- Changetime: 2012-09-24 21:47:48 UTC
- Created: 2010-12-08 21:59:51 UTC
- Keywords:
Attachments
- 71bceb9463c475f3d25a83dbb6d20e4cbb8a68fb/attachments/ir-fix.patch
- 71bceb9463c475f3d25a83dbb6d20e4cbb8a68fb/attachments/nested-syntax.patch
Description
I stumbled upon a problem when trying to generate a
re-rename the injected {{{void}}} symbol correctly. This resulted in
it referring to {{{#%void}}} aka {{{##sys#void}}}. The following
reproduces the problem:
{{{
(import foreign)
(foreign-declare "void foo() { printf(\"hi\\n\"); }")
(module foo
(bar)
(import chicken scheme foreign)
(define-syntax bar
(ir-macro-transformer
(lambda (x i c)
`((foreign-lambda ,(i 'void) ,(i 'foo)))))))
(import foo)
(bar)
Note that it does work outside the module, though. So does the ER version:
(er-macro-transformer
(lambda (x r c)
`((,(r 'foreign-lambda) void foo))))
This might suggest that the problem lies within the IR macro implementation but sjamaan is almost certain that the symbol lookup must be going wrong somewhere and that it only fails in the IR version because there's more renaming taking place. Thinking about it some more he concluded that there is a chance that it's a problem in the IR implementation anyway. This ticket mainly serves as a reminder for him to think about that some more. However, other interested parties are welcome to contribute their thoughts as well, of course!
P.S.: Mr Z. found out that (import (except chicken void)) helps to make the IR version. This might be a work-around for people experiencing the same issue and looking for a work-around.
Changes and comments
[2010-12-08 22:06:56 UTC] sjamaan wrote:
After some investigation, I found a difference in behaviour between Chicken and other Schemes:
(define else #f) (cond (else 1)) => 1
In other Schemes (s48, Mzscheme and Guile - but not Gauche or Chibi) it returns unspecified.
[2010-12-08 22:07:35 UTC] sjamaan wrote:
Gambit behaves as Chicken, Gauche and Chibi
[2010-12-08 22:17:10 UTC] sjamaan wrote:
eh, the relevance of this comment about "else" is that a COND macro written as IR macro would behave the same as s48 and mzscheme in all cases. One written as ER macro would behave as Chicken (since chicken's cond IS written as an er macro)
[2010-12-08 22:24:55 UTC] syn wrote:
Bigloo and MIT Scheme also behave as Chicken. Ikarus and Ypsilon don't allow definition of else. Racket behaves as s48 and friends.
[2010-12-08 22:31:56 UTC] syn wrote:
And, for the record, Mosh behaves like s48, too :-)
[2010-12-08 22:53:29 UTC] sjamaan wrote:
Correction: According to Alex, chibi only behaves like that at the toplevel because this redefines the "else" that "cond" matches against. It returns undefined when this is inside a module.
[2010-12-08 22:59:56 UTC] sjamaan wrote:
This very issue (what to do with "free" identifiers) is under consideration for WG1 of R7RS:
http://trac.sacrideo.us/wg/ticket/83
[2010-12-09 10:35:17 UTC] sjamaan wrote:
Here's a fun one:
(define (foo) (define else #f) (cond (else 1))) (foo) => 1 (define (foo) (letrec ((else #f)) (cond (else 1)))) (foo) => ; #<unspecified>
According to R5RS, this should behave the same http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-8.html#%_sec_5.2.2
[2010-12-09 12:52:26 UTC] syn changed description
[2010-12-09 12:52:26 UTC] syn wrote:
Oops, the original problem reproduction code contained the (except chicken void) work-around which lead to it not reproducing the problem anymore. I fixed this now!
[2010-12-09 15:50:53 UTC] sjamaan attached ir-fix.patch (description=Fix for IR renaming bug)
[2010-12-09 15:53:30 UTC] sjamaan wrote:
Here's a fix plus test. I'm still not 100% sure whether this qualifies as a bug, though.
I tried to add a second list "irenv" which was the inverse of "renv", but for some reason as soon as I assigned something to that list it caused a segfault I could not explain, so instead I just write a reverse-lookup procedure. May want to look at that.
[2010-12-09 15:57:07 UTC] sjamaan changed status from new to assigned
[2010-12-09 15:57:07 UTC] sjamaan set owner to felix
[2010-12-09 20:42:48 UTC] sjamaan wrote:
Here's a testcase that also fails with the other macro system, plus a patch that fixes it. It causes strip-syntax to strip syntax off of primitives too. This is neccessary since macro syntax environments inside modules always contain all imported bindings, which includes (void . #%void). This is always rewritten for syntax-rules and stripping syntax should restore this back to the original symbol "void".
Applying this patch also fixes the testcase in the other patch. I think both patches should be applied, probably. I can't currently think of a case which would break but I'm sure with deeply nested macros the earlier patch provides some added robustness.
[2010-12-09 20:43:37 UTC] sjamaan attached nested-syntax.patch (description=Fix for nested ER macros/syntax-rules as well as IR macros)
[2010-12-11 13:53:47 UTC] felix changed status from assigned to closed
[2010-12-11 13:53:47 UTC] felix set resolution to fixed
[2010-12-11 13:53:47 UTC] felix wrote:
patch is applied, thanks.
[2011-06-01 09:00:41 UTC] felix changed milestone from 4.7.0 to 4.8.0
[2011-06-01 09:00:41 UTC] felix wrote:
Milestone 4.7.0 deleted
[2012-09-24 21:47:48 UTC] felix changed milestone from 4.8.0 to 4.9.0
[2012-09-24 21:47:48 UTC] felix wrote:
Milestone 4.8.0 deleted