Idea: partially pure functions

Steven Schveighoffer schveiguy at yahoo.com
Thu May 1 08:25:30 PDT 2008


"Bruno Medeiros" wrote
> Steven Schveighoffer wrote:
>> "Bruno Medeiros" wrote
>>> I state that if you have 'pure' implemented (in a sensible manner), it 
>>> takes zero effort to implement partial/contextual pure.
>>>
>>> The definition of partial pure functions requires no extra effort from 
>>> the compiler to check. (The *same* check for normal pure functions is 
>>> made: that no external state is accessed unless invariant)
>>>
>>> The usage of partial pure functions also requires no extra effort. 
>>> Inside a pure function body, the compiler already has to check if no 
>>> external, non-invariant variables are accessed, like this:
>>>
>>>   Foo globalVar;
>>>
>>>   pure void func(...) {
>>>     localVar = globalVar + 1; // not allowed
>>>
>>> then just apply this same check on *any* expression, including function 
>>> call expressions:
>>>
>>>   partiallyPureFunction(localVar, globalVar); // not allowed
>>>   partiallyPureFunction(localVar, localVar2); // but this is allowed
>>
>> What if localVar is a pointer to global data, or transitively contains a 
>> pointer to global data?  There is no way to know whether localVar is a 
>> pointer to global data or 'contained' heap data without lots of context 
>> checking.
>
> Whatever checks you have to make for localVar, you still have to do them 
> with normal pure. (And not that it matters to the point, how do you 
> initialize a local var with global data?)
>
>> If partially pure functions with mutable parameters were allowed, I'd say 
>> it's a requirement that you can only call them from partially or fully 
>> pure functions, as local pointers from those functions are guaranteed to 
>> be contained within the function.
>>
>
> I'm not sure I understand what you're saying. Are you saying that 
> partially pure functions should not be called from *non-pure* functions? 
> What's the sense in that?

>From the digitalmars web site:

"A pure function can throw exceptions and allocate memory via a 
NewExpression."

So in the case of a partially pure function that takes a char array:

pure void f(char[] x) {...}

Let's say I have a non-pure function g:

void g()
{
    char[] v;
    ...
    f(v);
}

In the ..., v can be set to local mutable heap data (via new char[x] or 
whatever), or it could be set to point to a global mutable string.  How can 
the compiler be sure without severe context analysis?  The point is, in 
order to ensure context-free lexical analysis by the compiler, it must 
disallow calling f from a non-pure function.

Contrast that from a pure version of g:

pure void g()
{
   char[] v;
   ...
   f(v);
}

Because g is now pure, it is a requirement that v cannot be assigned to some 
global variable.  The fact that g is pure ensures that f can safely be 
called.  v can only be set by calling a new expression.

-Steve 





More information about the Digitalmars-d mailing list