in reply to Re^18: Why is the execution order of subexpressions undefined?
in thread Why is the execution order of subexpressions undefined?

You said:

for my $i ( 1 .. $n ) { $results[ $i ] = $db->getLocalData() * $lwp->getRemoteData(); }

The db object and the $lwp object can both run in parallel. The EOD is on the results, not the method calls.

I'm trying to wrap my head around this. How can they both run in parallel when the order of evaluation is well-defined? What if one argument has side effects affecting the other? If the two functions are evaluated in parallel, then they will end up with different results. For example:
for my $i (1 .. $n) { $results[ $i ] = somefunc1($i) + somefunc2($i); } { my $data = 0; sub somefunc1 { my $i = shift; $i += $data++; sleep(1); $i; } sub somefunc2 { my $i = shift; sleep(1); $i *= $data++; $i; } }
Here I'm just faking out your local/remote data retrieval, but with a dependancy between them. Based on EO, we must wait for somefunc1 to return before executing somefunc2 (or vice versa, depending on the definition of EO). This has become a completely serialised task - there is no way that we can parallelise it.

If, however, EO remains undefined, we place the ball firmly and explicitly in the developer's court. We are saying, "we, the compiler, make no guarantees about the order in which we evaluate expressions, or even if they are to be evaluated if we can prove their value is useless (e.g., 0 * foo(), if we know that foo returns natural numbers, as per its perl6-style prototype), or even that there will be an order if we can do it in parallel - if your code cannot handle this, it is up to you to use explicit synchronisation points (aka ";") to delineate where you want me to synchronise my calculations." Yes, you need to use temporary variables to store intermediate values. However, nothing says that this intermediate value can't be optimised away, as long as the compiler can guarantee that synchronisation point between executions, in the order that you specify.

In fact, I would love to see perl6 go the other way - and allow me to say "for this block of code, execution order is whatever you want." And then inside that, other blocks that say, "Well, treat this as sychronised." Or something like that. For example:

parallel { clean_up_tmp_dir(); serial { $data = read_value_from_db(); $data += read_value_from_lwp(); }; serial { my $other_stuff = fib(3) * fib(8); do_something($other_stuff); } };
And have /tmp cleaned up in one thread, db and lwp reading done in a second thread, fib(3) in a third, fib(8) in a fourth, and do_something with fib(3) * fib(8) in a fifith. All because execution order is undefined. That would be cool. (Writing a caching, parallelisable fib() would be an interesting task, too, methinks.)