[ Posted by Urban Hafner
Mon, 07 Nov 2005 14:31:03 GMT ]
The problem
Dataflow behaviour in a concurrent setting. Consider the function {Filter In F}, which returns the elements of In for which the boolean function F returns true. Here is a possible definition of Filter:
fun {Filter In F}
case In
of X|In2 then
if {F X} then X|{Filter In2 F}
else {Filter In2 F} end
else
nil
end
end
Executing the following:
{Show {Filter [5 1 2 4 0] fun {$ X} X>2 end}}
displays
(We use the procedure Show, which displays the instantaneous value of its argument in Mozart’s emulator window. Unlike Browse, this output is not updated if the argument is subsequently bound.) So Filter works as expected in the case of a sequential execution when all the input values are available. Let us now explore the dataflow behaviour of Filter.
a) What happens when we execute the following?:
declare A
{Show {Filter [5 1 A 4 0] fun {$ X} X>2 end}}
One of the list elements is a variable
A that is not yet bound to a value. Remember that the
case and
if statements will suspend the thread in which they execute, until they can decide which alternative path to take.
b) What happens when we execute the following?:
declare Out A
thread Out={Filter [5 1 A 4 0] fun {$ X} X>2 end} end
{Show Out}
Remember calling
Show displays its argument as it exists at the instant of the call. Several possible results can be displayed. Which and why? Is the
Filter function deterministic? Why or why not?
c) What happens when we execute the following?:
declare Out A
thread Out={Filter [5 1 A 4 0] fun {$ X} X>2 end} end
{Delay 1000}
{Show Out}
Remember that the call
{Delay N} suspends its thread for at least
N ms. During this time, other ready threads can be executed.
d) What happens when we execute the following?:
declare Out A
thread Out={Filter [5 1 A 4 0] fun {$ X} X>2 end} end
thread A=6 end
{Delay 1000}
{Show Out}
What is displayed and why?
My solution
a) Nothing is displayed because Filter is suspended waiting on A to become bound.
b) What gets displayed on my box is Out<optimized>. But when I use the Browser I see 5|_. Another possible value would _ if Show is executed before Filter. But even though there can be different values shown doesn’t mean that Filter itself is not deterministic. What’s not deterministic is the way threads are executed and Show is probably not part of the declarative model.
c) This displays 5|_<optimized>. So it seems that the calls to Show in b) that I got were all before the call to Filter.
d) This of course displays [5 6 4]. Filter can finish because A gets bound, and we are waiting long enough before calling Show.
Tags book, concurrency, CTM, dataflow, exercise, mozart, oz
[ Posted by Urban Hafner
Wed, 02 Nov 2005 16:13:41 GMT ]
The problem
The Wait operation. Explain why the {Wait X} operation could be defined as:
proc {Wait X}
if X==unit then skip else skip end
end
Use your understanding of the dataflow behavior of the if statement and == operation.
My solution
The idea of Wait is to wait until its argument become bound. The == (i.e. the entailment check) is used to make the procedure wait. The if statement is needed, because == returns a value but Wait doesn’t. To get rid of this value you simply wrap the call to == in an if statement and let the if return nothing.
Tags book, CTM, dataflow, exercise, mozart, oz, wait
[ Posted by Urban Hafner
Wed, 02 Nov 2005 16:13:30 GMT ]
The problem
Order-determining concurrency. Explain what happens when executing the following:
declare A B C D in
thread B=C+1 end
thread C=B+1 end
thread A=1 end
thread B=A+1 end
{Browse D}
In what order are the threads created? In what order are the additions done? What is the final result? Compare with the following:
declare A B C D in
A=1
B=A+1
C=B+1
D=C+1
{Browse D}
Here there is only one thread. In what order are the additions done? What is the final result? What do you conclude?
My solution
Of course both code snippets produce the same result, namely 4. And of course the threads in the first code example are executed in the same way as in the second. That’s because the threads have to wait for the variables they are using in the additions to become bound.
An what do I conclude? Well, that this kind of concurrency is declarative. At least that’s what I think I was supposed to answer :)
Tags book, concurrency, CTM, dataflow, exercise, mozart, oz, variable
[ Posted by Urban Hafner
Thu, 15 Sep 2005 18:55:46 GMT ]
The problem
Iterative computations and dataflow variables. The previous exercise shows that using dataflow variables sometimes makes it simpler to write iterative list operations. This leads to the following question. For any iterative operation defined with dataflow variables, is it possible to give another iterative definition of the same operation that does not use dataflow variables?
My solution
I’m really unsure about this one. If anyone can explain it in a nice and convincing way I’d happily replace my hand waving with it.
If we assume that iterative computation means the function Iterate from section 3.2.4 then it seems possible to replace any use of dataflow variables. Just translate your function into one similar to Iterate and you have removed any dataflow variables.
Tags book, CTM, dataflow, exercise, iterative, mozart, oz