Gargage collected top-level bindings?
Per Bothner
per@bothner.com
Sun May 8 22:23:00 GMT 2005
Steve Yegge wrote:
> Java and Scheme programmers alike seem to expect top-level bindings to
> act like Java instance variables, as if the file contents were contained
> within a single Java class.
I don't think it's that simple. The Scheme top-level environment is a
*dynamic* environment. Consider the opposite situation: when a module
references a variable which is *not* statically visible. Also, if a
module does define a binding, when is it visible to other modules?
Also consider fluid bindings. They are inherently dynamic. And once
you're using dynamic lookup, things are automatically thread-specific.
> Put another way, people expect them to be lexically scoped to that file
> (or perhaps module).
People's expectations are not consistent. They expect their code to
"work" but they usually can't clearly specify what they want, or see
the implications. The situation is complicated by the lack of either
threads or modules in R5RS, so we have to work out what makes most
sense.
> This is the way it has worked historically in the
> absence of multiple threads: you can read and write the bindings from
> any function defined in the file, e.g.:
>
> (define my-toplevel-var 10)
>
> (define (my-function)
> (set! my-toplevel-var
> (+ 1 my-toplevel-var)))
>
> Kawa recently changed so that the my-toplevel-var binding is not
> accessible to another thread entering my-function. That's confusing
> and unintuitive.
It is accessible if the other thread inherits from the initial thread.
> And finally, as I mentioned before, it's not the way it works in
> other languages. So even if Kawa's current semantics for globals
> are the "right thing" from some internal design perspective, it will
> continue to be a source of confusion, bugs, and mailing list traffic
> as long as it remains that way.
So what is your suggestion? Note the solution needs to specify how
fluid binds works. Another complication is that (load ...) of a
compiled module should behave similarly to loading a source file,
and the latter is specified by R5RS.
> Sharing top-level bindings among threads will of course necessitate
> user synchronization of those variables. But Java programmers are
> used to that, and java.util.concurrent.atomic provides some nice
> wrappers to simplify the synchronization.
The issue isn't just synchronization, but what bindings are shared
between what threads and what environments?
One possible solution is that initializing a top-level binding sets the
default binding rather than the current thread's. But that means that
initialization and assignment behave very differently, which could
leadto other weird behavior. We could also make it easier to share
environments.
I agree the current semantics are awkward. But it's not easy figuring
out the Right Thing.
--
--Per Bothner
per@bothner.com http://per.bothner.com/
More information about the Kawa
mailing list