Re: Implicit cast to immutable

2011-10-27 Thread Christophe
Steven Schveighoffer , dans le message (digitalmars.D.learn:30255), a
 écrit :
 On Fri, 21 Oct 2011 11:20:01 -0400, Christophe  
 trav...@phare.normalesup.org wrote:
 
 Daniel Murphy , dans le message (digitalmars.D.learn:30139), a écrit :
 bearophile bearophileh...@lycos.com wrote in message
 news:j7jepi$prp$1...@digitalmars.com...
 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

 Yes, and the problem in that report is that the function is const-pure,  
 not
 strong-pure.
 Without checking if the return type can contain a non-immutable  
 reference
 from the arguments, it is not safe to implicitly convert the result to
 immutable.

 eg.
 immutable(int[]) foo(in int[] x) { return x; }
 auto g = [1, 2, 3];
 auto a = foo(g.idup); //safe
 auto b = foo(g); // unsafe

 Checking at the call site is possible, but not from inside the function.

 int[] foo(in int[] x) { return new int[](3); }
 auto g = [1, 2, 3];
 immutable a = foo(g.idup); // safe
 immutable b = foo(g); // unsafe, and easily rejected

 In your example, it is safe as the argument is not returned.  Allowing  
 this
 in the general case requires checking (recursively) that the return type
 does not contain any types that any of the arguments can implicitly  
 convert
 to that are non-immutable.

 What is the rule ?
 
 The theoretical rule should be, if it can be proven (except for the case  
 where a cast is used) the result is not a subset of the input, then the  
 result can be implicitly cast to immutable.
 
 The actual rule may be more conservative, since it may be difficult to  
 prove it.

OK, it must be proven from the signature of the function alone, and not 
from the function body.

 The result of
 pure int[] foo(in int[] x);
 is castable to immutable, since elements of x are not supposed to escape
 the function.

 The result of
 pure int[] foo(const int[] x);
 is not, because the value return by foo may be elements of x.
 
 Only via cast.  How does foo legally change const int[] data to int[] data  
 without a cast?
 
 Note that the two functions you wrote are equivalent, since in translates  
 to const scope and scope does nothing to array parameters.
 

I meant:
pure const(int)[] foo(const/in int[] x);

But I thought scope was transitive like const, so it had effect on 
arrays. I find it pretty useless like that. A transitive scope could be 
very useful for purity checking and memory management optimisations. It 
would be useful for implicit casting to immutable too, even in no pure 
function. I may write about that later in another thread.


Re: Implicit cast to immutable

2011-10-24 Thread Steven Schveighoffer
On Fri, 21 Oct 2011 11:20:01 -0400, Christophe  
trav...@phare.normalesup.org wrote:



Daniel Murphy , dans le message (digitalmars.D.learn:30139), a écrit :

bearophile bearophileh...@lycos.com wrote in message
news:j7jepi$prp$1...@digitalmars.com...

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


Yes, and the problem in that report is that the function is const-pure,  
not

strong-pure.
Without checking if the return type can contain a non-immutable  
reference

from the arguments, it is not safe to implicitly convert the result to
immutable.

eg.
immutable(int[]) foo(in int[] x) { return x; }
auto g = [1, 2, 3];
auto a = foo(g.idup); //safe
auto b = foo(g); // unsafe

Checking at the call site is possible, but not from inside the function.

int[] foo(in int[] x) { return new int[](3); }
auto g = [1, 2, 3];
immutable a = foo(g.idup); // safe
immutable b = foo(g); // unsafe, and easily rejected

In your example, it is safe as the argument is not returned.  Allowing  
this

in the general case requires checking (recursively) that the return type
does not contain any types that any of the arguments can implicitly  
convert

to that are non-immutable.


What is the rule ?


The theoretical rule should be, if it can be proven (except for the case  
where a cast is used) the result is not a subset of the input, then the  
result can be implicitly cast to immutable.


The actual rule may be more conservative, since it may be difficult to  
prove it.



The result of
pure int[] foo(in int[] x);
is castable to immutable, since elements of x are not supposed to escape
the function.

The result of
pure int[] foo(const int[] x);
is not, because the value return by foo may be elements of x.


Only via cast.  How does foo legally change const int[] data to int[] data  
without a cast?


Note that the two functions you wrote are equivalent, since in translates  
to const scope and scope does nothing to array parameters.


-Steve


Re: Implicit cast to immutable

