Steven Schveighoffer:
>
int[] f()
{
int[] x = new int[5];
foreach(i, ref n; x) n = i;
return x;
}
int[] g()
{
int[] x = new int[6];
foreach(i, ref n; x) n = i;
return x;
}
f and g can be pure, because they do not have side effects. However,
consider:
void fill(int[] x)
{
foreach(i, ref n; x) n = i;
}
int[] f()
{
int[] x = new int[5];
fill(x);
return x;
}
[...]
I'm not sure what the solution is. Something like 'unique' which would ensure
that exclusive ownership of an object passes to the method would possibly allow
passing mutable state into a pure function. I'm unsure if there are any plans
for something like this.
<
Probably there are ways to solve the situation, using unique or something else,
but I think that way leads to C++-style madness (see the ridiculously complex
lambdas of the last C++, they look like a joke to me. Those designers have
missed the point that the essential purpose of a lambda as used in mostly
imperative languages is to simplify code and the like, so having one hundred
optional features is bad). Keeping pure functions simple is the key to allow
their optimizations.
To solve your problem you can change your function fill() to restore its purity
(code untested):
pure void range(int n) {
int[] arr = new int[n];
foreach (i, ref el; arr)
el = i;
return arr;
}
pure int[] f() {
return range(5);
}
pure int[] g() {
return range(6);
}
Or you can just accept to not mark fill(), f() and g() as pure.
Bye,
bearophile