Pure delegate not quite pure?

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jun 28 03:19:04 PDT 2015


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/


More information about the Digitalmars-d-learn mailing list