Hi Andreas,
[I don't reply to the users list but on the hackers list instead. This
discussion is and should remain internal.]
Don't be scared of the changes with the new ByNeed. We haven't broken
everything with our proposal. The idea was rather to factor out the
orthogonal concepts that were mixed up with futures. Those concepts
are: read-only views of variables, by-need synchronization, and failed
values (called failed 'futures').
The major change was a clear definition of the "need". Every variable
in Oz is either "needed" or "not needed". The "need state" is
monotonic: it goes from "not needed" to "needed", and remains needed.
Determined variables are needed by convention. By-need synchronization
is simply defined as the synchronization on the "needed" state:
proc {ByNeed P X}
thread {WaitNeeded X} {P X} end
end
> What you consider "serious" is subjective, of course. But for example,
> renaming the former ByNeed to ByNeedFuture surely is an incompatible
> change that requires adapting all occurances of it in the Alice
> system.
>
> That and other more subtle changes certainly break the semantics of
> the Future module in the Alice lib, which is specified at
>
> http://www.ps.uni-sb.de/alice/manual/library/future.html
>
> Here is the current implementation of the primitives (operations not
> found below are implemented non-primitively in Alice):
Great. Here are proposals and explanations on how to adapt the
operations.
> 'Future.await':
> fun {$ X} {Wait X} X end
> 'Future.awaitEither\'':
> fun {$ X Y} {WaitOr X Y} {Not {IsDet X}} end
No change is needed here.
> 'Future.byneed':
> fun lazy {$ P}
> try
> {P unit}
> catch error(InnerE ...) then
> {Value.byNeedFail error(InnerE)}
> end
> end
In our proposal, 'fun lazy' not longer returns a future, but simply a
variable with a by-need computation. Here is a proposal that will do
the job:
fun {$ P}
!!{ByNeed fun {$}
try
{P unit}
catch error(InnerE ...) then
{Value.failed error(InnerE)}
end
end}
end
> 'Future.concur':
> fun {$ P}
> !!thread
> try
> {P unit}
> catch error(InnerE ...) then
> {Value.byNeedFail error(InnerE)}
> end
> end
> end
Simply replace Value.byNeedFail by Value.failed:
fun {$ P}
!!thread
try
{P unit}
catch error(InnerE ...) then
{Value.failed error(InnerE)}
end
end
end
> 'Future.isByneed':
> fun {$ X}
> {IsFuture X} andthen
> case {Value.toVirtualString X 0 0} of % hack taken from
> Inspector
> &_|&<|&f|&u|&t|&u|&r|&e|& |&b|&y|&N|&e|&e|&d|_ then true
> else false
> end
> end
Well, that hack is not backward compatible... In our model, a by-need
computation is simply a thread that synchronizes on the need of the
variable. There's no difference with other threads.
Now it depends what you use this operation for. If you use it for
implementing isLazy, I have a proposal. Its definition can be directly
implemented by
fun {IsLazy V} {IsFuture V} andthen {Not {IsNeeded V}} end
> 'Future.status':
> fun {$ X}
> if {IsFuture X} then
> if {Value.isFailed X} then 'FAILED'
> else 'FUTURE'
> end
> else 'DETERMINED'
> end
> end
In my proposal, failed values have their own status, and are independent
from futures. It becomes:
fun {$ X}
case {Value.status X}
of future then 'FUTURE'
[] failed then 'FAILED'
else 'DETERMINED'
end
end
> AFAICS, at least byneed, concur, status and isByneed would break with the
> proposed changes. Since Alice relies heavily on futures (and essentially
> uses futures as the exclusive means of synchronisation), the system is
> unlikely to work properly at all without adaptions.
>
> OTOH, if somebody finds a way to express the above operations in a
> backward-compatible *and* sufficiently efficient way in the new semantics
> then we can relax and simply go with it. Any ideas?
As you can see, all operations except Future.isByneed can be adapted to
our new model. I will provide all the necessary help for maintaining
friendship between Mozart and Alice ;-)
Cheers,
raph
-
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/.