Re: Some comments felix 04 Jan 2003 15:47 UTC

Marc Feeley wrote:
>>
>>This is unfortunate, since this SRFI really moves all that "legacy"
>>code into non-specifiedness...
>
>
> Since SRFI 39 did not exist when the legacy code was written the code
> never conformed to it.  So SRFI 39 does not "move" the code into
> non-specifiedness.  The other choice (of having "make-parameter"
> create the mutable parameters as specified in SRFI 39) is even less
> appealing because in that case PLT legacy code would no longer work if
> PLT adopted that semantics.

That is exactly the reason why I think having fully thread-local
parameters is the more practical solution. The "legacy" code I talk of
is the (perhaps not unconsiderable) amount of code written that uses
parameters that do not share their value among different threads
(as in PLT).

>
>>I think parameters (as used in Chez, PLT or (say) Chicken) are
>>(IMHO) well understood and heavily used.
>
>
> For these systems and Gambit-C, "make-mutable-parameter" and
> "make-parameter" can be defined as the native "make-parameter" when
> multithreading is not used.  The semantic differences only matter with
> PLT when threads are being used and the parameters are mutated (indeed
> only PLT and Chicken implement threads and the Chicken manual does not
> explain the interaction between parameters and threads).

[It does, albeit not explicitly enough (see the SRFI-18 section).
I will fix this.]

> I view SRFI
> 39's main contribution as a specification of how mutation of
> parameters should work in the presence of threads.

Absolutely. But I think one should be more pragmatic here and
use parameters as user-defined *fully* thread-local storage,
dynamically scoped.

> No "copy-on-write" is not a valid implementation.  The reason is that
> the "swapping" semantics requires the child thread to have an
> independent copy of the parent's thread.  So the child must get a
> snapshot of the parent's dynamic environment which will make the
> child's mutations invisible to the parent ***AND*** the parent's
> mutations invisible to the child.  The copy-on-write approach you
> suggest only makes the child's mutations invisible to the parent.

That's not true. I'm probably expressing myself not clearly enough.
`make-parameter' creates a parameter in a global environment (not attached)
to any thread. Thread-creation copies the parent's parameter-env,
*but* this env will be empty if the parent has not yet changed it's
parameter-env (i.e. it is equivalent to the global env).

I'm pretty sure that it works. I would be delighted to see some sample
code that demonstrates the problem.

>
> When I say "clean" I don't mean it so subjectively.  A strong argument
> can be made that the semantics I propose in SRFI 39 for dynamic
> binding are closer to the lexical binding semantics.  What does this
> mean?  Well, if you look at how environments are manipulated in the
> denotational semantics (section 7.2 of R5RS) you will see that there
> are only two operations on environments "lookup" and "extends".
> "lookup" returns the location in the store that is bound to an
> identifier.  The value associated to a location in the store is
> obtained with "hold" and "assign" changes the value associated with
> the location.  Dynamic binding as I propose it uses exactly the same
> operations (with the minor point that the domain of "lookup" and
> "extends" must be changed to accept parameter objects).  In addition
> to the lexical environment, the semantic functions also need an extra
> environment: the dynamic environment.  The dynamic binding semantics
> is simply obtained by having procedure call pass this dynamic
> environment to the called procedure (and this is the only thing that
> distinguished it from lexical binding).  Similarly (but obviously
> outside the scope of R5RS), the creation of a new thread would capture
> the dynamic environment of the parent thread.  That's it.  There is no
> need for an additional semantic operation for copying dynamic
> environments (which is non trivial because it must allocate store).
> Dynamic binding is a simple and natural extension of the R5RS

Perfectly valid, but to repeat: I see parameters as a simple and effective device
for having thread-local storage, nothing more.

I find the reasons you give insufficient for changing a well-established
construct like parameters. The performance argument is weak, incompatibility
to existing systems will make adoption of this SRFI harder and compatibility
to non-released software is unimportant. Additionally it puts unneccessary burden
on implementors and confuses users of implementations that have parameters and threads.

(BTW, there is a simple way out of this dilemma: use different
names - `make-dynamic' and `let-dynamic' come to mind, for example...)

cheers,
felix