On Sunday, 28 June 2015 at 09:19:16 UTC, Tofu Ninja wrote:
module main;
import std.stdio;
void main(string[] args)
{
        auto d = foo();
        writeln(d()); // prints 25
}

auto foo()
{
        int x = 4;
        pure int delegate() d = delegate()
        {
                return x*x;
        };
        writeln(d()); // prints 16
        x = 5;
        writeln(d()); // prints 25
        return d;
}

I can see that after foo returns, then d will truly be pure as x will no longer be modifiable, but just before that, it seems d is not actually pure. Is this the intended behavior?

Here's a similar example where it's a bit clearer what's going on:
----
struct S
{
    int x = 0;
    int d() pure {return ++this.x;}
}
void main()
{
    S s;
    int delegate() pure d = &s.d;
    import std.stdio;
    writeln(d()); /* prints "1" */
    writeln(d()); /* prints "2" */
    writeln(d()); /* prints "3" */
}
----

`d` isn't all that pure, right? You're seeing the concept of "weak purity" in action. In D, the attribute `pure` really just means "doesn't access global mutable state". The function is still allowed to mutate any arguments it gets, including hidden ones. Here the method `d` has a hidden `this` parameter, and it can mutate data through it. With a nested function, the enclosing context is passed via a hidden parameter.

Properly/mathematically/strongly pure functions have additional requirements on top of being marked `pure`. Read more here:
http://klickverbot.at/blog/2012/05/purity-in-d/

Reply via email to