Re: Why doesn't this work in D2?

2010-06-28 Thread Jacob Carlborg

On 2010-06-28 02:28, BCS wrote:

Hello Jacob,


That's annoying, specially since char is a value type. I would
preferably have a solution for both D1 and D2. Can I use a template to
cast/alias away the immutable part?


One solution would be to have templates strip off const/immutable from
the top level of args.

void F1(T)(T t) { pragam(msg,typeof(t).stringof); }

string s1;
immutable(char[]) s2
char[] s3

F1(s1); // immutable(char)[] // all as normal
F1(s2); // immutable(char)[] // making a mutable copy of a immutable
value is OK
F1(s3); // char[] // all as normal

void F2(T)(immutable T t) { pragam(msg,typeof(t).stringof); }

F2(s1); // immutable(char[]) // making an immutable copy of a mutable
reference to immutable data is ok
F2(s2); // immutable(char[]) // all as normal
F2(s3); // error, invalid conversion

This solution would match the proposal that popped up a while ago to
allow value assignment from const/immutable to mutable.


I don't think I understand what you're showing here. How would I strip 
off the const/immutable with a template ?


--
/Jacob Carlborg


Re: Why doesn't this work in D2?

2010-06-28 Thread Philippe Sigaud
On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com wrote:

Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 / UTF-32
is managed was changed. asd is an array of immutable(dchar), not
imutable(char). At least DMD tells me that its element type is 'dchar'.

So your function can be done this way in D2:

void foo(T,U)(in T[] a, U b) if (is(U : Unqual!T)) // that compiles only if
b can be cast to A
{
writeln(a,b);
}

asd.foo('s'); // prints asds.

is(U == Unqual!T) does not work, for U is 'char' while Unqual!T is 'dchar'.

More generally, using ranges and not arrays, the template becomes a bit more
heavy:

void foo(Range,Elem)(in Range range, Elem elem)
if (isInputRange!Range  is(Elem : Unqual!(ElementType!Range)))
{
...
}


I don't think I understand what you're showing here. How would I strip off
 the const/immutable with a template ?


Hmmm...
* plays with is expressions *

This seems to work:

template UnConst(T)
{
static if (is(T t == const U, U)) // that is:  'if T is a 'const U', for
some U'
alias U UnConst;  // then give me the U, (ie, T
without a const)
else
alias T UnConst;  // else give me the (original)
T
}

template UnImmutable(T)
{
static if (is(T t == immutable U, U)) // 'if T is an 'immutable U', for
some U'
alias U UnImmutable;
else
alias T UnImmutable;
}

test:

void main() {
alias const int Int;
writeln(UnConst!Int.stringof);
writeln(Int.stringof);
writeln(UnConst!int.stringof);
writeln(UnConst!(const int).stringof);
writeln(UnConst!(immutable int).stringof);

alias immutable int IInt;
writeln(UnConst!IInt.stringof);
writeln(IInt.stringof);
writeln(UnImmutable!int.stringof);
writeln(UnImmutable!(const int).stringof);
writeln(UnImmutable!(immutable int).stringof);
}

Philippe


Re: Why doesn't this work in D2?

2010-06-28 Thread Steven Schveighoffer
On Mon, 28 Jun 2010 08:14:12 -0400, Philippe Sigaud  
philippe.sig...@gmail.com wrote:



On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com wrote:

Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 /  
UTF-32

is managed was changed. asd is an array of immutable(dchar), not
imutable(char). At least DMD tells me that its element type is 'dchar'.


No, that is not true.  It's still an array of immutable(char).  The  
compiler still sees it as an array of immutable(char).  However, std.range  
forces the element type of char[] and wchar[] to be bidirectional ranges  
of dchar.  The tests such as isRandomAccessRange and ElementType are  
fudged to say string is *not* a random access range, and its element type  
is dchar.  This was one of Andrei's changes because without such  
shoehorning, std.algorithm could possible start shearing off strings that  
weren't valid.


Whether that was the right decision remains to be seen.  I personally  
would rather have special ranges that do those things.  If I have a string  
that's always in English, why do I need to generate the dchars based on  
the characters in that array?


-Steve


Re: Why doesn't this work in D2?

2010-06-28 Thread Jacob Carlborg

On 2010-06-28 14:14, Philippe Sigaud wrote:

On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com
mailto:d...@me.com wrote:

Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 /
UTF-32 is managed was changed. asd is an array of immutable(dchar),
not imutable(char). At least DMD tells me that its element type is 'dchar'.

