Luke Palmer wrote:

forall was about concurrency, not order of evaluation.  There is a difference
between running in an arbitrary order serially and running in parallel.

    for %bag {
        .say;
    }

If the bag had elements "hello", "world", I think printing:

   helworld
   lo

Would definitely count as violating the principle of least surprise.

For the specific case of C<say>, I think that its implementation should probably be "is critical" -- The C<say> method is designed for simple user messages, and atomicity is probably as useful as the auto-newline for its intended usage. But your general message still stands: concurrency can surprise if not handled properly.

Just thinking out load, perhaps one could say that the following constructs are broadly equivalent:

*  for %bag { .say };
*  forall %bag { is locally_critical; .say };

(lets assume for now that "is locally_critical" is like "is critical" but protects only against child-threads of the ::OUTER scope)

Now lets change the definition of curlies such that they always imply this modified "is locally_critical" trait. Now, the following would be equivalent:

*  for %bag { .say };
*  forall %bag { isnt locally_critical; .say };

From here I'll just make one more proposal: a new form of curley:

* for %bag { .say }; // unordered sequential ("locally_critical")
* for %bag {{ .say }}; // unordered concurrent (not "locally_critical")

With these modified forms of braces it becomes much easier to define safe concurrent control structures: the default curlies force the additional safety yet there's a simple alternative that increases concurrency without requiring a new statement (but one would still need a special form of splat operator to morph a sequential container for unordered iteration -- so maybe the general unordered "forall" statement would still be useful)

Reply via email to