On 02/04/2012 11:04 PM, Era Scarecrow wrote:
Pure does not imply const in D. If you want stronger guarantees, just
turn 'test' into a const (or immutable) member function. In D, a
function can change anything that is mutable and reachable through its
parameters, this includes the implicit 'this' pointer. The reason for
this design is simple: There is no need to be overly restrictive,
because the additional restrictions are already trivially expressed in
the type system. Furthermore, any mutation of a parameter can be
turned into a less efficient protocol that only requires a const pure
function, so there would be no gain if pure implied const, it would
only make pure less useful.

void foo(int* x)pure{*x+=2;}
int bar(const(int)*x)pure{return *x+2;}

void main() pure{
int x, y;
foo(&x); // those two lines have
y = bar(&y); // equivalent functionality!
}

Only external data I was implying, that was not based off the input
arguments. Examples in the book refer that calculating Pi, or the square
root of 2 is a constant and will always result in the same output,
regardless the situation.

Quote TDPL pg 165:
"In D, a function is considered pure if returning a result is it's only
effect and the result depends only on the function's arguments.

Also, pure functions can run literally in parallel because they don't
interact with the rest of the program except through their result."

Probably the restriction was lifted after TDPL was out.

So... If we take a struct.

struct X {
int i;
pure int squaredPlus(int x) {
return x*x + i
}
alias squaredPlus sqp;
}

X st(15);

writeln(st.sqp(0)); //15
int i1 = st.sqp(10); st.i++;
int i2 = st.sqp(10); st.i++;
int i3 = st.sqp(10); st.i++;
int i4 = st.sqp(10); st.i++;

assert(i1 == 100); //pass/fail?
assert(i2 == 101); //pass/fail?
assert(i3 == 102); //pass/fail?
assert(i4 == 103); //pass/fail?
assert(s1.i == 104); //probably pass.

If the compiler can reorder or run these in parallel (for optimization)
or caches the result the first time (since it's suppose to always return
the same value), what's correct in this case? This afterall isn't
synchronized, even if it was, what's correct behavior? Am I wrong in
understanding this?

Yes. The compiler will only reorder/run in parallel/optimize if it is safe (not changing execution semantics). Pure can be used to prove that certain optimizations are safe. If a pure function only takes const or immutable arguments, the compiler has more guarantees and can do more things. If a pure function takes mutable arguments, it can be used as a component of other pure functions (important!), but the kind of optimizations that can be performed directly on them are a lot more limited.

'Pure' means that the behavior of the function does not change between invocations with the same/equivalent arguments. This can include mutating actions on the arguments, if those are typed mutable.


Reply via email to