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].

Reply via email to