Fix issue 17019: each should be usable with parallel (and behave like foreach)#4990
Conversation
|
Thanks for your pull request, @wilzbach! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + phobos#4990" |
ea4cc19 to
97a66cc
Compare
PetarKirov
left a comment
There was a problem hiding this comment.
Overall LGTM, just some minor comments below:
std/algorithm/iteration.d
Outdated
| foreach (ref a, ref b; r) | ||
| cast(void)binaryFun!BinaryArgs(a, b); | ||
| } | ||
| else // static if (isForeachUnaryWithIndexIterable!Iterable) |
There was a problem hiding this comment.
If you want, you can change the static if to a static assert and move it into the else block.
There was a problem hiding this comment.
Oh I opted for this because it was used like this before. I prefer static assert as well :)
std/algorithm/iteration.d
Outdated
| debug(each) pragma(msg, "Using foreach for ", Iterable.stringof); | ||
| static if (isForeachUnaryIterable!Iterable) | ||
| { | ||
| debug(each) pragma(msg, "unary"); |
There was a problem hiding this comment.
I guess this can be removed, now that you have debugged the issue ;)
| foreach (ref e; r) | ||
| { | ||
| cast(void)unaryFun!pred(e); | ||
| } |
There was a problem hiding this comment.
Nit/personal preference: curly braces are not needed for simple singe statement blocks.
| /// each should work with index | ||
| @safe unittest | ||
| { | ||
| import std.range : iota, lockstep; |
There was a problem hiding this comment.
I think you also need to import sum, even though it's in same module, so the unittest can be run in the online documentation.
There was a problem hiding this comment.
even though it's in same module, so the unittest can be run in the online documentation.
Luckily only external dependencies (e.g. global imports), it's fairly trivial to a import x.y.x and we do so:
https://github.com/dlang/dlang.org/blob/master/js/run_examples.js#L29
The automatic tests extractor which is partially enabled for Phobos does this as well and will warn if someone tries to sneak public tests in that aren't runnable ;-)
std/algorithm/iteration.d
Outdated
| } | ||
|
|
||
| // #15357: `each` should behave similar to foreach | ||
| /// each should work with index |
There was a problem hiding this comment.
Since it's a ddoc-ed example, "each works with iterable objects which provide an index variable, along with each element", or sth. like that would be more appropriate.
std/algorithm/iteration.d
Outdated
| assert(arrA.sum == 0); | ||
| assert(arrB.sum == 4); | ||
|
|
||
| /// three ref parameters |
There was a problem hiding this comment.
Nit: use either numbers or words on both places for consistency.
std/algorithm/iteration.d
Outdated
| parallel(logs).each!((ref e) => e += 1); | ||
| assert(logs.sum == 10); | ||
|
|
||
| auto logsIndex = new int[10]; |
There was a problem hiding this comment.
Nit: s/logs/arr/ (logs sounds confusing).
7a61f31 to
7273b50
Compare
std/algorithm/iteration.d
Outdated
| foreach (ref i, ref a; r) | ||
| cast(void)binaryFun!BinaryArgs(i, a); | ||
| foreach (ref a, ref b; r) | ||
| cast(void)binaryFun!BinaryArgs(a, b); |
There was a problem hiding this comment.
rationale for changing the parameter names?
There was a problem hiding this comment.
Strange, yes, but you can't be perfect. I think we should pull.
There was a problem hiding this comment.
To symbolize that it's a binary iteration with two elements - i is usually used as designated variable for the loop index.
The idea was to make it similar to std.functional.binaryFun.
Moreover, the private function isForeachBinaryIterable got renamed to isForeachUnaryWithIndexIterable (above) for which the loop variable names are kept.
dukc
left a comment
There was a problem hiding this comment.
each should be usable with everything foreach is with, yes. If only language makes it possible.
More than enough unittests are provided and everything passes. We should pull it.
7273b50 to
f145959
Compare
|
(rebased to latest |
343b08b to
e898090
Compare
|
That's weird. It seems for Windows this creates a cyclic dependency: CC @schveiguy any easy trick to workaround this? |
|
@wilzbach I've run into that before. I think it's due to a difference in how the module info is output on non-Windows platforms. I never got around to figuring out why it happens. The cycle is definitely there, and it's not Windows-specific. How you deal with the cycle is to get rid of the cycle, no easy tricks. If I were to approach it, I'd say try moving the CACHELIMIT variable and its initialization into its own file. That should break the cycle, since it only depends on druntime, so you can't have a cycle back to Phobos through core.cpuid. |
|
867c068 to
9b5ce12
Compare
9b5ce12 to
40e8db9
Compare
|
Rebased to master. I have good hopes that this finally passes the testsuite as there was quite some work to get rid of the shared module constructors... |
Grr... and sometime time does break the PR again. Reduced ICE: https://issues.dlang.org/show_bug.cgi?id=18713 |
40e8db9 to
3f44a4c
Compare
|
Can't be more green than now. Ready to move on? |


The following test fails:
while it passes without parallel:
of course the foreach alternative works as well
(I also added more tests, which should hopefully help to cover more edge cases)