Using pure to create immutable

Jonathan M Davis jmdavisProg at gmx.com
Thu Sep 22 14:03:08 PDT 2011


On Thursday, September 22, 2011 13:25 Steven Schveighoffer wrote:
> On Thu, 22 Sep 2011 16:15:20 -0400, Jonathan M Davis <jmdavisProg at gmx.com>
> 
> wrote:
> > On Thursday, September 22, 2011 16:09:29 Steven Schveighoffer wrote:
> >> Technically, something like this could be cast to immutable:
> >> 
> >> T[] foo(const(T)[] arg) pure
> >> 
> >> Since it can be proven that the result is new data.
> >> 
> >> So it doesn't *need* to be strong-pure.
> > 
> > Yes, you can always cast to immutable
> 
> I meant implicitly cast, sorry. I should be able to do this:
> 
> T[] foo(const(T)[] arg) pure {...}
> 
> immutable x = foo(y);
> 
> > but unless the compiler can _prove_
> > that the return value can be safely cast to immutable, it won't do it
> > implicitly, and the function needs to be strongly pure to do that.
> 
> It doesn't. In fact, the result of a strongly-pure function *cannot* be
> cast away from immutable implicitly:

Casting away immutability was never the issue. I don't believe that that can 
_ever_ be done implicitly, regardless of purity. It's casting _to_ immutable 
that's the issue.

> immutable(int)[] strongpure(immutable(int)[] arg) pure { return arg[0..5];}
> 
> immutable(int)[] y = [1,2,3,4,5,6,7,8,9];
> int[] x = strongpure(y); // error!
> 
> This function is not strong pure:
> 
> int[] weakpure(immutable(int)[] arg) pure {...}
> 
> because it cannot be optimized away. Subsequent calls to weakpure do
> *not* return the same value, each one returns a new piece of data.
> 
> Yet because we know it returns a new piece of data, the result should be
> implicitly castable to immutable:
> 
> immutable(int)[] y = [1,2,3,4,5,6,7,8,9];
> immutable(int)[] x = weakpure(y); // should be fine

Okay. I think that the problem here is that everything that I've been saying 
has everything to do with the parameters and arguments and _nothing_ to do 
with the return value. You make a valid point in your other post that a 
function returning a mutable value can't be considered strongly pure. However, 
if you ignore the return value in what I was saying about strongly pure 
before, everything holds for being able to implicitly cast to immutable. The 
issue is that a function which returns a mutable value can't quite be strongly 
pure, which I misjudged, so terming them strongly pure as I was is incorrect. 
However, I would point out that a function which returns a const value can 
still be strongly pure as long as all of its parameters are all immutable or 
implicitly convertible to immutable, since then the compiler can guarantee 
that the return value can't be changed without subverting the type system.

In any case, in order for a function to be able to have its return value 
implicitly value implicitly cast to immutable, it must pure and all of its 
arguments must be immutable or implicitly convertible to immutable (or - if 
the compiler is ever improved to treat pure functions with const parameters 
and immutable arguments the same way - the requirement would be that the 
function must be pure and all of its _arguments_ must be immutable or 
implicitly convertible to immutable). So, we have a new distinguish to make 
with regards to purity - whether the return value can be implicitly cast to 
immutable or not - and we don't have a name for that. And unlike strong purity 
vs weak purity, programmers actually have to understand the distinction if 
they're going to take advantage of it.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list