On Thursday, 15 May 2014 at 09:23:00 UTC, Jonathan M Davis via Digitalmars-d wrote:
functions that weren't pure. It allowed for mutation within the function, and it allowed for allocation via new, but from the outside, the function _was_
functionally pure.

If it didn't return the memory allocated with new and if the call to new resulted in an exception, yes.

It just didn't work.

That I question. A pure function ( http://en.wikipedia.org/wiki/Pure_function ) depends on the values of the parameters, and only that. That is most useful. Those value can be very complex. You could have a pure member function look up values in a cache. Then the configuration of entire cache is the value.

You need to think about this in terms of pre/post conditions in Hoare Logic (which I am not very good at btw).


So, Don introduced the idea of "weak" purity. What it comes down to is that it's an extension of the concept that mutation within a pure function is fine just so long as its arguments aren't mutated. We made it so that pure functions _didn't_ have to have immutable parameters. They just couldn't access anything that wasn't passed to them as arguments. This meant that they could only mutate what they were given and thus they didn't violate the "strong" purity of the original pure function which had immutable parameters.

And that's fine as long as nobody else is holding a reference to those mutable parameters. That means that you are taking version N of the mutable and returning version N+1. That's similar to

x=1
a =f(x)
x=x+1
b = f(x)

which can be rewritten as:

x0 =1
a = f(x0)
x1 = x0+1
b = f(x1)

If you think in terms of a context for purity such as a transaction then you can even allow access to globals as long as they remain constant until the transaction is committed (or you leave the context where purity is desired). Meaning, you can memoize within that context.

functions that called it), but we do need that guarantee. The result is that the pure attribute doesn't in and of itself mean functional purity anymore, but it _can_ be used to build a function which is functionally pure.

But, that can be deduced by the compiler, so what is the point of having "pure" for "weakly pure"? Clearly you only need to specify "strongly pure"?

So, sorry that it offends your sensibilities that pure by itself does not indicate functional purity, but it's a building block for functional purity,

It doesn't offend me, but it is a source of confusion and not sticking to definitions makes the language design look random.

The same thing goes for lazy parameters. Why pick Call-By-Name (Algol style) over Call-By-Need (memoing)? Call-By-Name is known to be error prone.

Actually, lazy parameters should be restricted to pure expressions… if correctness and safety is the goal.

attribute for this. And even if pure _didn't_ enable functional purity, it would still be highly useful just from the fact that a pure function (be it weak or strong) cannot access global variables, and that makes it _much_ easier to reason about code, because you know that it isn't accessing anything
that wasn't passed to it.

Ok, but maybe the opposite would be better. Marking functions that access globals with @global or something. After all, most functions don't access globals.



Reply via email to