Bug 8006 – Implement proper in-place-modification for properties

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-04-29T23:26:40Z
Last change time
2024-12-13T17:59:35Z
Assigned to
No Owner
Creator
Andrej Mitrovic
Blocks
16187
See also
https://issues.dlang.org/show_bug.cgi?id=16187, https://issues.dlang.org/show_bug.cgi?id=15231
Moved to GitHub: dmd#18434 →

Comments

Comment #0 by andrej.mitrovich — 2012-04-29T23:26:40Z
Currently properties are only usable for reading and writing values, but they can't really be used for in-place modification: // fake int type, just to avoid rvalue errors in this demo struct Bar { int x; alias x this; } struct Foo { Bar _val; @property Bar val() { return _val; } @property void val(Bar nval) { _val = nval; } } void main() { Foo foo; foo.val += 5; // modifies *temporary*, then discards it foo.val++; // ditto } The only way to work around this is to make the getter property return by ref, but this completely circumvents the setter property, e.g.: struct Bar { int x; alias x this; } struct Foo { Bar _val; @property ref Bar val() { return _val; } @property void val(Bar nval) { _val = nval; } // never called } void main() { Foo foo; foo.val += 5; assert(foo.val == 5); // updated, but setter circumvented foo.val++; assert(foo.val == 6); // ditto } C# apparently implements in-place modification by translating calls such as this: foo.val += 5; foo.val++; into this: foo.val = foo.val + 5; foo.val = foo.val + 1; DIP4 also mentioned this feature (http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4), but was superseeded by DIP6 which was approved. I think we ought to implement this to make properties more usable and less error-prone to work with.
Comment #1 by smjg — 2012-05-07T04:06:21Z
*** Issue 8056 has been marked as a duplicate of this issue. ***
Comment #2 by jminer7 — 2012-05-15T18:40:33Z
This bug might be a duplicate of bug 808, although @property didn't exist back then. This bug has a more detailed description. I would really like to see this implemented. Properties seem only half-implemented to me if they don't support +=, -=, etc. operators.
Comment #3 by doob — 2013-01-24T23:42:16Z
Same thing if you do something like this: foo.val.x = 3; Needs to be rewritten to: auto __tmp = foo.val; __tmp.x = 3; foo.val = __tmp;
Comment #4 by greensunny12 — 2016-06-20T22:41:52Z
Issue 16187 (bitmanip fields should be lvalues) depends on this. Has anyone worked on implementing this lowering on the DMD frontend?
Comment #5 by abc.mikey — 2016-10-09T12:23:58Z
As a beginner this is a source of some confusion for me. Ideally the implementation details of a property vs a member variable should be transparent to me as a user of a given object. class Test { private: int _val, _val2; public: @property int val() { return _val; } @property void val(int val) { _val = val; } @property auto ref val2() { return _val2; } } void main() { auto t = new Test; //t.val += 100; // BAD - not an lvalue t.val(t.val + 100); // probably preferable to misleading syntax t.val2 += 200; // OK - but inconsistent import std.stdio : writefln; writefln("val: %d, val2: %d", t.val, t.val2); } ~
Comment #6 by slavo5150 — 2017-08-11T11:53:35Z
An attempt at a partial implementation: https://github.com/dlang/dmd/pull/7079/files
Comment #7 by robert.schadek — 2024-12-13T17:59:35Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18434 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB