mit-scheme-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MIT-Scheme-devel] bug in shadowing caches


From: Taylor R Campbell
Subject: Re: [MIT-Scheme-devel] bug in shadowing caches
Date: Fri, 20 Aug 2010 17:00:15 +0000
User-agent: IMAIL/1.21; Edwin/3.116; MIT-Scheme/9.0.1

   Date: Fri, 20 Aug 2010 09:10:31 -0700
   From: Joe Marshall <address@hidden>

   I think the behavior you are seeing is the expected one.

If that is the case, then the compiler and the interpreter disagree on
the semantics of the language:

   ;;; /tmp/lose.scm

   (define (reference-barrier x)
     (identity-procedure x))

   ;;; repl

   (let ((environment (extend-top-level-environment (->environment '()))))
     (load "/tmp/lose.bin" environment)
     ((eval 'reference-barrier environment) 0))
   ;Loading "/tmp/lose.bin"... done
   ;Value: 0

   (let ((environment (extend-top-level-environment (->environment '()))))
     (load "/tmp/lose.com" environment)
     ((eval 'reference-barrier environment) 0))
   ;Loading "/tmp/lose.com"... done
   ;Quit!

I claim that the interpreter's semantics is the correct semantics.
Suppose, for example, that we first separate lose.scm into two forms,
a definition form and an assignment form:

   ;;; lose0.scm

   (define reference-barrier)
   (set! reference-barrier (lambda (x) (identity-procedure x)))

The compiler and interpreter disagree on the semantics as before.
Now suppose we split lose.scm into two files:

   ;;; a.scm

   (define reference-barrier)

   ;;; b.scm

   (set! reference-barrier (lambda (x) (identity-procedure x)))

In this case, the compiler and interpreter agree -- both behaving like
the interpreter on the single lose0 file:

   (let ((environment (extend-top-level-environment (->environment '()))))
     (load "/tmp/a.bin" environment)
     (load "/tmp/b.bin" environment)
     ((eval 'reference-barrier environment) 0))
   ;Loading "/tmp/a.bin"... done
   ;Loading "/tmp/b.bin"... done
   ;Value: 0

   (let ((environment (extend-top-level-environment (->environment '()))))
     (load "/tmp/a.com" environment)
     (load "/tmp/b.com" environment)
     ((eval 'reference-barrier environment) 0))
   ;Loading "/tmp/a.com"... done
   ;Loading "/tmp/b.com"... done
   ;Value: 0

The problem is that there are two distinct bindings, i.e. associations
between name and variable, but only a single variable between them,
and update_cache_references updates all references to the variable,
irrespective of what binding they went through (i.e. what name was
used to refer to the variable).  However, after the update, the name
IDENTITY-PROCEDURE still refers to the variable created in global.scm
-- not to the variable created in the child environment, to which
REFERENCE-BARRIER has been bound.  So future references to IDENTITY-
PROCEDURE will not be updated like prior references have been.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]