[r6rs-discuss] [Formal] Violation of lexical scoping
I believe I have solved the problems with lexical scoping I pointed out in the
various formal comments. It only requires an adjustment of the detection
algorithm in the first paragraph of page 28. It does not otherwise require any
change to the expansion algorithm.
I have implemented and tested the modified algorithm (which is in fact simpler).
It does not break any of my existing correct examples, but throws errors for all
cases where the current algorithm would assign lexically incorrect semantics.
Modified specification:
-----------------------
It is a syntax violation if an identifier already referenced
during expansion of a declaration, definition or expression
is redefined by the same or a later definition in the
same body. To detect this error, the expander records each
denotation of an identifier requested during expansion
of the body (denotations are calculated for identifier uses in
expanded code, for comparisons using free-identifier=? by
user and primitive macros, and for the expander's internal
dispatching mechanism). Before an identifier is bound, its
existing denotation is compared against already referenced
denotations in the current scope to determine if it has already
been used. If so, a syntax violation is thrown.
Here is a big bunch of examples where an error must be thrown to avoid
lexical-scope-violating semantics. The above algorithm treats them all
correctly:
;; (let ()
;; (define-syntax foo (lambda (e) (+ 1 2)))
;; (define + 2)
;; (foo)) ; Syntax violation: Redefinition of identifier + that has
; already been used during expansion
;; This should give no error:
(let ()
(define-syntax foo (lambda (e) (let ((+ -)) (+ 1 2))))
(define + 2)
(foo)) ;==> -1
;;(let ((bar 1))
;; (bar x)
;; (define-syntax bar
;; (syntax-rules ()
;; ((bar x) (define x 1))))
;; x) ; Syntax violation: Redefinition of identifier bar that has
; already been used during expansion
;; This must give an error:
;; (script
;; (import r6rs)
;; (bar x)
;; (define-syntax bar
;; (syntax-rules ()
;; ((bar x) (define x 1))))
;; x) ; Syntax violation: Redefinition of identifier bar that
; has already been used during expansion
;; (let ()
;; (declare safe)
;; (define declare 1)) ; Syntax violation: Redefinition of identifier
; declare that has already been used during expansion
;;(let ()
;; (declare safe)
;; (define safe 1)) ; Syntax violation: Redefinition of identifier safe
; that has already been used during expansion
;;(let ((x #f))
;; (let-syntax ((foo (syntax-rules (x)
;; ((_ x y) (define y 'outer))
;; ((_ _ y) (define y 'inner)))))
;; (let ()
;; (foo x p)
;; (define x #f)
;; p))) ; Syntax violation: Redefinition of identifier x
; that has already been used during expansion
;; The following is valid.
(let ((x #f))
(let-syntax ((foo (syntax-rules (x)
((_ x y) (define y 'outer))
((_ _ y) (define y 'inner)))))
(let ()
(define x #f)
(foo x p)
p))) ;==> inner
;;(let ((x #f))
;; (let-syntax ((foo (syntax-rules (x)
;; ((_ x y) (define y 'outer))
;; ((_ _ y) 1))))
;; (let ()
;; (foo x p)
;; (define x #f)
;; p))) ; Syntax violation: Redefinition of identifier x
; that has already been used during expansion
;;(let ((bar 1))
;; (bar x)
;; (define-syntax bar
;; (syntax-rules ()
;; ((bar x) (define x 1))))
;; x) ; Syntax violation: Redefinition of identifier bar
; that has already been used during expansion
;;(let-syntax ([def0 (syntax-rules ()
;; [(_ x) (define x 0)])])
;; (let ()
;; (def0 z)
;; (define def0 '(def 0))
;; (list z def0))) ; Syntax violation: Redefinition of identifier def0
; that has already been used during expansion
;;(let ()
;; (define define 17)
;; define) ; Syntax violation: Redefinition of identifier
; define that has already been used during expansion
Andre
Received on Tue Oct 24 2006 - 17:39:35 UTC
This archive was generated by hypermail 2.3.0
: Wed Oct 23 2024 - 09:15:01 UTC