Purity

Jonathan M Davis jmdavisProg at gmx.com
Sat Dec 18 01:08:20 PST 2010


On Saturday 18 December 2010 00:52:23 spir wrote:
> On Fri, 17 Dec 2010 02:42:14 -0500
> 
> bearophile <bearophileHUGS at lycos.com> wrote:
> > http://www.reddit.com/r/programming/comments/enajl/purity_in_d_language/
> > 
> > Bye,
> > bearophile
> 
> I take the opportunity to question the def of weakly pure.
> 
> -1- How can this even compile?
> 	pure append (ref int[] a, int i) {a ~= i;}
> The _only_ task of this func is to change state.

It's _weakly_ pure, not strongly pure. This pretty much just means that the 
function does not access global variables. No optimizations can be done to it. 
It's purely so that strongly pure (or other weakly pure) functions can legally 
call it. If it's a strongly pure function calling it, then not only do you know 
that global state can't be affected, but because all of the function's parameters 
are immutable (or full-on copies of mutable data in the case where it's a type 
implicitly convertible to/from immutable).

Weakly pure functions are _not_ pure in the functional sense at all. Only 
strongly pure functions are.

> -2- Why is output writing considered an impure task? It has no influence on
> the rest/future of the program, lets reasoning easy, does not touch state.
> 
> I would like weakly pure to include output funcs, and exclude all
> possibilities to modify (non-local) state.

The problem is that output is accessing global variables - which weakly pure 
functions _cannot_ do. If you call a weakly pure function from a strongly pure 
function, it's still guranteed that the result of the strongly pure function 
will be the same and have _no_ side effects - that is, it effectively has the 
functional definition of purity. However, if you allowed I/O, you then have a 
side effect, and two calls to a particular strongly pure function could differ, 
and yet the optimizer would then only do one call, thereby changing the results 
of the program. Optimizing out calls pure functions should _never_ change the 
results of a program. Allowing output in weakly pure functions would allow that.

Now, there is arguably some need for the ability to have _debug_ functions for 
printing in pure functions (be they weakly pure or strongly pure), but they'd 
likely be used in cases where pure optimizations were not used (since you 
wouldn't be using -O for debugging), and if they were used, the programmer would 
effectively be saying that they were okay with the I/O not necessarily occuring 
every time that a function call occured in the code (since the call could be 
optimized out). That is _not_ acceptible for general I/O.

I/O breaks purity. The way to get around it is to use monads, but that would 
affect the signatures of every single function in the chain of function calls 
which included the I/O. So, you wouldn't normally want to do that.

- Jonathan M Davis


More information about the Digitalmars-d mailing list