www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - & operator and aa lookup

reply "Ben Hinkle" <bhinkle mathworks.com> writes:
In the main newsgroup someone noticed that
int main() {
  int[char[]] x;
  int* p = &x["hello"];
  return 0;
}
errors that "hello" is not in the array. I think it is a bug and that & 
should force "hello" to be inserted if not present.
Jul 08 2005
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message 
news:dam0hb$5ds$1 digitaldaemon.com...
 In the main newsgroup someone noticed that
 int main() {
  int[char[]] x;
  int* p = &x["hello"];
  return 0;
 }
 errors that "hello" is not in the array. I think it is a bug and that & 
 should force "hello" to be inserted if not present.

Umm, isn't that behavior that was just changed in 0.126?
Jul 08 2005
next sibling parent reply David Medlock <noone nowhere.com> writes:
Jarrett Billingsley wrote:

 "Ben Hinkle" <bhinkle mathworks.com> wrote in message 
 news:dam0hb$5ds$1 digitaldaemon.com...
 
In the main newsgroup someone noticed that
int main() {
 int[char[]] x;
 int* p = &x["hello"];
 return 0;
}
errors that "hello" is not in the array. I think it is a bug and that & 
should force "hello" to be inserted if not present.

Umm, isn't that behavior that was just changed in 0.126?

advantage to making the common case(default insertion) the most difficult option with AAs. If the key may not exist in the AA you can still use in, but now the simple option of inserting a default value requires much hoop jumping. Can someone enlighten me the thinking behind this?
Jul 08 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"David Medlock" <noone nowhere.com> wrote in message 
news:damcu4$gb1$1 digitaldaemon.com...
 Jarrett Billingsley wrote:

 "Ben Hinkle" <bhinkle mathworks.com> wrote in message 
 news:dam0hb$5ds$1 digitaldaemon.com...

In the main newsgroup someone noticed that
int main() {
 int[char[]] x;
 int* p = &x["hello"];
 return 0;
}
errors that "hello" is not in the array. I think it is a bug and that & 
should force "hello" to be inserted if not present.

Umm, isn't that behavior that was just changed in 0.126?

advantage to making the common case(default insertion) the most difficult option with AAs.

Search for threads in the main newsgroup with titles like 'in stinks' and 'aa' or 'AA'. I see about 3 or 4 threads about insert-on-lookup behavior or other AA behaviors like 'in', 'delete', 'contains', etc
 If the key may not exist in the AA you can still use in, but now the 
 simple option of inserting a default value requires much hoop jumping.

 Can someone enlighten me the thinking behind this?

There were many suggestions to Walter about what to do about AAs. IMHO he's done a few of the changes but more is needed.
Jul 08 2005
parent reply David Medlock <noone nowhere.com> writes:
Ben Hinkle wrote:

 "David Medlock" <noone nowhere.com> wrote in message 
 news:damcu4$gb1$1 digitaldaemon.com...
 
Jarrett Billingsley wrote:


"Ben Hinkle" <bhinkle mathworks.com> wrote in message 
news:dam0hb$5ds$1 digitaldaemon.com...


In the main newsgroup someone noticed that
int main() {
int[char[]] x;
int* p = &x["hello"];
return 0;
}
errors that "hello" is not in the array. I think it is a bug and that & 
should force "hello" to be inserted if not present.

Umm, isn't that behavior that was just changed in 0.126?

I guess I missed the conversation about this, but I don't see a single advantage to making the common case(default insertion) the most difficult option with AAs.

Search for threads in the main newsgroup with titles like 'in stinks' and 'aa' or 'AA'. I see about 3 or 4 threads about insert-on-lookup behavior or other AA behaviors like 'in', 'delete', 'contains', etc

