Short description of the bug;
;; Doesn't matter whatThe first one is obviously wrong, it broke the definition of internal define. The second one is releated to comple time environment lookup. The
equal?return. ;; Bug 1 (let () (define-record-type (pare kons pare?) (fields (mutable x kar set-kar!) (immutable y kdr))) (define a (kons (vector 1 2 3) '(a b c))) (define b (kons (vector 1 2 3) '(a b c))) (equal? a b)) kons ;; -> #<closure kons> ;; this should be &assertion of unbound variable ;; Bug 2 (let ((c #t)) (define-record-type (pare kons pare?) (fields (mutable x kar set-kar!) (immutable y kdr))) (define a (kons (vector 1 2 3) '(a b c))) (define b (kons (vector 1 2 3) '(a b c))) (equal? a b)) ;; -> &assertion
konsis defined by
define-record-typeand it must be the same identifier as the one in internal define. But it's not. That's because macro expander re-name it to different identifer.
The simplest solution I have tried was to wrap all given expression first then expand macros. It's simple it worked (mostly) but broke constant literals such as quoted lists or vectors. The problem was not only it but also broke some other codes (mostly related with
er-macro-transformerused for generating bootstap code and R7RS). So I've decided not to do this (even though I feel like it's the easier way to do it).
The second solution is modifying the environment lookup process. An identifier can hold some environment without any restriction on current branch and if I can find a better way to look up proper variable from compile time environment, it can be resolved. The problem is I don't know how...
Consider the case of Bug 1. The
konsand environment have following frames;
;; kons identifier's frame ((0)) ;; when 'a' is being compiled ((0 (kons#user . #(lvar ...)) ...) ;; kons#user is an identifier (0)) ;; <-- the same environment as the kons identifierSo when a is being compiled, compiler can see the same environment at the very top of the frame chain. But how can we assume kons#user and kons in internal define are the same variables? If the root of the frame are the same, would we be able to assume? Or when it's expanded to internal define, should it be stripped to mere symbol?
Hmm..., I need to think ...