From posting-system@google.com Sun Aug 10 23:51:25 2003 Date: Sun, 10 Aug 2003 15:51:18 -0700 From: oleg-at-pobox.com Newsgroups: comp.lang.scheme Subject: Re: define-top-level-value References: Message-ID: <7eb8ac3e.0308101451.3ac98c7b@posting.google.com> Status: OR Matthias Radestock wrote in message news:... > (define-syntax define-top-level-value > (syntax-rules () > ((_ name value) > ((eval '(begin (define name #f) > (lambda (val) (set! name val))) > (interaction-environment)) > value)))) > "Unlike the solution Jim posted, which is PLT-specific, the above will > work in any R5RS-compliant Scheme that support interaction-environment > and EVALuation of definitions. There are many Schemes that do." I have reservations about that statement. Support for interaction-environment and EVALuation of definitions does not imply that the above technique will work. The code above may have different results even on the same Scheme system -- depending on whether the code is compiled or interpreted. R5RS says: [[optional procedure]] (interaction-environment) This procedure returns a specifier for the environment that contains implementation-defined bindings, typically a superset of those listed in the report. The intent is that this procedure will return the environment in which the implementation would evaluate expressions dynamically typed by the user. Nothing in that passage says that the environment denoted by the (interaction-environment) includes all or any of the bindings from the user code. R5RS leaves it to an implementation to decide which bindings to include in the interaction environment. Let us consider the following Bigloo code (please disregard the (module) expression. It is needed for compilation) /tmp> cat b.scm (module aaa) (define x 1) (display (eval 'x (interaction-environment))) (newline) /tmp> bigloo -i b.scm # interpretation 1 /tmp> bigloo b.scm # compile the code b.scm: /tmp> ./a.out *** ERROR:bigloo:eval: Unbound variable -- x Here's a more insidious example: /tmp> cat b.scm (module aaa) (define x 1) (eval '(define x 2) (interaction-environment)) (display x) (newline) (display (eval 'x (interaction-environment))) (newline) /tmp> bigloo -i b.scm File "b.scm", line 3, character 34: #(eval '(define x 2) (interaction-environment)) # ^ # *** WARNING:bigloo:eval redefinition of variable -- x 2 2 Now, Bigloo explicitly warns of re-definition. Let us compile the same code /tmp> bigloo b.scm b.scm: /tmp> ./a.out 1 2 There is no redefinition here. As you see, the binding of x in the main program and the binding of x in the interaction environment are completely independent -- in full compliance with R5RS. In Bigloo, if we want to share a binding between compiled and interpreted code, we must specifically describe that binding in the module statement. Furthermore, if we want to mutate that binding in the interpreted code, we must mention that fact in the module statement as well (so the compiler will arrange for the appropriate boxing of the binding). In short, the only sure way of exchanging data in and out of 'eval'-uated code is to use explicit boxing and evaluate only closed expressions, as has been described in http://pobox.com/~oleg/ftp/Scheme/eval-in-env.txt