Odd, considering automatic insertion is the default for std::map's operator[]... There are 3 basic situations with a map: 1. I have a value which I absolutely must insert into the map. 2. I wish to see if the value exists in the map, if it doesnt do action A else do Action B. 3. I wish to see if the value exists in the map, if it doesnt then add a value, then perform some actions on that entry. #1 is unaffected by the change. #2 is well covered by *in* #3 is the overriding default for structs and especially arrays. Before you could use *in* for the special case where you had an AA and did not wish to insert (struct or array only, since classes are by reference). Now you are forced to use *in* for #3 for these types on every access. For : int[][ char c ] myAA; I cannot just use the elegant: myAA['x'] ~= 100; now it is: int[]* ptr = ('x' in myAA); if ( ptr is null ) { ptr[0] = new int[1]; myAA['x'] = ptr[0]; } ptr[0] ~= 100; And this is considered a good thing? By what standards is the second case more readable, and maintainable ? So saving a few machine cycles for the corner case where you do not want to auto-insert is the rationale? Isn't that covered by *in*?
 
If the key may not exist in the AA you can still use in, but now the 
simple option of inserting a default value requires much hoop jumping.

Can someone enlighten me the thinking behind this?

There were many suggestions to Walter about what to do about AAs. IMHO he's done a few of the changes but more is needed.

I fear D is fast losing its 'simplicity' compared to C++. Programmer time is *always* more valuable than machine time. -DavidM
Jul 08 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
 For :

 int[][ char c ]  myAA;

 I cannot just use the elegant:

 myAA['x'] ~= 100;

That works just fine. For example try running int main() { int[][char[]] x; x["hello"] ~= 10; x["hello"] ~= 20; x["world"] ~= 30; printf("length %d\n",x.length); return 0; }
Jul 08 2005
parent reply David Medlock <noone nowhere.com> writes:
Ben Hinkle wrote:
For :

int[][ char c ]  myAA;

I cannot just use the elegant:

myAA['x'] ~= 100;

That works just fine. For example try running int main() { int[][char[]] x; x["hello"] ~= 10; x["hello"] ~= 20; x["world"] ~= 30; printf("length %d\n",x.length); return 0; }

True. However replacing int[] with a struct like your List!(int) will cause it to fail. This disallows replacing an int[] with a container, doesn't it? My question still remains, which instances are better because off with this change? I don't see any improvement in the *dont create* case, compared with the previous situation. But this adds complexity in the *insert and give me the default* case. (which I would argue is more often used) A better solution would be keep STL like behavior, and add a builtin: bool get( in Key key, out Value val ) method to all AAs. This would return true if it was found, and store the value in val. Oh well.. -DavidM
Jul 08 2005
next sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"David Medlock" <noone nowhere.com> wrote in message 
news:daml32$o2a$1 digitaldaemon.com...
 Ben Hinkle wrote:
For :

int[][ char c ]  myAA;

I cannot just use the elegant:

myAA['x'] ~= 100;

That works just fine. For example try running int main() { int[][char[]] x; x["hello"] ~= 10; x["hello"] ~= 20; x["world"] ~= 30; printf("length %d\n",x.length); return 0; }

True. However replacing int[] with a struct like your List!(int) will cause it to fail. This disallows replacing an int[] with a container, doesn't it? My question still remains, which instances are better because off with this change? I don't see any improvement in the *dont create* case, compared with the previous situation. But this adds complexity in the *insert and give me the default* case. (which I would argue is more often used) A better solution would be keep STL like behavior, and add a builtin: bool get( in Key key, out Value val ) method to all AAs. This would return true if it was found, and store the value in val.

"bool get( in Key key, out Value val )" This is what 'in' is doing.currently. Isn't it? Andrew.
Jul 08 2005
parent David Medlock <noone nowhere.com> writes:
Andrew Fedoniouk wrote:
 "David Medlock" <noone nowhere.com> wrote in message 
 news:daml32$o2a$1 digitaldaemon.com...
 
Ben Hinkle wrote:

For :

int[][ char c ]  myAA;

I cannot just use the elegant:

myAA['x'] ~= 100;