So your function can be done this way in D2:

void foo(T,U)(in T[] a, U b) if (is(U : Unqual!T)) // that compiles only
if b can be cast to A
{
 writeln(a,b);
}

asd.foo('s'); // prints asds.

is(U == Unqual!T) does not work, for U is 'char' while Unqual!T is 'dchar'.

More generally, using ranges and not arrays, the template becomes a bit
more heavy:

void foo(Range,Elem)(in Range range, Elem elem)
if (isInputRange!Range  is(Elem : Unqual!(ElementType!Range)))
{
...
}


I don't think I understand what you're showing here. How would I
strip off the const/immutable with a template ?


Hmmm...
* plays with is expressions *

This seems to work:

template UnConst(T)
{
 static if (is(T t == const U, U)) // that is: 'if T is a 'const U',
for some U'
 alias U UnConst;  // then give me the U,
(ie, T without a const)
 else
 alias T UnConst;  // else give me the
(original) T
}

template UnImmutable(T)
{
 static if (is(T t == immutable U, U)) // 'if T is an 'immutable U',
for some U'
 alias U UnImmutable;
 else
 alias T UnImmutable;
}

test:

void main() {
 alias const int Int;
 writeln(UnConst!Int.stringof);
 writeln(Int.stringof);
 writeln(UnConst!int.stringof);
 writeln(UnConst!(const int).stringof);
 writeln(UnConst!(immutable int).stringof);

 alias immutable int IInt;
 writeln(UnConst!IInt.stringof);
 writeln(IInt.stringof);
 writeln(UnImmutable!int.stringof);
 writeln(UnImmutable!(const int).stringof);
 writeln(UnImmutable!(immutable int).stringof);
}

Philippe


Hmm, now I don't know what I'm doing, I thought you could do something 
like this:


template Char (T)
{
alias T Char;
}

void foo (T) (Char!(T) b)
{

}

void main ()
{
foo('s');
}


--
/Jacob Carlborg


Re: Why doesn't this work in D2?

2010-06-28 Thread BCS

Hello Jacob,


On 2010-06-28 02:28, BCS wrote:


One solution would be to have templates strip off const/immutable
from the top level of args.


[...]

This solution would match the proposal that popped up a while ago to
allow value assignment from const/immutable to mutable.


I don't think I understand what you're showing here. How would I strip
off the const/immutable with a template ?



I was proposing a language change Sorry for any confusion. The idea is that 
unless the user ask for it explicitly, there is no particular reason to preserve 
const/immutable for the value portion (true value types and the first level 
of references/pointers) of arguments.


--
... IXOYE





Re: Why doesn't this work in D2?

2010-06-28 Thread Philippe Sigaud
On Mon, Jun 28, 2010 at 14:35, Steven Schveighoffer schvei...@yahoo.comwrote:

 On Mon, 28 Jun 2010 08:14:12 -0400, Philippe Sigaud 
 philippe.sig...@gmail.com wrote:

  On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com wrote:

 Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 /
 UTF-32
 is managed was changed. asd is an array of immutable(dchar), not
 imutable(char). At least DMD tells me that its element type is 'dchar'.


 No, that is not true.  It's still an array of immutable(char).  The
 compiler still sees it as an array of immutable(char).  However, std.range
 forces the element type of char[] and wchar[] to be bidirectional ranges of
 dchar.  The tests such as isRandomAccessRange and ElementType are fudged to
 say string is *not* a random access range, and its element type is dchar.
  This was one of Andrei's changes because without such shoehorning,
 std.algorithm could possible start shearing off strings that weren't valid.



Ah yes, indeed, you're right.



 Whether that was the right decision remains to be seen.  I personally would
 rather have special ranges that do those things.  If I have a string that's
 always in English, why do I need to generate the dchars based on the
 characters in that array?


All that I can say is that it instantly broke dozens of unit tests in my
projects, which were using strings a simple random-access ranges. It took me
2 DMD releases to work my way uout of it.

Maybe I should have a look at byCodeUnit or somesuch. But for clueless users
like me, strings suddenly became much more complicated to use. Maybe I was
using them in unsafe ways, I don't know. I just hope for a way to get my
simple strings back.


Re: Why doesn't this work in D2?

2010-06-28 Thread Jacob Carlborg

On 2010-06-28 15:48, BCS wrote:

Hello Jacob,


