digitalmars.D - opIndexAddAssign? ...
- Manfred Nowak (10/10) Feb 09 2007 On writing the implementation of a map, where the Valuetype is a set, I
- Lionello Lunesu (4/18) Feb 09 2007 opIndexAssign was needed because D has no "inout" return type. It's a
- Jarrett Billingsley (12/14) Feb 09 2007 Ehhh, I don't really think so.. having opIndexAssign is nice because you...
- Manfred Nowak (17/26) Feb 09 2007 The question is: what do really want to do and why do you have to mix
- Jarrett Billingsley (21/33) Feb 09 2007 So, if all we had was opIndex that returned inout, you're suggesting I
- Manfred Nowak (11/16) Feb 09 2007 This or the other: repeating the same operation for every other
- Sean Kelly (9/25) Feb 09 2007 It is a hack, but a useful one IMO. For example, say I want to insert
- Andrei Alexandrescu (See Website For Email) (8/36) Feb 09 2007 It's also useful for sparse vectors and matrices: you don't want to
- Stewart Gordon (8/20) Feb 09 2007 I agree. It's been said about properties enough times, and the same sho...
- Andrei Alexandrescu (See Website For Email) (4/31) Feb 09 2007 Same with .length.
- BCS (22/36) Feb 09 2007 It could have some nasty side effect but, have opIndex return a
On writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted. I.e.: map[ key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness? -manfred
Feb 09 2007
Manfred Nowak wrote:On writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted. I.e.: map[ key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness? -manfredopIndexAssign was needed because D has no "inout" return type. It's a hack, if you ask me. L.
Feb 09 2007
"Lionello Lunesu" <lio lunesu.remove.com> wrote in message news:eqhnb7$2tjh$2 digitaldaemon.com...opIndexAssign was needed because D has no "inout" return type. It's a hack, if you ask me.Ehhh, I don't really think so.. having opIndexAssign is nice because you can do some processing on the value when it's assigned. How, for example would you do something as simple as this: void opIndexAssign(int value, int key) { mData[key] = value % 10; } using inout return values? In almost every one of my opIndexAssign overloads, I do some kind of checking or processing on the value before inserting it into the internal container.
Feb 09 2007
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wroteHow, for example would you do something as simple as this: void opIndexAssign(int value, int key) { mData[key] = value % 10; } using inout return values?The question is: what do really want to do and why do you have to mix up your intentions? Your intention seems to bind an operation to the valuetype of the AA. But you have bound it to the AA directly and not to the valuetype. The code instance[ key]= value; should be called approximately as instance.opIndex_l(key)= typeof( mData[key]).opAssign( value) In fact your example is not that easy because it is unclear what the return value of opIndex( int) would be: mData[key] or mData[key] * 10 or void as your opIndexAssign suggests? -manfred
Feb 09 2007
"Manfred Nowak" <svv1999 hotmail.com> wrote in message news:eqi90k$kf5$1 digitaldaemon.com...Your intention seems to bind an operation to the valuetype of the AA. But you have bound it to the AA directly and not to the valuetype.So, if all we had was opIndex that returned inout, you're suggesting I implement a new class for the value type of the internal container every time I want the behavior of index assigning to change? That seems a little overkill. Besides, the code I posted is an example. I'm just trying to say that an inout-returning-opIndex doesn't allow you to do anything with the value that's added to this.The code instance[ key]= value; should be called approximately as instance.opIndex_l(key)= typeof( mData[key]).opAssign( value)Again, if my internal data structure for instance is just an: int[] mData; then I can't have the "mData[key] = value % 10;" like in the opIndexAssign version. I'll have to create a proxy class to hold the data which modulos its value by 10 whenever opAssign is used, and make an array of that, and create all those class instances. God, it's starting to sound like Java.In fact your example is not that easy because it is unclear what the return value of opIndex( int) would be: mData[key] or mData[key] * 10That's not what I'm really getting at.. I'm talking about adding or setting an index of a container type, not getting one.or void as your opIndexAssign suggests?I find chaining assignments and using assignments in conditionals (i.e. "if((x = nextThing()) == 0)") to be in bad form, so I always make my opXxxAssign and property setters return void so you can't do that. It's just a personal preference.
Feb 09 2007
Jarrett Billingsley wroteI'll have to create a proxy class to hold the data which modulos its value by 10 whenever opAssign is used, and make an array of that, and create all those class instances.This or the other: repeating the same operation for every other opIndex<op>Assign, which D currently not has.I'm talking about adding or setting an index of a container type, not getting one.Correct. But storing data without any accesses is quite useless. As Andrei already pointed out | Probably the principled thing to do is to allow two functions, one | that returns lvalue and one that returns an rvalue, and have the | compiler pick the appropriate one. there might be a difference between the representations of data inside and outside of classes. -manfred
Feb 09 2007
Lionello Lunesu wrote:Manfred Nowak wrote:It is a hack, but a useful one IMO. For example, say I want to insert an element in an AA only if the AA itself is used as an lvalue. ie. auto x = myAA[key]; // return default value if not present myAA[key] = x; // insert and assign I'll admit that it would be much nicer if this worked for all applicable operator overloads without requiring separate signatures for each, but I'll take what I can get :-) SeanOn writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted. I.e.: map[ key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness? -manfredopIndexAssign was needed because D has no "inout" return type. It's a hack, if you ask me.
Feb 09 2007
Sean Kelly wrote:Lionello Lunesu wrote:It's also useful for sparse vectors and matrices: you don't want to autoinsert stuff or throw when all you want is to read. Just return zero if it's not there. Probably the principled thing to do is to allow two functions, one that returns lvalue and one that returns an rvalue, and have the compiler pick the appropriate one. AndreiManfred Nowak wrote:It is a hack, but a useful one IMO. For example, say I want to insert an element in an AA only if the AA itself is used as an lvalue. ie. auto x = myAA[key]; // return default value if not present myAA[key] = x; // insert and assign I'll admit that it would be much nicer if this worked for all applicable operator overloads without requiring separate signatures for each, but I'll take what I can get :-)On writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted. I.e.: map[ key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness? -manfredopIndexAssign was needed because D has no "inout" return type. It's a hack, if you ask me.
Feb 09 2007
Manfred Nowak Wrote:On writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted.To add opIndexAddAssign et al would be a step back towards the old C++ nightmare of providing lots of operator overloads where just one should suffice.I.e.: map[key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness?I agree. It's been said about properties enough times, and the same should apply to array indexes. That is, qwert[yuiop] op= asdfg should be, in the lack of any overriding alternative (such as an op<op>Assign on the type of qwert[yuiop]), equivalent to qwert[yuiop] = qwert[yuiop] op asdfg except that qwert and yuiop are evaluated only once. Stewart.
Feb 09 2007
Stewart Gordon wrote:Manfred Nowak Wrote:Same with .length. arr.length += 2; AndreiOn writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted.To add opIndexAddAssign et al would be a step back towards the old C++ nightmare of providing lots of operator overloads where just one should suffice.I.e.: map[key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness?I agree. It's been said about properties enough times, and the same should apply to array indexes. That is, qwert[yuiop] op= asdfg should be, in the lack of any overriding alternative (such as an op<op>Assign on the type of qwert[yuiop]), equivalent to qwert[yuiop] = qwert[yuiop] op asdfg except that qwert and yuiop are evaluated only once.
Feb 09 2007
Manfred Nowak wrote:On writing the implementation of a map, where the Valuetype is a set, I had to stop on recognizing, that only opIndexAssign is permitted. I.e.: map[ key]+= element; has no possible overload. OpIndex delivers an rvalue and the only possibility to get an lvalue is in conjunction with a plain assignment. Why arbitrary restrictions when the goal is to have great expressiveness? -manfredIt could have some nasty side effect but, have opIndex return a struct/object that shadows the original and overloads opAddAssign. class F { T[] i class N { this(inout T l){j=&l;} T* j; T opAddAssign(T k) { j+=k; return this; } } N opIndex(int ind) { return new N(i[ind]); } } On second thought, don't
Feb 09 2007