Pure functions in D
Steven Schveighoffer
schveiguy at yahoo.com
Wed Sep 24 05:34:29 PDT 2008
"Bruno Medeiros" wrote
> Steven Schveighoffer wrote:
>> "Bruno Medeiros" wrote
>>> Steven Schveighoffer wrote:
>>>> Another possibility is that pure functions that accept mutable
>>>> parameters can only be called from other pure functions, therefore you
>>>> are guaranteed that the data is not being used in any other thread.
>>>>
>>> I'm almost certain this is the intended behavior, with the addition that
>>> you can also call that same pure function from an unpure one, only then,
>>> the compiler will treat the function as being unpure. This is the gist
>>> of the "partially pure"/"contextually pure" idea: a function is
>>> considered pure or not dependent on the immutability of the arguments
>>> with which it's called. This consideration "happens" on every call.
>>> Since the optimizations to pure functions are made on the call, and not
>>> on the body of the function, this is perfectly ok.
>>> I don't see any other behavior that isn't either broken, or more limited
>>> in functionality.
>>
>> One of the benefits that Walter and Andrei's original purity plan
>> provided was that you could always assume that pure functions did not
>> have to worry about threading issues. I think allowing a pure function
>> that takes mutable arguments to be callable from an unpure function
>> removes that benefit. I hope this isn't the case.
>>
>> Of course, if shared/unshared is implemented, and pure functions are only
>> allowed to be passed 'unshared' mutable data, then the benefit is still
>> on.
>>
>> I'm just unclear on what Walter is planning. I admit I didn't read the
>> whole article, I just saw that quote and thought 'hm... that looks
>> wrong'.
>>
>>> Also note that in the case where the given (contextually) pure "foo"
>>> function is called from a pure function, the fact that foo is called
>>> from a pure function only guarantees that the arguments are not changed
>>> by anyone else when foo executes, but foo must still be treated as
>>> unpure. Example:
>>>
>>> pure void foo(int* iptr) {
>>> (*iptr)++; // side effect
>>> }
>>>
>>>
>>> pure int func() {
>>> int a = 1;
>>> foo(&a); // side-effect, cannot optimize this call
>>> foo(&a); // side-effect, cannot optimize this call
>>> return a;
>>> }
>>> // Yet func is allways pure.
>>
>> I agree with you, partially pure functions can be called from pure
>> functions with limited optimization. But if you allow foo to be called
>> from an unpure function you could have this problem:
>>
>> int func2()
>> {
>> static int a = 1;
>> foo(&a);
>> }
>>
>> Now, if 2 threads are calling func2, you have race conditions and
>> threading issues in foo, which seems to be a major concern that W/A were
>> trying to address. And I hope they do address it, it was the one huge
>> benefit I saw from pure functions.
>>
>> -Steve
>
> Yes, you can have race and threading issues in foo with that call. But
> what is the alternative? In the first pure system (in andrei's
> presentation) that call would not be allowed. So what you would do? You'd
> have to write another function just like foo (the same code), but that is
> not marked pure, and use that. But you'd still have the same
> synchronization problems.
> If you don't want to have those issues, write a foo function that takes
> invariant parameters.
> The partially pure functions (functions with mutable parameters), which
> basically have localized side-effects and are deterministic when called
> from "really-pure" functions, are not there to provide the full effects of
> really-pure functions. They are just a convenience for the writing the
> really-pure functions.
>
> (Also, I'd reckon most static/global functions will be partially pure.)
It creates a definitive line which can be used to determine whether or not I
need to worry about threading. Having the compiler enforce this I see as a
huge benefit. I was hoping to keep that line.
If the compiler enforces that the parameters to foo must be local, either by
implementing the shared/unshared paradigm or only allowing calling from
other pure functions, then the line still exists.
It appears that that is the case, as evidenced from other posts.
-Steve
More information about the Digitalmars-d
mailing list