Proposal: Relax rules for 'pure'

Robert Jacques sandford at jhu.edu
Tue Sep 21 22:26:01 PDT 2010


On Tue, 21 Sep 2010 22:21:39 -0400, Don <nospam at nospam.com> wrote:

> The docs currently state that:
> ---
> Pure functions are functions that produce the same result for the same  
> arguments. To that end, a pure function:
>
>      * has parameters that are all immutable or are implicitly  
> convertible to immutable
>      * does not read or write any global mutable state
> ---
>
> This is extremely restrictive, and not currently enforced.
> Two specific limitations:
> - a 'pure' member function doesn't really make sense (could only be  
> called on an immutable class)
> - a pure function cannot have 'out' parameters.
>
> In a discussion on D.learn, Steven Schveighoffer noted that it's only  
> shared variables which make things complicated.
> The limitations exist because 'pure' is used to mean both 'no hidden  
> state' AND 'cachable'. But 'cachable' is really only an implementation  
> detail.
>
> PROPOSAL:
> Drop the first requirement. Only one requirement is necessary:
>
> A pure function does not read or write any global mutable state.
>
> If a pure function has parameters that are all immutable or are  
> implicitly convertible to immutable, then the compiler is permitted to  
> cache the results.
>
> This is possible because the first rule (all immutable parameters) is  
> trivial, and can be checked from the function declaration (in fact, you  
> can check it just from the mangled function name). The second rule (no  
> globals) is viral, and requires inspection of the function body, and the  
> function bodies of every function called by that function.
>
> Actually, a clever compiler could even cache the results of pure  
> functions which have parameters which don't implicitly cast to immutable.
>
> I haven't found anything in TDPL which mentions the "only immutable  
> parameters" rule. Relaxing that rule would allow much larger functions  
> to be cached. The more important benefit (IMHO) of pure, that it makes  
> it easier to reason about code, would be dramatically extended.

One of the major benefits of functional languages (a.k.a pure functions)  
is that you can automatically parallelize them (i.e. via a task based  
runtime) in addition to caching the result. I really don't want to lose  
that guarantee. However, I do see your point. One of the benefits of D's  
pure functions is the ability to use procedural code inside them; however  
the "does not read or write any global mutable state" prevents pure  
functions from calling impure functions/members on their internal (impure)  
variables. So removing the concurrency safety from pure would greatly  
expand the number of pure functions, however, automatic parallelism would  
be lost. I don't view this as an acceptable reduction in pure's power,  
particularly given that Dave's std.parallelism module is currently under  
review.

With regard to an alternative, I think two levels of pure have been  
identified as being useful and synergistic to each other. I think this  
could either manifest itself as pure + scope(pure) or as a new 'task' type  
+ pure. Anyways, that's my two cents worth.


More information about the Digitalmars-d mailing list