let-fluid problem shivers@xxxxxx (14 Nov 1999 04:07 UTC)
Re: let-fluid problem Per Bothner (16 Nov 1999 07:13 UTC)
Re: let-fluid problem shivers@xxxxxx (19 Nov 1999 22:31 UTC)
Re: let-fluid problem Per Bothner (20 Nov 1999 06:26 UTC)
Re: let-fluid problem Lars Thomas Hansen (16 Nov 1999 17:13 UTC)
Re: let-fluid problem Per Bothner (16 Nov 1999 17:24 UTC)
Re: let-fluid problem Lars Thomas Hansen (16 Nov 1999 18:57 UTC)

Re: let-fluid problem Per Bothner 16 Nov 1999 07:13 UTC

xxxxxx@ai.mit.edu writes:

> I would like to argue against any DYNAMIC-WIND + SET! sort of
> "fluid variable" system. The problem is threads. If you have a
> thread model, then any thread switch involves unwinding up the
> stack to the common ancestor continuation, then winding down into
> the activated continuation. This seems unacceptably expensive; thread
> switch should be a low-overhead operation.

(Let us not confuse specification with implementation.  When I
was (briefly) involved with C++ standardization, I learned the
"as-if rule."  This refers to the fact that a feature may be
defined "as if" it were implemented in a particular way, but
an implementation is free to use a different implementation as long
as long as no well-defined program can tell the difference.)

A more fundamental problem with the fluid-let specification is that it
does not support a thread model that may have true parallel threads.
When the topic of "thread local variables" came up in the Guile
mailing list (see http://sourceware.cygnus.com/ml/guile/1999-03/)
I proposed a "deep binding" model of variable access
(see http://sourceware.cygnus.com/ml/guile/1999-03/msg00023.html):

  Each thread has an association list of fluid bindings.
  When fluid-let is evaluated, it conses up a new association to the
  front of the list.  That becomes the current fluid binding
  association list while the body of the fluid-let is evaluated.
  The old list is restored when the fluid-let finishes.
  (This can be implemented with the appropriate dynamic-wind.)
  When a new thread is created, it initializes its fluid
  binding list with the *current* list from the parent thread.
  Thus all bindings are initially shared.  When a non-local
  variable is evaluated, the evaluator searches the current thread's
  fluid binding list, and finds the first binding for the given name.
  If none, is found, the global binding is returned.
  When a set! is evaluated, it also searches the fluid bindigs list
  of the current thread, and modifies the first association whose
  name matches.  If there is none, the global binding is modified.

This is of course only the semantic model;  an actual implementation
may use caching or other thread-local storage.

This model is actually very general;  it allows rather fine-grained
control over which variables are shared between which threads,
but using a very simple but general mechanism.  (As such I think
it first very much in the spirit of Scheme.)

This model of thread-local storage has been implemented in Kawa.
	--Per Bothner
xxxxxx@bothner.com   http://www.bothner.com/~per/