in reply to Re^30: Why is the execution order of subexpressions undefined? (magic ruts)
in thread Why is the execution order of subexpressions undefined?
In code with undefined EO, we still have some defined order. They're called "sequence points". And that is anywhere you see ";", ",", "(...)", "||", "&&", "or", "and". So, if I want to define an order, I can use temporary variables:
Here is a single statement with multiple sequence points. I know that func1 will be passed the original $a value. I know that $a will be incremented prior to entering func2 (the parens become a sequence point), and that func2 will get that incremented value. And that $var will be the sum of the return values from the two functions. If func1 has side effects that affect func2, then I know that func1 will finish prior to caling func2, and those side effects will occur.my $var = do { my $temp1 = func1($a); my $temp2 = func2(++$a); $temp1 + $temp2; };
Compare with:
The compiler is free to do this in any order it pleases. Even parallel. Side effects from func1 will not be guaranteed to occur prior to executing func2. Thus, with undefined EO, the programmer is asserting that there are no such side effects. If the compiler wants to run func1 and func2 in separate threads and combine their return value, that's fine by the programmer. The programmer has a degree of freedom here to choose one of the two methods depending on whether there are side effects or not.my $var = func1($a) + func2($a + 1);
With defined EO, the programmer has no freedom. There is no way to express the idea that "these may be parallelised." That's because defined EO defines, well, an Execution Order. That something completes prior to something else. And that is the definition of serial. The closest that we get to allowing a programmer to do this in parallel is:
Now, if the argument for EO is that this convoluted syntax would require programmers to really think hard before doing anything with threading, I could buy that a bit more. If perl (5 or 6) ever started auto-threading functions, I'm sure a lot of code would break. However, I would prefer undefined EO, and simpler syntax:my $var = do { my ($temp1, $temp2); my $thr1 = threads->new(sub { $temp1 = func1($a) })->start; my $thr2 = threads->new(sub { $temp2 = func2($a+1) })->start; $thr1->join; $thr2->join; $temp1 + $temp2 };
Or something like that. Or a pragma of some sort:AUTOTHREADSUBEXPRS { $var = func1($a) + func2($a+1); }
These only work when the EO remains undefined and make zero sense when EO is defined.use threadedsubexprs; my $var = func1($a) + func2($a+1);
Summary - I think I showed exactly how undefined EO still allows a programmer to convey requirements for execution ordering to the compiler. I've gone further - I've shown how EO definition merely changes how much work it is to either define execution order, or to get a pseudo-random execution order (via threads). Please stop making claims to the contrary. Thanks.
|
|---|