digitalmars.D - Char literals
- Eldar Insafutdinov (16/16) Nov 06 2009 I've just written a simple replicate function (the one from std.range do...
- Michal Minich (4/31) Nov 06 2009 no builtin type is immutable by default.
- Steven Schveighoffer (18/40) Nov 06 2009 a value type such as char makes no sense as an immutable entity. First ...
- Bill Baxter (18/34) Nov 06 2009 s not work in CTFE):
- Eldar Insafutdinov (2/36) Nov 06 2009 Yes you are right, I used cast(string) eventually and made it non-templa...
- Eldar Insafutdinov (2/36) Nov 06 2009 Yes you are right, I used cast(string) eventually and made it non-templa...
I've just written a simple replicate function (the one from std.range does not work in CTFE): T[] replicate(T)(int n, T value) { T[] ret; if (n > 0) { for(int i = 0; i < n; i++) ret ~= value; } return ret; } it's not the best implementation, but that's not the thing I want to say today. When I call it string str = replicate(5, 'a'); I get moc.d(370): Error: cannot implicitly convert expression (replicate(5,',')) of type char[] to string That means that char literals are "char", but not "immutable(char)". I remember the whole conversation about array literals, but char literals are closer to those of the string. What's the reasoning behind leaving them as mutable char?
Nov 06 2009
Hello Eldar,I've just written a simple replicate function (the one from std.range does not work in CTFE): T[] replicate(T)(int n, T value) { T[] ret; if (n > 0) { for(int i = 0; i < n; i++) ret ~= value; } return ret; } it's not the best implementation, but that's not the thing I want to say today. When I call it string str = replicate(5, 'a'); I get moc.d(370): Error: cannot implicitly convert expression (replicate(5,',')) of type char[] to string That means that char literals are "char", but not "immutable(char)". I remember the whole conversation about array literals, but char literals are closer to those of the string. What's the reasoning behind leaving them as mutable char?no builtin type is immutable by default. string is not builtin type, it is defined as "alias immutable(char)[] string;" in object.d file.
Nov 06 2009
On Fri, 06 Nov 2009 06:24:51 -0500, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:I've just written a simple replicate function (the one from std.range does not work in CTFE): T[] replicate(T)(int n, T value) { T[] ret; if (n > 0) { for(int i = 0; i < n; i++) ret ~= value; } return ret; } it's not the best implementation, but that's not the thing I want to say today. When I call it string str = replicate(5, 'a'); I get moc.d(370): Error: cannot implicitly convert expression (replicate(5,',')) of type char[] to string That means that char literals are "char", but not "immutable(char)". I remember the whole conversation about array literals, but char literals are closer to those of the string. What's the reasoning behind leaving them as mutable char?a value type such as char makes no sense as an immutable entity. First of all, an immutable char can be implicitly cast to and from a mutable char. Although it might seem incorrect, since it is a value type, assigning it to an immutable variable makes a copy anyways, so the mutability/immutability of the original variable stays intact. You bring up a legitimate concern. However, you are probably never going to see 'a' by itself typed as an immutable char, because mutable makes the most sense as the default constancy of a value type literal. It seems that string literals being typed as immutable(char)[] is an inconsistency in the world of D literals that always needs to be handled specially. What you probably want to have is a specialization for your template. Again, another use case for unique(T)... BTW, you can save a loop by doing this: T[] ret = new T[n]; ret[] = value; // assign value to all elements of ret -Steve
Nov 06 2009
On Fri, Nov 6, 2009 at 3:24 AM, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:I've just written a simple replicate function (the one from std.range doe=s not work in CTFE):T[] replicate(T)(int n, T value) { =A0 =A0T[] ret; =A0 =A0if (n > 0) =A0 =A0{ =A0 =A0 =A0 =A0for(int i =3D 0; i < n; i++) =A0 =A0 =A0 =A0 =A0 =A0ret ~=3D value; =A0 =A0} =A0 =A0return ret; } it's not the best implementation, but that's not the thing I want to say =today. When I call itstring str =3D replicate(5, 'a'); I get moc.d(370): Error: cannot implicitly convert expression (replicate(5,',')=) of type char[] to stringThat means that char literals are "char", but not "immutable(char)". I re=member the whole conversation about array literals, but char literals are c= loser to those of the string. What's the reasoning behind leaving them as m= utable char? In Phobos they use std.contracts.assumeUnique to turn char[] to string at the end of string processing functions. It's actually just a cast to immutable(char)[]. But the idea is you're asserting that you know the char[] data is not referenced by anyone else (your reference is unique) so it's safe to make it immutable. So it documents the intent better than a straight cast. It's also better because if you later change the underlying type say from char[] to dchar[], assumeUnique will still do the right thing (become a cast to immutable(dchar)[]), but cast(string) would silently become bogus. --bb
Nov 06 2009
Bill Baxter Wrote:On Fri, Nov 6, 2009 at 3:24 AM, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:Yes you are right, I used cast(string) eventually and made it non-template. There were other bugs that are specific to CTFE that I could not track down though.I've just written a simple replicate function (the one from std.range does not work in CTFE): T[] replicate(T)(int n, T value) { T[] ret; if (n > 0) { for(int i = 0; i < n; i++) ret ~= value; } return ret; } it's not the best implementation, but that's not the thing I want to say today. When I call it string str = replicate(5, 'a'); I get moc.d(370): Error: cannot implicitly convert expression (replicate(5,',')) of type char[] to string That means that char literals are "char", but not "immutable(char)". I remember the whole conversation about array literals, but char literals are closer to those of the string. What's the reasoning behind leaving them as mutable char?In Phobos they use std.contracts.assumeUnique to turn char[] to string at the end of string processing functions. It's actually just a cast to immutable(char)[]. But the idea is you're asserting that you know the char[] data is not referenced by anyone else (your reference is unique) so it's safe to make it immutable. So it documents the intent better than a straight cast. It's also better because if you later change the underlying type say from char[] to dchar[], assumeUnique will still do the right thing (become a cast to immutable(dchar)[]), but cast(string) would silently become bogus. --bb
Nov 06 2009
Bill Baxter Wrote:On Fri, Nov 6, 2009 at 3:24 AM, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:Yes you are right, I used cast(string) eventually and made it non-template. There were other bugs that are specific to CTFE that I could not track down though.I've just written a simple replicate function (the one from std.range does not work in CTFE): T[] replicate(T)(int n, T value) { T[] ret; if (n > 0) { for(int i = 0; i < n; i++) ret ~= value; } return ret; } it's not the best implementation, but that's not the thing I want to say today. When I call it string str = replicate(5, 'a'); I get moc.d(370): Error: cannot implicitly convert expression (replicate(5,',')) of type char[] to string That means that char literals are "char", but not "immutable(char)". I remember the whole conversation about array literals, but char literals are closer to those of the string. What's the reasoning behind leaving them as mutable char?In Phobos they use std.contracts.assumeUnique to turn char[] to string at the end of string processing functions. It's actually just a cast to immutable(char)[]. But the idea is you're asserting that you know the char[] data is not referenced by anyone else (your reference is unique) so it's safe to make it immutable. So it documents the intent better than a straight cast. It's also better because if you later change the underlying type say from char[] to dchar[], assumeUnique will still do the right thing (become a cast to immutable(dchar)[]), but cast(string) would silently become bogus. --bb
Nov 06 2009