On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote:
I have found the documentation for each in std.algorithm a bit
terse. It seemed like it was an eager version of map, but it
seems to be a bit more limited than that.
In particular, the documentation says that if you can mutate
the value in place, then you can call each on it. The first
thing I noticed is that this works easiest (beyond in place
operators) when you're using a void function and taking the
input you want to change as ref. This is what I did in the foo
and bar functions below. However, it's not the same thing as
just applying the function. In the baz function, I mutate the
value and then return a different value. Using baz with each
doesn't change the value by 2, only by 1.
What really confused me is that I can't use a lambda with each
in a similar way as map. I think this is because the lambdas
I'm using really aren't void functions. The part after the =>
is basically a return statement, so I'm not really mutating
anything in place. Is there any way to do this with lambdas or
are void functions required?
"a += 1" in D is an expression that first mutates a and then
returns a. Therefore, you can write this lamda:
(ref a) => a += 1
And it should work fine with `each`. The expanded version that
this desugars to is:
int function(ref int a)
{
return a += 1;
}
On the other hand, however, a + 1 is an expression that does not
mutate a. It just returns the value of a with 1 added to it.
Therefore, `(ref a) => a + 1` cannot work, as it does not
actually modify a.
The best way to think of it is as if the body of your lambda is
being executed in a `foreach` loop. If you translate some of your
examples, it should become obvious as to what the result is.
x.each!((ref a) => a++)
becomes
foreach (ref a; x)
{
a++;
}
And, of course, the answer is x == [2, 3, 4].