That works just fine. For example try running int main() { int[][char[]] x; x["hello"] ~= 10; x["hello"] ~= 20; x["world"] ~= 30; printf("length %d\n",x.length); return 0; }

True. However replacing int[] with a struct like your List!(int) will cause it to fail. This disallows replacing an int[] with a container, doesn't it? My question still remains, which instances are better because off with this change? I don't see any improvement in the *dont create* case, compared with the previous situation. But this adds complexity in the *insert and give me the default* case. (which I would argue is more often used) A better solution would be keep STL like behavior, and add a builtin: bool get( in Key key, out Value val ) method to all AAs. This would return true if it was found, and store the value in val.

"bool get( in Key key, out Value val )" This is what 'in' is doing.currently. Isn't it? Andrew.

struct A { int n = 0; } A[char[]] aa; void set( char[] key, int val ) { A var; if ( aa.get( key, var ) ) var.n = val; } // versus void set( char[] key, int val ) { A* ptr = (key in aa ); if ( a is null ) { A temp; temp.n = val; aa[key] = temp; } else ptr.n = val; } Sorry, I wasn't clear on that. If you allow it to create the out parameter, you get the old behavior, plus you get the information whether or not it was created! if ( aa.get( 100, var ) ) { ...key was in aa...} else { ...key was not in aa, do something with var... } This seems like a good addition if the new semantics are retained. -DavidM
Jul 08 2005
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"David Medlock" <noone nowhere.com> wrote in message
news:daml32$o2a$1 digitaldaemon.com...
 Oh well..
 -DavidM

I wish you'd spoken up sooner. I don't remember a single person defending the former behavior of aa's.
Jul 08 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

Oh well..
-DavidM

I wish you'd spoken up sooner. I don't remember a single person defending the former behavior of aa's.

I hope we are not "designing by committee" here, because I don't think the new AA is much better... (and 'in' returning a pointer is still a tad weird) i.e. to me it doesn't make much of a difference if a lookup secretly inserts a value, or if a missing key makes it throw up an exception on the carpet ? And all of this "let's add a method to do it" makes you wonder if we wouldn't all be better off with a library implementation of AAs ? I like the built-in AAs a lot, but if we can't make the syntax "OK" and if you can't initialize them in a simple and pretty way - then why ? As in: I would rather have any old horse, than a new camel. --anders PS. I'm still hoping we can fix them, and leave them in ? Built-in arrays and tables are *very* useful to have.
Jul 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:dao0rm$1q6p$1 digitaldaemon.com...
 PS. I'm still hoping we can fix them, and leave them in ?
      Built-in arrays and tables are *very* useful to have.

Yes, I totally agree with that. I often get the "C++ is better because it does it with a library", but there are significant advantages to building it into the core. I use them a lot in my own D programming, and they're a big win. Where I screwed up, though, are the bit arrays <g>. If I was doing D over, I'd leave them out. They aren't worth the trouble.
Jul 09 2005
next sibling parent reply "Uwe Salomon" <post uwesalomon.de> writes:
 Where I screwed up, though, are the bit arrays <g>. If I was doing D  
 over, I'd leave them out. They aren't worth the trouble.

Well, why don't you leave them out now? We could make a poll in the newsgroup (just a *suggestion* for now!): 1. Will you need bit arrays in the future? 2. Did you already use bit arrays in some important piece of code? Perhaps they are unpopular, und all your problems will be solved... ;o) Ciao uwe
Jul 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Uwe Salomon" <post uwesalomon.de> wrote in message
news:op.stnv8yzj6yjbe6 sandmann.maerchenwald.net...
 Where I screwed up, though, are the bit arrays <g>. If I was doing D
 over, I'd leave them out. They aren't worth the trouble.

Well, why don't you leave them out now? We could make a poll in the newsgroup (just a *suggestion* for now!): 1. Will you need bit arrays in the future? 2. Did you already use bit arrays in some important piece of code? Perhaps they are unpopular, und all your problems will be solved... ;o)

