[SO] Modifing local class instance in pure function

Steven Schveighoffer schveiguy at yahoo.com
Thu Jun 18 20:04:50 PDT 2009


On Thu, 18 Jun 2009 18:16:36 -0400, div0 <div0 at users.sourceforge.net>  
wrote:

> Pure functions are not allowed to alter global state.
> That's what you doing when you create a new object.
>
> http://en.wikipedia.org/wiki/Functional_programming
>

I once thought as you do.  You are wrong.  Memory allocation is a  
necessary function, and although it is inherently unpure, it must be  
allowed in pure functions.

The problem is that the function boundary is where purity is enforced, not  
inside.  For instance, basic programming 101, split common tasks into  
functions:


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;
}

Note that f is still pure, and fill is contextually pure, since in f's  
context, it is not altering external state.

However, we cannot mark fill as pure, because when called from a non-pure  
function, it could alter external state.  Therefore, fill cannot be called  
 from f if f is pure.

This is similar to calling a method on an object:

C c = new C;
c.method();

The method call translates to:

C.method(c);

The compiler cannot tell whether c is external state or not, just like it  
cannot tell that fill() can be contextually pure.  So it is not allowed.

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.

-Steve


More information about the Digitalmars-d-learn mailing list