Search code examples
dpure-function

How to use pure in D 2.0


While playing around with D 2.0 I found the following problem:

Example 1:

pure string[] run1()
{
   string[] msg;
   msg ~= "Test";
   msg ~= "this.";
   return msg;
}

This compiles and works as expected.

When I try to wrap the string array in a class I find I can not get this to work:

class TestPure
{
    string[] msg;
    void addMsg( string s )
    {
       msg ~= s;
    }
};

pure TestPure run2()
{
   TestPure t = new TestPure();
   t.addMsg("Test");
   t.addMsg("this.");
   return t;
}

This code will not compile because the addMsg function is impure. I can not make that function pure since it alters the TestPure object. Am i missing something? Or is this a limitation?

The following does compile:

pure TestPure run3()
{
    TestPure t = new TestPure();
    t.msg ~= "Test";
    t.msg ~= "this.";
    return t;
}

Would the ~= operator not been implemented as a impure function of the msg array? How come the compiler does not complain about that in the run1 function?


Solution

  • Since v2.050, D relaxed the definition of pure to accept the so called "weakly pure" functions too. This refers to functions that "do not read or write any global mutable state". Weakly pure functions are not the same as pure functions in the functional language sense. The only relation is that they makes real pure functions, a.k.a. "strongly pure" functions able call the weak ones, like OP's example.

    With this, addMsg can be marked as (weakly) pure, since only the local variable this.msg is altered:

    class TestPure
    {
        string[] msg;
        pure void addMsg( string s )
        {
           msg ~= s;
        }
    };
    

    and of course, now you can use the (strongly) pure function run2 with no modification.

    pure TestPure run2()
    {
       TestPure t = new TestPure();
       t.addMsg("Test");
       t.addMsg("this.");
       return t;
    }