On Tue, 21 Sep 2010 22:21:39 -0400, Don <nos...@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.

Reply via email to