Will compiler-enforced pure be too strict?

Don Clugston dac at nospam.com.au
Fri Apr 4 00:35:40 PDT 2008


Craig Black wrote:
> Don Clugston wrote:
>> A function which accesses a global is inherently impure. But,
>> a function which takes a non-invariant argument, can in theory safely 
>> be called
>> from inside a pure function, provided any non-invariant arguments are 
>> local
>> variables, or invariant.
>>
>> eg.
>>
>> class C
>> {
>>   int numcalls;
>>   this() { numcalls=0; }
>>   void foo() { ++numcalls; } // Not pure - but no global side effects.
>> }
>>
>> pure int bar(int x)
>> {
>>     C c = new C;
>>     for (int i=0; i<x; ++i) c.foo();
>>     return c.numcalls;
>> }
>>
>> Is bar() pure or not?
>>
>> Incidentally this type of code currently works in CTFE.
> 
> The answer is yes bar is pure even though foo is not, because c is a 
> local variable, so it's non-static fields won't be accessed by other 
> threads. Unless I misunderstand, the rule is that a non-static 
> class/struct variable that is local to a pure function can call a member 
> function if that member function does not access global state.
> 
> My question is, will the compiler be smart enough to know that bar is 
> pure, even though foo is not?  Maybe we need some other keyword to 
> denote that a function does not access any global/static variables.  
> Something like this:
> 
> localstate void foo() { ++numcalls; }
> 
> Or perhaps the compiler would be smart enough to know this without the 
> keyword?

I don't see how the compiler could do it, without access to the source code.
Also, if the compiler is doing this automatically, then if you add a static 
variable inside foo(), you are changing the API of the function, and bar() . 
Even though bar() as written is pure, it can't safely use foo(), since foo() 
makes no guarantees that it won't become impure some day.

I can see a few options --
* very strict pure, bar() above cannot be pure.
* some way of signifying (new keyword?) that an arbitrary function has no global 
state.
* allow something like 'pure class'/'pure struct' for a class or struct which is 
safe to use in circumstances like the above -- a class which contains contains 
no statics, and which has no functions which access local variables.
* allow non-const member functions to be pure, even if they modify 'this'.

Probably we'll initally get the first one, but hopefully we'll get something 
like one of the other options eventually, otherwise pure functions will be very 
limited.



More information about the Digitalmars-d mailing list