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

Reply via email to