Memory allocation purity

via Digitalmars-d digitalmars-d at puremagic.com
Thu May 15 03:10:57 PDT 2014


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.





More information about the Digitalmars-d mailing list