pure or not pure?

Janice Caron caron800 at googlemail.com
Wed Apr 9 13:36:16 PDT 2008


On 09/04/2008, Steven Schveighoffer <schveiguy at yahoo.com> 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).



>  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!().



>  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.


>  i.e.:

By the way, that should be e.g., not i.e.


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




>  as an example of a pure function that takes a pointer to mutable data, but
>  doesn't use the data, i.e. this doesn't ever read or write heap data:
>
>  pure char *add(char * c, int n) { return c + n;}

Oooh - now that's an interesting one. That one's got me foxed. My
instinct says it should be disallowed, but I can't quite put my finger
on why. I'm gonna have to think about that one some more.


>  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


>  Will the compiler tag heap data somehow during execution of a pure function
>  to determine whether it is unique or not?

My guess would be no. (But that's just a guess). I reckon you'll have
to worry about that yourself and use the assumeUnique!() template to
return the data.



More information about the Digitalmars-d mailing list