www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question about pure functions

reply "Bienlein" <jeti890 web.de> writes:
Hello,

ich habe a pure method bar() in a class Foo:

class Foo {
	int i = 0;
	
	void bar() pure {
	    i++;
	}	
}

main() {
	auto foo = new Foo();
	foo.bar()	
}

The pure method bar changes the inst var i. Nevertheless, the
code above compiles and runs which I find confusing. I assumed
that changing an inst var by a pure function is considered
creating a side efect. But the compiler has no problems with this.

Am I getting something wrong here? Thanks for any hints.
Regards, Bienlein
Sep 16 2013
parent reply "anonymous" <anonymous example.com> writes:
On Monday, 16 September 2013 at 07:01:52 UTC, Bienlein wrote:
 Hello,

 ich habe a pure method bar() in a class Foo:

 class Foo {
 	int i = 0;
 	
 	void bar() pure {
 	    i++;
 	}	
 }

 main() {
 	auto foo = new Foo();
 	foo.bar()	
 }

 The pure method bar changes the inst var i. Nevertheless, the
 code above compiles and runs which I find confusing. I assumed
 that changing an inst var by a pure function is considered
 creating a side efect. But the compiler has no problems with 
 this.

 Am I getting something wrong here? Thanks for any hints.
 Regards, Bienlein
(Weak) pure functions are allowed to mutate their arguments. Methods take the object via a hidden parameter, so that's an argument, too. Mark all parameters const to get a strong pure function. For "this" const goes on the method: class Foo { int i = 0; void bar() const pure { // can't mutate i here } } See also: http://dlang.org/function.html#pure-functions
Sep 16 2013
next sibling parent "Bienlein" <jeti890 web.de> writes:
 Mark all parameters const to get a strong pure function. For 
 "this" const goes on the method:

 class Foo {
 	int i = 0;
 	
 	void bar() const pure {
 	    // can't mutate i here
 	}
 }

 See also: http://dlang.org/function.html#pure-functions
I see, thanks a lot. I like this pure feature and was already disappointed. Scala doesn't have it (has to remain interoperable with Java), so I was really happy to see it in D. Your answer saved my day :-) -- Bienlein
Sep 16 2013
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, September 16, 2013 10:08:22 anonymous wrote:
 Mark all parameters const to get a strong pure function. For
 "this" const goes on the method:
That's not actually enough. At present, in order for a function to be considered strongly pure, all of its parameters must be either immutable or implicitly convertible to pure (including the this reference). A const reference type is neither. In principle, a function could be considered strongly pure if its parameters were const but its arguments were immutable, but the compiler isn't that smart about it at this point. The parameters themselves must be immutable or implicitly convertible to immutable. So, at present, for a member function to be considered strongly pure, it must be an immutable member function, not const. In theory it could be const if the object itself were immutable, but again, the compiler isn't that smart about it at this point. In either case, the actual object would have to be immutable, which is not the case in most code. And if you make the member functions immutable, they can only be called by immutable objects, forcing you to either duplicate your functions or make it so that your class can only be constructed as immutable. pure member functions are useful, because they guarantee that the function is not accessing global mutable state, and because it makes it so that they can be called from strongly pure functions, but in general, pure member functions can't be strongly pure and therefore can't be optimized. If you want to see how many times a pure function is being called, then put a call to writeln inside of a debug {} block inside of it and compile with -debug, since debug blocks are not checked for purity (since they're for debugging). It should then print out every time it's being called, which should allow you to see whether multiple calls with the same arguments within an expression are actually being optimized out (though you might have to compile with -O for the compiler to do the optimizations - I don't know). - Jonathan M Davis
Sep 16 2013