2011-10-21 Thread Christophe
Daniel Murphy , dans le message (digitalmars.D.learn:30139), a écrit :
 bearophile bearophileh...@lycos.com wrote in message 
 news:j7jepi$prp$1...@digitalmars.com...
 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
 
 Yes, and the problem in that report is that the function is const-pure, not 
 strong-pure.
 Without checking if the return type can contain a non-immutable reference 
 from the arguments, it is not safe to implicitly convert the result to 
 immutable.
 
 eg.
 immutable(int[]) foo(in int[] x) { return x; }
 auto g = [1, 2, 3];
 auto a = foo(g.idup); //safe
 auto b = foo(g); // unsafe
 
 Checking at the call site is possible, but not from inside the function.
 
 int[] foo(in int[] x) { return new int[](3); }
 auto g = [1, 2, 3];
 immutable a = foo(g.idup); // safe
 immutable b = foo(g); // unsafe, and easily rejected
 
 In your example, it is safe as the argument is not returned.  Allowing this 
 in the general case requires checking (recursively) that the return type 
 does not contain any types that any of the arguments can implicitly convert 
 to that are non-immutable. 

What is the rule ?
The result of a pure function can be cast to immutable if the arguments 
are immutable. That requires specific checking by the compiler. The real 
type of the argument prior to the conversion to the argument type has to 
be checked.

in, scope, or inout arguments are supposed to solve the problem with 
function site checking: without call-site checking, which are IMO a 
rather bad idea.

The result of
pure int[] foo(in int[] x);
is castable to immutable, since elements of x are not supposed to escape 
the function.

The result of
pure int[] foo(const int[] x);
is not, because the value return by foo may be elements of x.


Re: Implicit cast to immutable

2011-10-19 Thread Steven Schveighoffer

On Tue, 18 Oct 2011 02:40:12 -0400, Daniel Murphy
yebbl...@nospamgmail.com wrote:


Steven Schveighoffer schvei...@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();


Neither of those is relevant, since they do not contain parameters (I'm  
assuming you meant them both to be pure).


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.


No, it's not complicated, at least in my view.  The rules are:

1. if the pure function parameters are only immutable or
implicitly-convertible-to-immutable, the result is safe to cast to
immutable, regardless of what happens inside the function, or the type of
the result.
2. if the pure function parameters contain any mutable data that is
mutable and *not* implicitly convertible to mutable, and the result is
only safe to cast to immutable if it can already implicitly cast to
immutable.
3. if the pure function parameters are implicitly castible to immutable,
immutable, or are const, then:
  a) if the return type is implicitly castable to immutable, obviously
it can be cast.
  b) if the return type is not implicitly castable to immutable, but
contains only mutable references, then it's implicitly castable to
immutable.
  c) otherwise, it cannot be implicitly cast.

You do not need the function body to determine this, and the decision
should be made by the compiler at the call site.

Your case 2 where the conversion happens at the return statement is
already covered.


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; }


This struct could only be cast to immutable under my rule 1 above.  It
does not implicitly cast to immutable.


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


Invalid.  arr is not implicitly castable to immutable and is mutable, so
the result must already be implicitly castable (which it is not).  This
falls under rule 2 above, and fails the test.

-Steve


Re: Implicit cast to immutable

2011-10-19 Thread Daniel Murphy

Steven Schveighoffer schvei...@yahoo.com wrote in message 
news:op.v3lug2q2eav7ka@localhost.localdomain...
 On Tue, 18 Oct 2011 02:40:12 -0400, Daniel Murphy
 yebbl...@nospamgmail.com wrote:

 Steven Schveighoffer schvei...@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();

 Neither of those is relevant, since they do not contain parameters (I'm 
 assuming you meant them both to be pure).


Yeah, they were supposed to be pure.  I was just demonstrating that 
conversion happens at the return statement, or the call site, but only 
currently for strongly pure functions.

 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.

 No, it's not complicated, at least in my view.  The rules are:

 1. if the pure function parameters are only immutable or
 implicitly-convertible-to-immutable, the result is safe to cast to
 immutable, regardless of what happens inside the function, or the type of
 the result.
 2. if the pure function parameters contain any mutable data that is
 mutable and *not* implicitly convertible to mutable, and the result is
 only safe to cast to immutable if it can already implicitly cast to
 immutable.
 3. if the pure function parameters are implicitly castible to immutable,
 immutable, or are const, then:
   a) if the return type is implicitly castable to immutable, obviously
 it can be cast.
   b) if the return type is not implicitly castable to immutable, but
 contains only mutable references, then it's implicitly castable to
 immutable.
   c) otherwise, it cannot be implicitly cast.

 You do not need the function body to determine this, and the decision
 should be made by the compiler at the call site.

 Your case 2 where the conversion happens at the return statement is
 already covered.

 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; }

 This struct could only be cast to immutable under my rule 1 above.  It
 does not implicitly cast to immutable.

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

 Invalid.  arr is not implicitly castable to immutable and is mutable, so
 the result must already be implicitly castable (which it is not).  This
 falls under rule 2 above, and fails the test.

 -Steve

Ok, I think I meant to make fun pure and fun's parameter 'in', so it would 
fall under rule 3 but be rejected by 3b as it contains a const member.