I know that Stewart uses them a lot.
Jul 09 2005
parent "Uwe Salomon" <post uwesalomon.de> writes:
 Perhaps they are unpopular, und all your problems will be solved...  ;o)

I know that Stewart uses them a lot.

Oh my! Stewart, how could you do that to us?! ;o) Ciao uwe
Jul 10 2005
prev sibling next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

PS. I'm still hoping we can fix them, and leave them in ?
     Built-in arrays and tables are *very* useful to have.

Yes, I totally agree with that. I often get the "C++ is better because it does it with a library", but there are significant advantages to building it into the core. I use them a lot in my own D programming, and they're a big win.

I can only compare with C or Java, but I do think the syntax is nicer when they are built-in to the core language itself. But that could be since I've been doing Perl for ten years, where the arrays and %hashes are as natural as $scalars ? :-) --anders
Jul 10 2005
prev sibling next sibling parent clayasaurus <clayasaurus gmail.com> writes:
Walter wrote:
 "Anders F Björklund" <afb algonet.se> wrote in message
 news:dao0rm$1q6p$1 digitaldaemon.com...
 
PS. I'm still hoping we can fix them, and leave them in ?
     Built-in arrays and tables are *very* useful to have.

Yes, I totally agree with that. I often get the "C++ is better because it does it with a library", but there are significant advantages to building it into the core. I use them a lot in my own D programming, and they're a big win. Where I screwed up, though, are the bit arrays <g>. If I was doing D over, I'd leave them out. They aren't worth the trouble.

If you don't mind me asking, what are wrong with the bit arrays?
Jul 10 2005
prev sibling next sibling parent Vathix <chris dprogramming.com> writes:
On Sat, 09 Jul 2005 14:52:23 -0400, Walter <newshound digitalmars.com>  
wrote:

 Where I screwed up, though, are the bit arrays <g>. If I was doing D  
 over,
 I'd leave them out. They aren't worth the trouble.

I don't use bit arrays or pointers-to-bit because they seem to be screwed up, but I do like using regular old bit variables since I like that the compiler can pack them together. What if there were some rules about bit arrays and pointers: 1) Can only slice or take address on byte boundaries, otherwise an exception is thrown. 2) To slice or take address on non-byte boundaries, you'd have to use a special method, perhaps: bitarray.dup(1, 2) to create a new slice of bitarray[1 .. 2]. This means bit* will actually be byte* internally. Are there other problems with bit?
Jul 10 2005
prev sibling parent "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:dap6pp$2sv5$1 digitaldaemon.com...
 "Anders F Björklund" <afb algonet.se> wrote in message
 news:dao0rm$1q6p$1 digitaldaemon.com...
 PS. I'm still hoping we can fix them, and leave them in ?
      Built-in arrays and tables are *very* useful to have.

Yes, I totally agree with that. I often get the "C++ is better because it does it with a library", but there are significant advantages to building it into the core. I use them a lot in my own D programming, and they're a big win. Where I screwed up, though, are the bit arrays <g>. If I was doing D over, I'd leave them out. They aren't worth the trouble.

Yep. Bit arrays is a dark corner now. May I suggest to replace them with some templated struct in Phobos? Sort of: struct bitset( uint numBits ) { static if (numBits <= 16) ushort data; static else if (numBits <= 32) uint data; static else uint[ numBits / 32 ] data; .... opIndexAssign() ... opIndex() ... }
Jul 11 2005
prev sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:damt98$v3j$1 digitaldaemon.com...
 "David Medlock" <noone nowhere.com> wrote in message
 news:daml32$o2a$1 digitaldaemon.com...
 Oh well..
 -DavidM

I wish you'd spoken up sooner. I don't remember a single person defending the former behavior of aa's.

If you change something and no-one complains it means you don't have enough users :-)
Jul 12 2005
parent Kramer <Kramer_member pathlink.com> writes:
<g> That's a great quote on so many levels. :)

