This page is part of the web mail archives of SRFI 39 from before July 7th, 2015. The new archives for SRFI 39 contain all messages, not just those from before July 7th, 2015.
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