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