In article <db1449$198j$1 digitaldaemon.com>, Ben Hinkle says...
"Walter" <newshound digitalmars.com> wrote in message 
news:damt98$v3j$1 digitaldaemon.com...
 "David Medlock" <noone nowhere.com> wrote in message
 news:daml32$o2a$1 digitaldaemon.com...
 Oh well..
 -DavidM

I wish you'd spoken up sooner. I don't remember a single person defending the former behavior of aa's.

If you change something and no-one complains it means you don't have enough users :-)

Jul 12 2005
prev sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"David Medlock" <noone nowhere.com> wrote in message 
news:daml32$o2a$1 digitaldaemon.com...
 Ben Hinkle wrote:
For :

int[][ char c ]  myAA;

I cannot just use the elegant:

myAA['x'] ~= 100;

That works just fine. For example try running int main() { int[][char[]] x; x["hello"] ~= 10; x["hello"] ~= 20; x["world"] ~= 30; printf("length %d\n",x.length); return 0; }

True. However replacing int[] with a struct like your List!(int) will cause it to fail. This disallows replacing an int[] with a container, doesn't it?

I assume you mean an example like import mintl.list; int main() { List!(int)[char[]] x; x["hello"] ~= 10; } The x["hello"] is treated as an rvalue instead of an lvalue when ~= gets converted to opCatAssign. I would consider that another bug in AA's indexing.
Jul 10 2005
prev sibling parent reply Nick <Nick_member pathlink.com> writes:
In article <dambvi$fih$1 digitaldaemon.com>, Jarrett Billingsley says...
"Ben Hinkle" <bhinkle mathworks.com> wrote in message 
news:dam0hb$5ds$1 digitaldaemon.com...
 In the main newsgroup someone noticed that
 int main() {
  int[char[]] x;
  int* p = &x["hello"];
  return 0;
 }
 errors that "hello" is not in the array. I think it is a bug and that & 
 should force "hello" to be inserted if not present.

Umm, isn't that behavior that was just changed in 0.126?

The idea is that the & operator expects an lvalue, and the AA inserts an element whenever an lvalue is required. Personally I'm more getting inclined towards an .add() property, which would always return a valid element. Having all these special cases to remember is not a Good Thing, IMHO. Nick
Jul 08 2005
parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Nick" <Nick_member pathlink.com> wrote in message 
news:damdj8$h06$1 digitaldaemon.com...
 In article <dambvi$fih$1 digitaldaemon.com>, Jarrett Billingsley says...
"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:dam0hb$5ds$1 digitaldaemon.com...
 In the main newsgroup someone noticed that
 int main() {
  int[char[]] x;
  int* p = &x["hello"];
  return 0;
 }
 errors that "hello" is not in the array. I think it is a bug and that &
 should force "hello" to be inserted if not present.

Umm, isn't that behavior that was just changed in 0.126?

The idea is that the & operator expects an lvalue, and the AA inserts an element whenever an lvalue is required. Personally I'm more getting inclined towards an .add() property, which would always return a valid element. Having all these special cases to remember is not a Good Thing, IMHO. Nick

I wouldn't mind seeing more explicit names for the indexing behaviors like "get","add","insert" whatever and then have indexing do what it currently does (assuming the bugs get fixed) - pick the best function depending on rvalue/lvalue needs. I would bet that if the AA indexing bugs weren't there none of these recent threads about indexing would have come up because it just does what is natural.
Jul 10 2005
prev sibling parent "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message 
news:dam0hb$5ds$1 digitaldaemon.com...
 In the main newsgroup someone noticed that
 int main() {
  int[char[]] x;
  int* p = &x["hello"];
  return 0;
 }
 errors that "hello" is not in the array. I think it is a bug and that & 
 should force "hello" to be inserted if not present.

Probably immutables might also help in this situation int foo( inout int #[char[]] x ) { int *p = &x["hello"]; // returns null return 0; } int foo( inout int [char[]] x ) { int *p = &x["hello"]; // returns valid pointer return 0; } No?
Jul 08 2005