pure or not pure?

Steven Schveighoffer schveiguy at yahoo.com
Wed Apr 9 14:24:39 PDT 2008


"Janice Caron" wrote
> On 09/04/2008, Steven Schveighoffer wrote:
>> I realize that I don't fully understand all the rules of what D pure
>>  functions will be.
>>
>>  I think all agree on these rules:
>>
>>  - pure functions can only call pure functions
>>  - allow access to invariant data
>>  - allow mutable access to simple stack variables (variables that are all 
>> on
>>  the stack, no references)
>>
>>  In Andrei's accu-functional document, instead of the last rule, there 
>> is:
>>
>>  - allow local automatic mutable state
>
> I thought that was pretty clear. It means local variables are allowed
> to be mutable. (I realise that "automatic" isn't a synonym for
> "local", but in the examples in accu-functional, Andrei does seem to
> use it that way).

So 'local automatic' means 'local local'?

>>  But here are some questions about what is
>>  pure and what is not pure:
>>
>>  1. Can pure functions use mutable heap data?
>
> I don't see why not.
>
>
>>  If so, what are the
>>  restrictions for this?
>>
>>  i.e.:
>>  pure char[] f(int x, int y)
>
> I'm confident enough to say the return value will have to be
> invariant. However, you that doesn't stop you from returning heap
> data.  You should be able to do
>
>    pure string spaces(int x)
>    {
>        auto s = new char[x];
>        s[] = ' ';
>        return assumeUnique!(s);
>    }
>
> but you can't omit the assumeUnique!().

So how is new char[] a pure function?  And why can't I 'wrap' new?  For 
instance, if I have a function:

int[] createIncreasingSequence(int s, int e, int step){...}

which creates an array of ints that start at s and end at e, increasing by 
step each time, why can't I make that pure?  i.e. I want to specify my own 
way to initialize an array.  If I do that in 10 different pure functions, 
you're saying I have to re-implement that code in each one?

>
>
>
>>  2. Can pure functions use stack references to objects that are partially
>>  invariant, partially mutable?
>
> My guess would be no. There's just no need for it.
>

Surely there is some possible need for having run-time initialized invariant 
variables...

>>  This of course, assumes that C can assign x through a constructor, not 
>> just
>>  through a static initializer (this is not implemented today).
>
> I don't think it will be possible to initialize invariant data in a
> non-invariant constructor, and I think an invariant constructor can
> only make a fully invariant class.
>
> I think this is a /necessary/ restriction, because otherwise the
> following could not be typechecked:
>
>    class C
>    {
>        invariant int * p;
>
>        this(int * q)
>        {
>            p = q; // Big no no!
>        }
>    }

Why would that compile?  If it did, then so would this:

this(int *q) invariant
{
    p = q;
}

I think invariant members that are run-time initialized can be done, as 
during the constructor, nothing has access to the 'this' pointer.

>>  3. If the answer to question 1 is 'yes', can you pass mutable heap data 
>> to
>>  pure functions?
>>
>>  pure char[] substr(char[] src, int beg, int end) { return 
>> src[beg..end];}
>
> Same answer.
>
>
>
>>  Would substr be allowed to be called from a pure function?
>
> If and only if substr() is itself a pure function.
>
>>  Would substr be allowed to be called from a non-pure function?
>
> Yes

This was misleading on my part.  I should have asked instead of these two 
questions, if substr is allowed to be pure, can it be called from a non-pure 
function?  In the context of being called from a pure function, src is 
unique, because pure has to have unique data.  But in the context of calling 
from a non-pure function, it might not be...

-Steve 





More information about the Digitalmars-d mailing list