Jump to page: 1 2
Thread overview
Implicit cast to immutable
Oct 05, 2011
bearophile
Oct 06, 2011
Andrej Mitrovic
Oct 06, 2011
bearophile
Oct 06, 2011
Christophe
Oct 06, 2011
bearophile
Oct 16, 2011
Daniel Murphy
Oct 18, 2011
Daniel Murphy
Oct 18, 2011
bearophile
Oct 18, 2011
Daniel Murphy
Oct 21, 2011
Christophe
Oct 27, 2011
Christophe
Oct 20, 2011
Daniel Murphy
October 05, 2011
Do you know why this program doesn't compile (with DMD 2.056head)?


immutable(int[]) foo(in int[] x) pure {
    return new int[1];
}
void main() {}


It gives:
test.d(2): Error: cannot implicitly convert expression (new int[](1u)) of type int[] to immutable(int[])

This program instead compiles (now x is int[2] instead of int[]):

immutable(int[]) foo(in int[2] x) pure {
    return new int[1];
}
void main() {}


Bye and thank you,
bearophile
October 06, 2011
Maybe:

immutable(int[]) foo(in int[] x) pure {
   return new immutable(int[1]);
}

void main() {}

Or does this have something to do with implicit casts to immutable for pure functions? I'm only vaguely familiar with pure..
October 06, 2011
Andrej Mitrovic:

> Maybe:
> 
> immutable(int[]) foo(in int[] x) pure {
>    return new immutable(int[1]);
> }
> 
> void main() {}

I'd like to know why the code in my original post doesn't compile. I suspect it's a DMD bug, but I am not sure.


> Or does this have something to do with implicit casts to immutable for pure functions?

Right.


> I'm only vaguely familiar with pure..

I suggest you to use purity more and more in D, because it helps and with the recent bug fixes it is also becoming usable in D (but there are some significant problems left, example: map/filter are not pure yet).

Bye and thank you,
bearophile
October 06, 2011
bearophile , dans le message (digitalmars.D.learn:29961), a écrit :
> Andrej Mitrovic:
> 
>> Maybe:
>> 
>> immutable(int[]) foo(in int[] x) pure {
>>    return new immutable(int[1]);
>> }
>> 
>> void main() {}
> 
> I'd like to know why the code in my original post doesn't compile. I suspect it's a DMD bug, but I am not sure.

The error message tells you why. new int[1] is not castable to immutable int[] (in a pure function). The solution is to change new int[1] to make it immutable directly. That is very consistent, so I don't think this should be considered as a bug. There may be an improvement to ask to make the compiler able to check when the cast to immutable is safe, but I don't think there is a bug.

>> Or does this have something to do with implicit casts to immutable for pure functions?
> 
> Right.
> 
> 
>> I'm only vaguely familiar with pure..
> 
> I suggest you to use purity more and more in D, because it helps and with the recent bug fixes it is also becoming usable in D (but there are some significant problems left, example: map/filter are not pure yet).

You would need to have pure delegates to have a real effect, wouldn't you ?

-- 
Christophe
October 06, 2011
Christophe:

> That is very consistent, so I don't think this should be considered as a bug. There may be an improvement to ask to make the compiler able to check when the cast to immutable is safe, but I don't think there is a bug.

The compiler already performs such checks, in this case it answers "no" and I don't understand why, I think it's not the right answer.


> You would need to have pure delegates to have a real effect, wouldn't you ?

The compiler is already able to infer delegate purity, I think.

Bye,
bearophile
October 06, 2011
On Wed, 05 Oct 2011 19:19:37 -0400, bearophile <bearophileHUGS@lycos.com> wrote:

> Do you know why this program doesn't compile (with DMD 2.056head)?
>
>
> immutable(int[]) foo(in int[] x) pure {
>     return new int[1];
> }
> void main() {}
>
>
> It gives:
> test.d(2): Error: cannot implicitly convert expression (new int[](1u)) of type int[] to immutable(int[])
>
> This program instead compiles (now x is int[2] instead of int[]):
>
> immutable(int[]) foo(in int[2] x) pure {
>     return new int[1];
> }
> void main() {}

I think it's a bug.

new should be considered pure, and since it's return value cannot be a reference to any parameter, it should implicitly cast to immutable.

The fact that changing the parameter to foo makes it compile is a big clue.

Note, this should compile even if foo isn't pure, since new is pure (no matter what type of function it is in).

-Steve
October 16, 2011
The implicit conversion to immutable is only possible inside strongly pure functions.  When the parameter is 'in int[]' foo cannot be strongly pure, only const pure.  As 'in int[2]' is a value type, the second foo can be strongly pure.

