On Tuesday, Sep 2, 2003, at 20:53 Europe/Brussels, Denys Duchier wrote:
> I like the idea of devising a cleaner set of primitives, but you need
> to make it clearer in your argumentation that currently ByNeed bundles
> two things: the "on demand" aspect and the "safe abstraction" aspect
> (aka futures). The non-confluence comes entirely from the latter and
> its behaviour with respect to unification.
Thanks for providing this clarification.
> Then what you are doing becomes clearer: you unbundle and make
> available the pure "on demand" aspect. This allows you to rewrite the
> example program: on the one hand your abstractions are now unsafe, but
> on the other hand confluence is preserved.
Indeed. And the combination of both can still be programmed, as we
showed in the example.
>
> I'd like to hear more about the implementation. I imagine that:
>
> proc {ByNeed P X}
> thread {WaitNeed X} {P X} end
> end
>
> is the specification and not the actual implementation, or is it?
We did implement the WaitNeed as a primitive, not (yet) the ByNeed.
I think it is good to provide the WaitNeed primitive to the user as
such for the following reasons.
1. The thread..end statement is no longer inside this primitive. That
allows for more control on the creation of threads, when creating lazy
lists (or other lazy structures), for instance to avoid the needless
overhead of creating and garbage collecting a thread for every element
to be computed, in case the elements are (to be) computed sequentially.
proc {Lazy F ?L} % F takes an integer and returns an integer
proc {NextNeeded N Xs}
{WaitNeed Xs} Xs={F N} | {NextNeeded N+1}
end
in
thread {NextNeeded 1 L} end
end
We did a crude and simple performance test, and for long lists (> 1 M)
we measured up to 66% increase in performance, mostly due to avoiding
garbage collection.
2. It also decouples the fact of synchronizing on X becoming needed,
from what happens when X becomes needed. The latter no longer has to be
a one-argument procedure taking X as a parameter. It is now straight
forward to create other forms of ByNeed from the WaitNeed primitive,
for example:
proc{ByNeedSend Obj Msg X}
thread {WaitNeed X} {Obj Msg(X)} end
end
We claim that the WaitNeed primitive really makes by-need
synchronization complementary to dataflow synchronization.
thanks for your reaction,
Fred.
-
Please send submissions to hackers@mozart-oz.org
and administriva mail to hackers-request@mozart-oz.org.
The Mozart Oz web site is at http://www.mozart-oz.org/.