It's not always simple to determine if an aggregate contains non-mutable 
members.  An example would be a class when you only have a base class 
reference.
Another problem (which we're already seeing with the existing conversions) 
is that when you screw it up the conversion fails, but doesn't give you any 
hint as to why it failed.  Making the rules more complicated is just going 
to make this worse. 




Re: Implicit cast to immutable

2011-10-19 Thread Steven Schveighoffer
On Wed, 19 Oct 2011 21:39:47 -0400, Daniel Murphy  
yebbl...@nospamgmail.com wrote:




Steven Schveighoffer schvei...@yahoo.com wrote in message
news:op.v3lug2q2eav7ka@localhost.localdomain...

On Tue, 18 Oct 2011 02:40:12 -0400, Daniel Murphy
yebbl...@nospamgmail.com wrote:


Steven Schveighoffer schvei...@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();


Neither of those is relevant, since they do not contain parameters (I'm
assuming you meant them both to be pure).



Yeah, they were supposed to be pure.  I was just demonstrating that
conversion happens at the return statement, or the call site, but only
currently for strongly pure functions.


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.


No, it's not complicated, at least in my view.  The rules are:

1. if the pure function parameters are only immutable or
implicitly-convertible-to-immutable, the result is safe to cast to
immutable, regardless of what happens inside the function, or the type  
of

the result.
2. if the pure function parameters contain any mutable data that is
mutable and *not* implicitly convertible to mutable, and the result is
only safe to cast to immutable if it can already implicitly cast to
immutable.
3. if the pure function parameters are implicitly castible to immutable,
immutable, or are const, then:
  a) if the return type is implicitly castable to immutable,  
obviously

it can be cast.
  b) if the return type is not implicitly castable to immutable, but
contains only mutable references, then it's implicitly castable to
immutable.
  c) otherwise, it cannot be implicitly cast.

You do not need the function body to determine this, and the decision
should be made by the compiler at the call site.

Your case 2 where the conversion happens at the return statement is
already covered.

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; }


This struct could only be cast to immutable under my rule 1 above.  It
does not implicitly cast to immutable.


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


Invalid.  arr is not implicitly castable to immutable and is mutable, so
the result must already be implicitly castable (which it is not).  This
falls under rule 2 above, and fails the test.

-Steve


Ok, I think I meant to make fun pure and fun's parameter 'in', so it  
would

fall under rule 3 but be rejected by 3b as it contains a const member.

It's not always simple to determine if an aggregate contains non-mutable
members.  An example would be a class when you only have a base class
reference.


I had not thought about classes (or interfaces), I was only thinking of  
concrete types.  I think in the case of classes, all parameters with  
classes must be marked as immutable to have an implicit cast of the result  
to immutable (i.e. fall under rule 1).  In reality, the rules I specify  
are enough, but they simply aren't explicit about how classes make it  
impossible to determine if any const members are aboard.


The same goes for void *, which could point to a type which has const  
members.


All cases where classes or void * pointers are involved must fall under  
rule 1, since you cannot determine whether such types are transitively  
mutable.


Another problem (which 

Re: Implicit cast to immutable

2011-10-18 Thread Daniel Murphy
Steven Schveighoffer schvei...@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]); 




Re: Implicit cast to immutable

2011-10-18 Thread bearophile
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


Re: Implicit cast to immutable

2011-10-18 Thread Daniel Murphy
bearophile bearophileh...@lycos.com wrote in message 
news:j7jepi$prp$1...@digitalmars.com...
 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

Yes, and the problem in that report is that the function is const-pure, not 
strong-pure.
Without checking if the return type can contain a non-immutable reference 
from the arguments, it is not safe to implicitly convert the result to 
immutable.

eg.
immutable(int[]) foo(in int[] x) { return x; }
auto g = [1, 2, 3];
auto a = foo(g.idup); //safe
auto b = foo(g); // unsafe

Checking at the call site is possible, but not from inside the function.

int[] foo(in int[] x) { return new int[](3); }
auto g = [1, 2, 3];
immutable a = foo(g.idup); // safe
immutable b = foo(g); // unsafe, and easily rejected

In your example, it is safe as the argument is not returned.  Allowing this 
in the general case requires checking (recursively) that the return type 
does not contain any types that any of the arguments can implicitly convert 
to that are non-immutable. 




Re: Implicit cast to immutable

2011-10-17 Thread Steven Schveighoffer
On Sat, 15 Oct 2011 23:05:43 -0400, Daniel Murphy  
yebbl...@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


Re: Implicit cast to immutable

2011-10-15 Thread Daniel Murphy
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 bearophileh...@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 




Re: Implicit cast to immutable

2011-10-06 Thread Christophe
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


Re: Implicit cast to immutable

2011-10-06 Thread bearophile
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


Re: Implicit cast to immutable

2011-10-06 Thread Steven Schveighoffer
On Wed, 05 Oct 2011 19:19:37 -0400, bearophile bearophileh...@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


Re: Implicit cast to immutable

2011-10-05 Thread Andrej Mitrovic
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..


Re: Implicit cast to immutable

2011-10-05 Thread bearophile
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