On Thursday, September 22, 2011 16:11:05 Steven Schveighoffer wrote: > On Thu, 22 Sep 2011 16:09:29 -0400, Steven Schveighoffer > > <[email protected]> wrote: > > On Thu, 22 Sep 2011 15:44:21 -0400, Jonathan M Davis > > > > <[email protected]> wrote: > >> On Thursday, September 22, 2011 23:36:40 Dmitry Olshansky wrote: > >>> On 22.09.2011 22:53, Jesse Phillips wrote: > >>> > The discussion on Reddit brought to my attention that pure > >>> > functions > >>> > >>> can > >>> > >>> > return and assign to an immutable. > >>> > >>> http://www.reddit.com/r/programming/comments/knn5p/thoughts_on_immut > >>> abil>>> > >>> > ity_in_d/c2lsgek > >>> > > >>> > I am trying to modify the example request to make use of this, > >>> > but > >>> > >>> have > >>> > >>> > failed. > >>> > >>> http://www.reddit.com/r/programming/comments/knn5p/thoughts_on_immut > >>> abil>>> > >>> > ity_in_d/c2lrfpm > >>> > > >>> > test.d(4): Error: cannot implicitly convert expression > >>> > (makeFromArray([1,2,3])) of type test.List!(int).List to > >>> > immutable(List) > >>> > > >>> > Is this a bug? I can't identify where this issue would lie > >>> > (works > >>> > >>> with > >>> > >>> > inheritance and templating). > >>> > >>> Maybe: > >>> -------------------------<<<<<<<<<< > >>> > >>> List!T makeFromArray(T)(immutable T[] array) pure { > >>> > >>> > if (array.length == 0) { return null; } > >>> > > >>> > auto result = new Cons!T(array[0], null); > >>> > auto end = result; > >>> > > >>> > for (int i = 1; i< array.length; ++i) { > >>> > > >>> > end.tail_ = new Cons!T(array[i], null); > >>> > end = end.tail_; > >>> > > >>> > } > >>> > > >>> > return result; > >>> > > >>> > } > >>> > >>> If I'm not mistaken only strongly pure functions are working.h > >> > >> Which would make sense. The only reason that it can implicitly cast to > >> immutable is because it _knows_ that there are no other mutable > >> references to > >> that data, and for it to be able to know that, the function must be > >> strongly > >> pure. > > > > 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. > > And actually, just making the argument immutable doesn't make it > strong-pure, the result has to be too. > > So I don't think it has to do with strong-purity at all.
??? Functions are pure, not variables or return values. The entire reason that the compiler can implicitly cast the return value to immutable is because it _knows_ that there are no mutable references to that data, and it can only make that guarantee if the function is strongly pure. So, if a function is strongly pure, the implicit cast to immutable can be made, and if it's not, then it can't be. For a function to be strongly pure, it cannot access any globally mutable state, all functions that it calls must be pure, and all of its parameters must either be immutable or implicitly convertible to immutable (so that the complire can guarantee that they'll never change). So, it's guaranteed that the return value of a strongly pure function is either immutable or it was allocated within that strongly pure function (or within a function that it called) and that there are no other references to that data, so then it's guaranteed that the return value can be safely cast to immutable. const doesn't enter into it (unless the compiler is improved to consider a pure function with const parameters strongly pure when it's passed immutable arguments), and there is no concept of the return value being pure or not. So, I'm not quite sure what you're thinking here. - Jonathan M Davis
