This is the mail archive of the guile@cygnus.com mailing list for the guile project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
> Right. Bindings created with fluid-let are thread local, Not quite, at least in my version: Bindings (not just values) are inherited by child threads. It is possible the disagreement may be because I have not explain fluid-let well enough, or you think it does something different than I intend. The intended semantics (but not of course the implementation) is as follows: 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 search 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 bindings is modified. > so you have to use a different binding form to change the value of > a truly global variable You use set! for both global and thread-local bindings. > A perhaps better question is, do parameters provide a useful and well > designed abstraction that fluid-let does not provide? You didn't > expend the least bit of effort trying to answer that question. First, I hope we can agree that parameterizations are lower-level mechanism. It is more general. It might be more efficient, since you don't have to support thread-local bindings in regular dyanmic binding lookup. It does allow finer-grained control. However, it is a very non-functional side-effect-using feature. Of course bindings and assignments are always that, but I think parameterizations are even more so. I think on the other hand that fluid-let is much more "Lispy" - it is just old-fashioned dynamic scoping extended to work for threads. MzScheme provides various features where parameterizations are used just like fluid-let (i.e. evaluate some expression or thread with a modified dynmaic scope). This seems to confirm to me that fluid-let would provide the essential core that covers 99% of the uses of parameterizations. > I'll try to formulate an example using *print-circle*. Imagine a > program with two threads, operating on a circular data structure. > Thread a determines that there is a chance that the data structure is > circular, so it tries to prepare the world like this: > With parameters, this code would be: > (parameterize ((*print-circle* #t)) > (do-stuff-with-obj) > (put-object-onto-b-inq obj) > (wait-for-b-to-finish-processing obj)) I'm missing the essential difference here. You left out how you set up a and b to use the same parameterization. With fluid-let, it is easy. (fluid-let ((*print-circle*)) (future ;; thread a (do-stuff-with-obj) (set! *print-circle* #t) (put-object-onto-b-inq obj) (wait-for-b-to-finish-processing obj)) (future ;; thread b ...)) I'm unclear on exactly what sharing semantics you want (when *print-circle* gets set and reset), but I'm fairly confident I can express it using fluid-let. > I'm not completely happy with the example I formulated, but I still > think that this feature is very useful. It unifies the concepts of > binding thread-local and truly global variables, which makes the code > that uses these types of variables simpler. Good points. That's what I like about fluid-let. --Per Bothner Cygnus Solutions bothner@cygnus.com http://www.cygnus.com/~bothner