Search code examples
language-designlanguage-featuresd

Why is there no 'forall' in std.parallel?


I've been going over the new std.parallel library. I'm not a language or library designer, so forgive my ignorance, but would it not be beneficial if there was a forall statement in the language, or at least in std.parallel?

For example, instead of this:

auto logs = new double[1_000_000];
foreach(i, ref elem; taskPool.parallel(logs)){
        elem = log(i + 1.0);
}

we could write this:

auto logs = new double[1_000_000];
forall!((x){ return log(x + 1.0); })(logs);

foreach is sequential by nature and we can break out of it anytime, whereas forall is a guarantee that all elements will be processed. Is that a correct statement? Is it only a matter of time before forall is implemented, or is there a good reason for not having it?


Solution

  • I think that you're misunderstanding what std.parallelism is doing with foreach. If you look at the documentation, it specifically states that

    Break­ing from a par­al­lel fore­ach loop via a break, la­beled break, la­beled con­tinue, re­turn or goto state­ment throws a Par­al­lelFore­achEr­ror.

    So, you can't break out of it at any time unless you throw an exception - which is exactly what the case would be with forall. When you use foreach with parallel, you're telling it to dole out the iterations of that loop to separate threads. They're almost certainly doled out in sequential order, but they're executed in parallel, and you don't really care about the order. If you did, you couldn't do them in parallel. So, adding a forall wouldn't buy you anything here.

    D is by its very nature a sequential language just like most programming languages. It provides some powerful features which relate to threading (such as defaulting to thread-local storage), but I expect that it would require a fair bit of redesign to put something like forall directly in the language. And as it turns out, it's not necessary. The language is powerful enough to allow for the parallelism to be built on top of it. std.parallelism is effectively giving you forall. It's just that it's doing it by using the existing language feature foreach rather than having to have the language altered to understand and contain forall as a built-in feature.

    And, as CyberShadow notes, a new module, std.parallel_algorithm, is in the works which will have parallel versions of many of the functions in std.algorithm so that you get that parallelism for free. Overall, std.parallelism seems to be doing a good job of giving easy to use but powerful parallelism features for D.