On 2010-06-28 02:28, BCS wrote:


One solution would be to have templates strip off const/immutable
from the top level of args.


[...]

This solution would match the proposal that popped up a while ago to
allow value assignment from const/immutable to mutable.


I don't think I understand what you're showing here. How would I strip
off the const/immutable with a template ?



I was proposing a language change Sorry for any confusion. The idea is
that unless the user ask for it explicitly, there is no particular
reason to preserve const/immutable for the value portion (true value
types and the first level of references/pointers) of arguments.


Ok, now I understand.


--
/Jacob Carlborg


Why doesn't this work in D2?

2010-06-27 Thread Jacob Carlborg

Why doesn't the following code work in D2 (it works in D1)?

void foo (T) (in T[] a, T b)
{

}

void main ()
{
asd.foo('s');
}

The error I get is:

main.d(10): Error: template main.foo(T) does not match any function 
template declaration
main.d(10): Error: template main.foo(T) cannot deduce template function 
from argument types !()(string,char)


It seems to be some problem with the b argument, if I change that to 
char it works.


--
/Jacob Carlborg


Re: Why doesn't this work in D2?

2010-06-27 Thread Ellery Newcomer

On 06/27/2010 12:18 PM, Jacob Carlborg wrote:

Why doesn't the following code work in D2 (it works in D1)?

void foo (T) (in T[] a, T b)
{

}

void main ()
{
asd.foo('s');
}



asd.foo(cast(immutable) 's');



Re: Why doesn't this work in D2?

2010-06-27 Thread Simen kjaeraas

Jacob Carlborg d...@me.com wrote:


Why doesn't the following code work in D2 (it works in D1)?

void foo (T) (in T[] a, T b)
{

}

void main ()
{
asd.foo('s');
}

The error I get is:

main.d(10): Error: template main.foo(T) does not match any function  
template declaration
main.d(10): Error: template main.foo(T) cannot deduce template function  
from argument types !()(string,char)


It seems to be some problem with the b argument, if I change that to  
char it works.


In D2, strings are of type immutable(char)[], so your T would be
immutable(char). However, 's' is a simple, unadorned char.

Ways to fix this would include:

void foo(T)(const T[] a, const T b){
...
}

void foo(T,U)(const T[] a, U b) if (is(Unqual!T == Unqual!U)) {
...
}

--
Simen


Re: Why doesn't this work in D2?

2010-06-27 Thread Jacob Carlborg

On 2010-06-27 19:26, Simen kjaeraas wrote:

Jacob Carlborg d...@me.com wrote:


Why doesn't the following code work in D2 (it works in D1)?

void foo (T) (in T[] a, T b)
{

}

void main ()
{
asd.foo('s');
}

The error I get is:

main.d(10): Error: template main.foo(T) does not match any function
template declaration
main.d(10): Error: template main.foo(T) cannot deduce template
function from argument types !()(string,char)

It seems to be some problem with the b argument, if I change that to
char it works.


In D2, strings are of type immutable(char)[], so your T would be
immutable(char). However, 's' is a simple, unadorned char.

Ways to fix this would include:

void foo(T)(const T[] a, const T b){
...
}

void foo(T,U)(const T[] a, U b) if (is(Unqual!T == Unqual!U)) {
...
}


That's annoying, specially since char is a value type. I would 
preferably have a solution for both D1 and D2. Can I use a template to 
cast/alias away the immutable part?



--
/Jacob Carlborg


Re: Why doesn't this work in D2?

2010-06-27 Thread BCS

Hello Jacob,


That's annoying, specially since char is a value type. I would
preferably have a solution for both D1 and D2. Can I use a template to
cast/alias away the immutable part?


One solution would be to have templates strip off const/immutable from the 
top level of args.


void F1(T)(T t) { pragam(msg,typeof(t).stringof); }

string s1;
immutable(char[]) s2
char[] s3

F1(s1); // immutable(char)[] // all as normal
F1(s2); // immutable(char)[] // making a mutable copy of a immutable value 
is OK

F1(s3); // char[] // all as normal

void F2(T)(immutable T t) { pragam(msg,typeof(t).stringof); }

F2(s1); // immutable(char[]) // making an immutable copy of a mutable reference 
to immutable data is ok

F2(s2); // immutable(char[]) // all as normal
F2(s3); // error, invalid conversion

This solution would match the proposal that popped up a while ago to allow 
value assignment from const/immutable to mutable. 


--
... IXOYE