pure member functions

Don nospam at nospam.com
Mon Sep 20 13:26:44 PDT 2010


Steven Schveighoffer wrote:
> On Mon, 20 Sep 2010 15:45:10 -0400, Don <nospam at nospam.com> wrote:
> 
>> bearophile wrote:
>>> Jonathan M Davis:
>>>
>>>> I assume that if you declare a member function as pure, then all of 
>>>> its parameters - including the invisible this - are included in 
>>>> that. That is, if all of them - including the invisible this - have 
>>>> the same value, then the result will be the same.
>>>  This D2 program runs with no errors, and here there isn't a D 
>>> language/compiler bug:
>>>  struct Foo {
>>>     int x;
>>>     this (int xx) { this.x = xx; }
>>>     pure int bar() { return x; }
>>> }
>>> void main() {
>>>     Foo f = Foo(1);
>>>     assert(f.bar() == 1);
>>>     f.x *= 2;
>>>     assert(f.bar() == 2);
>>> }
>>>  Bye,
>>> bearophile
>>
>> You do need to be careful about concluding how 'pure' works based on 
>> the current behaviour of the compiler.
>> There's a trap here. What if you use a hypothetical startTimer() 
>> function which executes a delegate every few clock ticks?
>>
>> void main() {
>>      Foo f = Foo(1);
>>      startTimer( () { f.x++; });
>>      scope(exit)
>>     killTimer();
>>
>>      assert(f.bar() == 1); // may fail!
>>      f.x *= 2;
>>      assert(f.bar() == 2);
>> }
> 
> Wouldn't f have to be shared for this to be asynchronous?

That's an excellent point. 'pure' was put into the language long before 
'shared' and '__gshared'. It could now just mean, "doesn't use static, 
globals, shared, or __gshared".

And then cachable pure is just: pure, + all reference parameters are 
immutable.

If this becomes the rule, it seems likely that pure functions would 
become far more common than impure ones.

>> I actually think that 'pure' on a member function can only mean, it's 
>> cacheably pure if and only if 'this' can be cast to immutable. Which 
>> includes the important case where the call is made from a pure 
>> function (this implies that the 'this' pointer is either a local 
>> variable of a pure function, or an immutable object).
>> Since pure functions cannot call impure functions, they can't do any 
>> of this nasty asynchronous stuff.
> 
> I think it's ok for a function to be pure if all the arguments are 
> unshared, regardless of immutability.  However, in order to cache the 
> return value, the reference itself must not be used as the key, but the 
> entire data of the reference.  Even if it's immutable, wouldn't you not 
> want to cache the return values between two identical immutable objects?

Possibly, but my guess is that it would take too long to check.


More information about the Digitalmars-d-learn mailing list