digitalmars.D - string and char[]
- Morlan <home valentimex.com> Apr 08 2011
- "Simen kjaeraas" <simen.kjaras gmail.com> Apr 08 2011
- simendsjo <simen.endsjo pandavre.com> Apr 08 2011
- Morlan <home valentimex.com> Apr 08 2011
- Morlan <home valentimex.com> Apr 08 2011
- spir <denis.spir gmail.com> Apr 08 2011
- spir <denis.spir gmail.com> Apr 08 2011
- spir <denis.spir gmail.com> Apr 08 2011
- "Simen kjaeraas" <simen.kjaras gmail.com> Apr 08 2011
- "Simen kjaeraas" <simen.kjaras gmail.com> Apr 08 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Apr 08 2011
- "Denis Koroskin" <2korden gmail.com> Apr 08 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Apr 08 2011
- Jesse Phillips <jessekphillips+d gmail.com> Apr 08 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Apr 08 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Apr 08 2011
It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
Apr 08 2011
On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array. -- Simen
Apr 08 2011
It is a mistake to use non-immutable keys for an associative array.
But a string literal isn't mutable..?
Apr 08 2011
int[char[]] is consistently used D's Language reference to illustrate associative arrays. For me it looks like something that should not compile. Of course int[string] works without problem so I wonder why int[char[]] was used as an example. Was it carried over from D1 reference perhaps?
Apr 08 2011
Of course, by saying it should not compile I mean things like asr["hello"] should not compile.
Apr 08 2011
On 04/08/2011 03:13 PM, Steven Schveighoffer wrote:On Fri, 08 Apr 2011 06:44:42 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array.
int[char[]] asr; pragma(msg, typeof(asr).stringof); outputs: AssociativeArray!(const(char)[],int) So the compiler adds const to the keys, which is why it works. Do I think this is the correct behavior? Absolutely not. First, it prevents nothing as far as modifying keys (const accepts mutable keys as well as const and mutable ones). Second, I believe you should be able to use whatever key constancy you want. We should just say if you do the wrong thing, it's undefined. Maybe safe code can only use immutable keys. Third, if it must be illegal to have an AA with mutable keys, it should be an error, not silently change to const.
I agree on points 1 & 3. "Second" looks dangerous to me. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 08 2011
On 04/08/2011 03:40 PM, Denis Koroskin wrote:What about storing objects as keys? There is nothing wrong to modify those objects as long as their order stays the same.
I think if referenced objects are to be used as keys, they should be compared by pointer/identity (hash would return their address?). Then, it's up to the programmer to be coherent. After all, that is the sense of "reference" isn't it? Denis -- _________________ vita es estrany spir.wikidot.com
Apr 08 2011
On 04/08/2011 09:20 PM, Steven Schveighoffer wrote:On Fri, 08 Apr 2011 14:57:52 -0400, spir <denis.spir gmail.com> wrote:On 04/08/2011 03:13 PM, Steven Schveighoffer wrote:On Fri, 08 Apr 2011 06:44:42 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array.
int[char[]] asr; pragma(msg, typeof(asr).stringof); outputs: AssociativeArray!(const(char)[],int) So the compiler adds const to the keys, which is why it works. Do I think this is the correct behavior? Absolutely not. First, it prevents nothing as far as modifying keys (const accepts mutable keys as well as const and mutable ones). Second, I believe you should be able to use whatever key constancy you want. We should just say if you do the wrong thing, it's undefined. Maybe safe code can only use immutable keys. Third, if it must be illegal to have an AA with mutable keys, it should be an error, not silently change to const.
I agree on points 1 & 3. "Second" looks dangerous to me.
Dangerous, yes. But immutable objects are typically not easy to deal with. For one, you can't have tail-immutable objects (currently), so implementation of such a container is going to be a pain. In fact, dcollections simply doesn't work if you have fully immutable types as keys. In reality, most times you are not using something as a key and somewhere else simultaneously. So while theoretically dangerous, it's easy to write code that isn't dangerous.
What about ref'ed objects used as keys be compared (at least as keys) by ref -- and only by ref. This is how Lua tables work (and the reason why they're so fast): a = {1,1} ; b = {2,2} t = {[a]=1 , [b]=2} print (t[a], t[{1,1}]) --> 1 nil a and the second {1,1} key are distinct objects. This is not often what we mean, in the general case. Composite objects actually often are, conceptually, *values*, like a position or color; thus, should be compared by value. But they sometimes represent unique "entities", like a game character, which should be compared (as keys and everywhere else) by "unicity" -- and only that way. Comparing their state simply makes no sense. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 08 2011
On Fri, 08 Apr 2011 13:01:41 +0200, simendsjo <simen.endsjo pandavre.com> wrote:It is a mistake to use non-immutable keys for an associative array.
But a string literal isn't mutable..?
This is correct. I'm referring to line 1, int[char[]] asr;. This declaration is wrong, and should be rejected by the compiler. Also note that I'm saying non-immutable. const is not good enough, as it may come from a mutable source. -- Simen
Apr 08 2011
On Fri, 08 Apr 2011 13:37:10 +0200, Morlan <home valentimex.com> wrote:int[char[]] is consistently used D's Language reference to illustrate associative arrays. For me it looks like something that should not compile. Of course int[string] works without problem so I wonder why int[char[]] was used as an example. Was it carried over from D1 reference perhaps?
Probably it was. Could you please file a bug report on that? http://d.puremagic.com/issues/enter_bug.cgi -- Simen
Apr 08 2011
On Fri, 08 Apr 2011 06:44:42 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array.
int[char[]] asr; pragma(msg, typeof(asr).stringof); outputs: AssociativeArray!(const(char)[],int) So the compiler adds const to the keys, which is why it works. Do I think this is the correct behavior? Absolutely not. First, it prevents nothing as far as modifying keys (const accepts mutable keys as well as const and mutable ones). Second, I believe you should be able to use whatever key constancy you want. We should just say if you do the wrong thing, it's undefined. Maybe safe code can only use immutable keys. Third, if it must be illegal to have an AA with mutable keys, it should be an error, not silently change to const. -Steve
Apr 08 2011
On Fri, 08 Apr 2011 17:13:19 +0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Fri, 08 Apr 2011 06:44:42 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array.
int[char[]] asr; pragma(msg, typeof(asr).stringof); outputs: AssociativeArray!(const(char)[],int) So the compiler adds const to the keys, which is why it works. Do I think this is the correct behavior? Absolutely not. First, it prevents nothing as far as modifying keys (const accepts mutable keys as well as const and mutable ones). Second, I believe you should be able to use whatever key constancy you want. We should just say if you do the wrong thing, it's undefined. Maybe safe code can only use immutable keys. Third, if it must be illegal to have an AA with mutable keys, it should be an error, not silently change to const. -Steve
What about storing objects as keys? There is nothing wrong to modify those objects as long as their order stays the same. Immutable works, but that's an overkill, tail const would suffice in most cases (where an indirection isn't used). E.g.: int[void*] example; All that is required is that "int compare(T)(T lhs, T rhs)" is pure (i.e. returns same result for same inputs). In future, compiler could statically enforce that int compare(void* lhs, void* rhs) pure { if (lhs < rhs) return 1; if (lhs > rhs) return -1; return 0; } is correct and int compare(char[] lhs, char[] rhs) pure { if (lhs < rhs) return 1; if (lhs > rhs) return -1; return 0; } is not. For some reason (bug?), both compile with 2.052.
Apr 08 2011
On Fri, 08 Apr 2011 09:40:32 -0400, Denis Koroskin <2korden gmail.com> wrote:On Fri, 08 Apr 2011 17:13:19 +0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Fri, 08 Apr 2011 06:44:42 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array.
int[char[]] asr; pragma(msg, typeof(asr).stringof); outputs: AssociativeArray!(const(char)[],int) So the compiler adds const to the keys, which is why it works. Do I think this is the correct behavior? Absolutely not. First, it prevents nothing as far as modifying keys (const accepts mutable keys as well as const and mutable ones). Second, I believe you should be able to use whatever key constancy you want. We should just say if you do the wrong thing, it's undefined. Maybe safe code can only use immutable keys. Third, if it must be illegal to have an AA with mutable keys, it should be an error, not silently change to const. -Steve
What about storing objects as keys? There is nothing wrong to modify those objects as long as their order stays the same.
I agree with you. See my second point. But even if that isn't what the committee decides, the current behavior guarantees absolutely nothing. -Steve
Apr 08 2011
On Fri, 08 Apr 2011 17:40:32 +0400, Denis Koroskin wrote:int compare(char[] lhs, char[] rhs) pure { if (lhs < rhs) return 1; if (lhs > rhs) return -1; return 0; } is not. For some reason (bug?), both compile with 2.052.
Purity has nothing to do with the type. "Hello" and a char[] storing "Hello" will always produce the same results when passed to this function. The fact that it can be changed to "Byelo" does not effect the results for when "Hello" is passed in. I agree that Objects make for great mutable keys, but how can you guarantee the hash won't change when the contents change, toHash is overridable after all.
Apr 08 2011
On Fri, 08 Apr 2011 14:57:52 -0400, spir <denis.spir gmail.com> wrote:On 04/08/2011 03:13 PM, Steven Schveighoffer wrote:On Fri, 08 Apr 2011 06:44:42 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:On Fri, 08 Apr 2011 12:46:08 +0200, Morlan <home valentimex.com> wrote:It is OK if I write int[char[]] asr; asr["hello"] = 10; but the following does not compile: char[] car = "hello"; What is the explanation for this behaviour?
The first should not be allowed. It is a mistake to use non-immutable keys for an associative array.
int[char[]] asr; pragma(msg, typeof(asr).stringof); outputs: AssociativeArray!(const(char)[],int) So the compiler adds const to the keys, which is why it works. Do I think this is the correct behavior? Absolutely not. First, it prevents nothing as far as modifying keys (const accepts mutable keys as well as const and mutable ones). Second, I believe you should be able to use whatever key constancy you want. We should just say if you do the wrong thing, it's undefined. Maybe safe code can only use immutable keys. Third, if it must be illegal to have an AA with mutable keys, it should be an error, not silently change to const.
I agree on points 1 & 3. "Second" looks dangerous to me.
Dangerous, yes. But immutable objects are typically not easy to deal with. For one, you can't have tail-immutable objects (currently), so implementation of such a container is going to be a pain. In fact, dcollections simply doesn't work if you have fully immutable types as keys. In reality, most times you are not using something as a key and somewhere else simultaneously. So while theoretically dangerous, it's easy to write code that isn't dangerous. -Steve
Apr 08 2011
On Fri, 08 Apr 2011 16:12:27 -0400, spir <denis.spir gmail.com> wrote:On 04/08/2011 09:20 PM, Steven Schveighoffer wrote:In reality, most times you are not using something as a key and somewhere else simultaneously. So while theoretically dangerous, it's easy to write code that isn't dangerous.
What about ref'ed objects used as keys be compared (at least as keys) by ref -- and only by ref. This is how Lua tables work (and the reason why they're so fast): a = {1,1} ; b = {2,2} t = {[a]=1 , [b]=2} print (t[a], t[{1,1}]) --> 1 nil a and the second {1,1} key are distinct objects. This is not often what we mean, in the general case. Composite objects actually often are, conceptually, *values*, like a position or color; thus, should be compared by value. But they sometimes represent unique "entities", like a game character, which should be compared (as keys and everywhere else) by "unicity" -- and only that way. Comparing their state simply makes no sense.
I believe objects are compared that way by default. But you may want to compare them based on their values. For example, a container may want to compare equal to another container if it has all of the same elements, regardless of whether they are the same exact instance. In any case, allowing non-immutable keys in the case where it's just the references being compared is a good use case. -Steve
Apr 08 2011









Morlan <home valentimex.com> 