'new' expressions will hopefully be able to be converted to immutable eventually, along with array concatenation and array.dup.

It is also likely that the following will be valid code (const pure foo called with immutable arguments)

int[] foo(in int[] x) pure {
   return new int[1];
}

void main() {
  immutable x = foo([1, 2, 3].idup);
}

"bearophile" <bearophileHUGS@lycos.com> wrote in message news:j6iom9$2g1m$1@digitalmars.com...
> Do you know why this program doesn't compile (with DMD 2.056head)?
>
>
> immutable(int[]) foo(in int[] x) pure {
>    return new int[1];
> }
> void main() {}
>
>
> It gives:
> test.d(2): Error: cannot implicitly convert expression (new int[](1u)) of
> type int[] to immutable(int[])
>
> This program instead compiles (now x is int[2] instead of int[]):
>
> immutable(int[]) foo(in int[2] x) pure {
>    return new int[1];
> }
> void main() {}
>
>
> Bye and thank you,
> bearophile


October 17, 2011
On Sat, 15 Oct 2011 23:05:43 -0400, Daniel Murphy <yebblies@nospamgmail.com> wrote:

> The implicit conversion to immutable is only possible inside strongly pure
> functions.  When the parameter is 'in int[]' foo cannot be strongly pure,
> only const pure.  As 'in int[2]' is a value type, the second foo can be
> strongly pure.
>
> 'new' expressions will hopefully be able to be converted to immutable
> eventually, along with array concatenation and array.dup.
>
> It is also likely that the following will be valid code (const pure foo
> called with immutable arguments)
>
> int[] foo(in int[] x) pure {
>    return new int[1];
> }
>
> void main() {
>   immutable x = foo([1, 2, 3].idup);
> }

That sounds like an incorrect restriction.  The implicit cast to immutable should depend on whether the function being *called* qualifies, not if the function you are calling *from* qualifies.

Qualifying means the return type should be mutable, and cannot be derived from the parameters without requiring casts.  The easiest way to do this is to ensure the parameters are all const, immutable, or implicitly cast to immutable.  You could do funky things like assume for instance an int[] cannot possibly be implicit-casted to a char[], so therefore int[] foo(char[] data) pure can be implicitly casted to immutable, but that might be flirting with dangerous situations.

The one exception should be allocating memory, which should always qualify, even though it's not a pure function.

This should compile:

void main() {
   immutable x = foo([1, 2, 3]);
}

-Steve
October 18, 2011
"Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.v3h06olweav7ka@localhost.localdomain...
>
> That sounds like an incorrect restriction.  The implicit cast to immutable should depend on whether the function being *called* qualifies, not if the function you are calling *from* qualifies.
>

I think you've misunderstood what I'm saying.  The patch I made implemented two ways to implicly convert to immutable: the result of a pure function returning immutable and a return statement inside a pure function.

1)
int[] fun() { return new int[]; }
immutable x = fun(); // conversion happens here

2)
immutable(int[]) fun() { return new int[]; } // conversion happens here
immutable x  = fun();

Bearophile's example is of the second, where it definately matters what the purity of the function is.

> Qualifying means the return type should be mutable, and cannot be derived from the parameters without requiring casts.  The easiest way to do this is to ensure the parameters are all const, immutable, or implicitly cast to immutable.  You could do funky things like assume for instance an int[] cannot possibly be implicit-casted to a char[], so therefore int[] foo(char[] data) pure can be implicitly casted to immutable, but that might be flirting with dangerous situations.
>
> The one exception should be allocating memory, which should always qualify, even though it's not a pure function.
>

This is valid, but becomes very complicated with complex return types.  I doubt this will ever make it into the language.

I've got the beginnings of a patch to enable a sort of 'pure expression', such as new, array.dup and array concatenation expressions.  The result of a call to a const-pure function using immutable arguments can be converted to immutable, while calling it with mutable or const arguments cannot, without searching the return type for anything the arguments can implicitly convert to (or create).

Eg. I can't see a great way to detect situations like this:

struct S { const void* p; }
S[] fun(int[] arr)
{
    return [ S(arr.ptr) ];
}
immutable x = fun([1, 2, 3]);


October 18, 2011
Daniel Murphy:

> 2)
> immutable(int[]) fun() { return new int[]; } // conversion happens here
> immutable x  = fun();
> 
> Bearophile's example is of the second, where it definately matters what the purity of the function is.

This is the enhancement request I have written days ago: http://d.puremagic.com/issues/show_bug.cgi?id=6783

Bye,
bearophile
« First   ‹ Prev
1 2