digitalmars.D.learn - OpIndex/OpIndexAssign strange order of execution
- SrMordred (37/37) Sep 17 2017 struct Test{
- SrMordred (3/3) Sep 18 2017 Should I report this as a bug?
- Moritz Maxeiner (21/43) Sep 18 2017 gets rewritten to
- Moritz Maxeiner (6/10) Sep 18 2017 Sorry, forgot one level of rewriting:
- SrMordred (11/23) Sep 18 2017 Nice, thanks for the explanation :)
- =?UTF-8?Q?Ali_=c3=87ehreli?= (21/21) Sep 18 2017 Have you considered the multiple indexes?
- SrMordred (1/9) Sep 18 2017 I thought about this too, thanks!
struct Test{ property int value(){ writeln("property value : ", _value); return _value; } int _value; Test opIndex( string index ) { writeln( "opIndex : index : ", index ); return this; } Test opIndexAssign(int value, string index ) { writeln( "opIndexAssign : value : ", value, " , index : ", index ); this._value = value; return this; } } Test t; t["a"] = 100; t["b"]["c"] = t["a"].value; //OUTPUT: opIndexAssign : index : a , value : 100 opIndex : index : b opIndex : index : a property value : 100 opIndexAssign : index : c , value : 100 //EXPECTED OUTPUT opIndexAssign : index : a , value : 100 opIndex : index : a property value : 100 opIndex : index : b opIndexAssign : index : c , value : 100 Is this right? I find unexpected this mix of operations on left and right side of an equal operator.
Sep 17 2017
Should I report this as a bug? I tried a C++ equivalent code and it execute in the expected order.
Sep 18 2017
On Sunday, 17 September 2017 at 18:52:39 UTC, SrMordred wrote:struct Test{ [...] } Test t;As described in the spec [1]t["a"] = 100;gets rewritten to --- t.opIndexAssign(100, "a"); --- , whilet["b"]["c"] = t["a"].value;gets rewritten to --- t.opIndex("b").opIndexAssign(t["a"].value, "c"); --- , which has to result in your observed output (left-to-right evaluation order)://OUTPUT: opIndexAssign : index : a , value : 100 opIndex : index : b opIndex : index : a property value : 100 opIndexAssign : index : c , value : 100 //EXPECTED OUTPUT opIndexAssign : index : a , value : 100 opIndex : index : a property value : 100 opIndex : index : b opIndexAssign : index : c , value : 100 Is this right?AFAICT from the spec, yes. Your expected output does not match D's rewriting rules for operator overloading.I find unexpected this mix of operations on left and right side of an equal operator.Adding some more examples to the spec to show the results of the rewriting rules could be useful, but AFAICT it's unambiguous. On Monday, 18 September 2017 at 13:38:48 UTC, SrMordred wrote:Should I report this as a bug?Not AFAICT.I tried a C++ equivalent code and it execute in the expected order.D does not (in general) match C++ semantics. [1] https://dlang.org/spec/operatoroverloading.html
Sep 18 2017
On Monday, 18 September 2017 at 15:11:34 UTC, Moritz Maxeiner wrote:gets rewritten to --- t.opIndex("b").opIndexAssign(t["a"].value, "c"); ---Sorry, forgot one level of rewriting: --- t.opIndex("b").opIndexAssign(t.opIndex("a").value, "c"); ---
Sep 18 2017
On Monday, 18 September 2017 at 15:14:20 UTC, Moritz Maxeiner wrote:On Monday, 18 September 2017 at 15:11:34 UTC, Moritz Maxeiner wrote:Nice, thanks for the explanation :) This will be a problem for me because in my use case the internal operations of the structs are stack-like manipulations. So in this case t["b"]["c"] = t["a"].value; instead of manipulating the internal stack with "a" then "b" and "c" I got this weird order of "b", "a", "c" messing with the internal stack logic. Well, back to work :)gets rewritten to --- t.opIndex("b").opIndexAssign(t["a"].value, "c"); ---Sorry, forgot one level of rewriting: --- t.opIndex("b").opIndexAssign(t.opIndex("a").value, "c"); ---
Sep 18 2017
Have you considered the multiple indexes? https://dlang.org/spec/operatoroverloading.html#index_assignment_operator It may give you some power in execution order. import std.stdio; struct S { auto opIndex(string index) { writeln(index); return 42; } auto opIndexAssign(int value, string[] indexes...) { writeln(indexes); } } void main() { auto s = S(); s["b", "c"] = s["a"]; } Prints a ["b", "c"] Ali
Sep 18 2017
void main() { auto s = S(); s["b", "c"] = s["a"]; } Prints a ["b", "c"] AliI thought about this too, thanks!
Sep 18 2017