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