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