digitalmars.D - property syntax problems
- Alex Burton (25/25) Feb 05 2009 Hi,
- Robert Jacques (4/34) Feb 05 2009 This isn't a bug, it's a feature. What you wanted to use were ref return...
- Bill Baxter (5/47) Feb 05 2009 You could call it a bug that the compiler doesn't warn about the
- Robert Jacques (5/22) Feb 05 2009 isn't the real ( or I think desired ) warning. The real issue is that
- Alex Burton (17/43) Feb 05 2009 I think in this case it has to be an error, precicely because the syntax...
- Alex Burton (18/62) Feb 05 2009 Using
- Robert Jacques (15/88) Feb 05 2009 Alex, this looks like you want to use proxy structs/objects. Remember ea...
- Christopher Wright (5/10) Feb 06 2009 This has given me some trouble in C#. As a result, anything complicated
- Chad J (11/15) Feb 05 2009 Yep, as was said, this is a "feature".
- Andrei Alexandrescu (4/23) Feb 05 2009 Yah, I gotta say that the a.b.c = d catastrophe finally dropped the coin...
Hi, I just found a bug that comes out of the property syntax. The property syntax is great in that it allows a smooth transition from simple code dealing with public member variables to the use of interfaces without needing to update the client code. i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being an int to being void A::bob(int i) instead of changing to A.bob(1). But this can introduce the bug I show below. Proposal : If the temporary returned by the property syntax getter function is modified, then the corresponding setter function needs to be called with the temporary as argument. struct A { int i; int j; }; class B { A mA; public: A a() { return mA; } void a(Atom a) { mA = a; } }; int main() { B b; b.a.j = 10; // error b.a is a temporary. }
Feb 05 2009
On Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alexibu mac.com> wrote:Hi, I just found a bug that comes out of the property syntax. The property syntax is great in that it allows a smooth transition from simple code dealing with public member variables to the use of interfaces without needing to update the client code. i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being an int to being void A::bob(int i) instead of changing to A.bob(1). But this can introduce the bug I show below. Proposal : If the temporary returned by the property syntax getter function is modified, then the corresponding setter function needs to be called with the temporary as argument. struct A { int i; int j; }; class B { A mA; public: A a() { return mA; } void a(Atom a) { mA = a; } }; int main() { B b; b.a.j = 10; // error b.a is a temporary. }This isn't a bug, it's a feature. What you wanted to use were ref returns (see http://www.digitalmars.com/d/2.0/function.html ) ref A a() { return mA; }
Feb 05 2009
On Fri, Feb 6, 2009 at 2:34 AM, Robert Jacques <sandford jhu.edu> wrote:On Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alexibu mac.com> wrote:You could call it a bug that the compiler doesn't warn about the modification of a temporary like that in a way that has no side effects. Or maybe it does warn about it if you enable warnings? --bbHi, I just found a bug that comes out of the property syntax. The property syntax is great in that it allows a smooth transition from simple code dealing with public member variables to the use of interfaces without needing to update the client code. i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being an int to being void A::bob(int i) instead of changing to A.bob(1). But this can introduce the bug I show below. Proposal : If the temporary returned by the property syntax getter function is modified, then the corresponding setter function needs to be called with the temporary as argument. struct A { int i; int j; }; class B { A mA; public: A a() { return mA; } void a(Atom a) { mA = a; } }; int main() { B b; b.a.j = 10; // error b.a is a temporary. }This isn't a bug, it's a feature. What you wanted to use were ref returns (see http://www.digitalmars.com/d/2.0/function.html ) ref A a() { return mA; }
Feb 05 2009
On Thu, 05 Feb 2009 14:27:27 -0500, Bill Baxter <wbaxter gmail.com> wrote:On Fri, Feb 6, 2009 at 2:34 AM, Robert Jacques <sandford jhu.edu> wrote:Actually, from that point of viewOn Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alexibu mac.com> wrote:You could call it a bug that the compiler doesn't warn about the modification of a temporary like that in a way that has no side effects. Or maybe it does warn about it if you enable warnings? --bbint main() { B b; b.a.j = 10; // error b.a is a temporary. }This isn't a bug, it's a feature. What you wanted to use were ref returns (see http://www.digitalmars.com/d/2.0/function.html ) ref A a() { return mA; }isn't the real ( or I think desired ) warning. The real issue is that b.a.j results in an unused variable which several other compilers issue warnings about and is a much more general issue.b.a.j = 10; // error b.a is a temporary.
Feb 05 2009
Robert Jacques Wrote:On Thu, 05 Feb 2009 14:27:27 -0500, Bill Baxter <wbaxter gmail.com> wrote:I think in this case it has to be an error, precicely because the syntax doesn't show that there is a function call. If I do this: x.variable() = 7; Then I can expect it to do nothing as the parentheses show that this is a function. If I do this: x.variable = 7; I expect the code to work as intended which means that : writefln("x.variable = %d",x.variable); should print "x.variable = 7" And this does work as long as variable is a plain old data. The problem occurs when variable is a struct or class. Which allows me to type : x.variable.i = 7 Which doesn't work as expected. Moreover code evolving from variable being an int to a struct with two ints is common. AlexOn Fri, Feb 6, 2009 at 2:34 AM, Robert Jacques <sandford jhu.edu> wrote:Actually, from that point of viewOn Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alexibu mac.com> wrote:You could call it a bug that the compiler doesn't warn about the modification of a temporary like that in a way that has no side effects. Or maybe it does warn about it if you enable warnings? --bbint main() { B b; b.a.j = 10; // error b.a is a temporary. }This isn't a bug, it's a feature. What you wanted to use were ref returns (see http://www.digitalmars.com/d/2.0/function.html ) ref A a() { return mA; }isn't the real ( or I think desired ) warning. The real issue is that b.a.j results in an unused variable which several other compilers issue warnings about and is a much more general issue.b.a.j = 10; // error b.a is a temporary.
Feb 05 2009
Robert Jacques Wrote:On Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alexibu mac.com> wrote:Using ref A a() { return mA; } requires us to have a member variable mA ( which is actually there in the example). One of the reasons for using the setter and getter functions instead of the raw member variable is that there is not actually a member variable. For example: A a() { Dataset ds = mDatabase.Execute("SELECT A,B FROM TABLE"); return A(ds[0][0],ds[0][1]); } void a(A a) { mDatabase.Execute(format("INSERT %d,%d INTO TABLE;",a.i,a.j)); } The only way I can see to handle this correctly is to use my proposal above. This could be a really valuable feature in D if correctly implemented. Being able to transparently change from a member variable in a struct to getters and setters on a struct to getters and setters on a class and in reverse order is really powerful and allows code to evolve in a much more fluid way. AlexHi, I just found a bug that comes out of the property syntax. The property syntax is great in that it allows a smooth transition from simple code dealing with public member variables to the use of interfaces without needing to update the client code. i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being an int to being void A::bob(int i) instead of changing to A.bob(1). But this can introduce the bug I show below. Proposal : If the temporary returned by the property syntax getter function is modified, then the corresponding setter function needs to be called with the temporary as argument. struct A { int i; int j; }; class B { A mA; public: A a() { return mA; } void a(A a) { mA = a; } }; int main() { B b; b.a.j = 10; // error b.a is a temporary. }This isn't a bug, it's a feature. What you wanted to use were ref returns (see http://www.digitalmars.com/d/2.0/function.html ) ref A a() { return mA; }
Feb 05 2009
On Thu, 05 Feb 2009 20:26:03 -0500, Alex Burton <alexibu mac.com> wrote:Robert Jacques Wrote:Alex, this looks like you want to use proxy structs/objects. Remember each of the following are equivalent: b.a.j = 10; <=> (b.a).j = 10; <=> auto c = b.a; c.j = 10; And that last case is a kinda tricky. Also, the x.y.z = 10 not doing anything when y is a struct from your other post is a well known issue is all languages that have POD struct (As far as I know). The solution is to move x.y to a ref return property. Moving from POD members to functions in order to support more complex logic is the primary motivation of properties.On Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alexibu mac.com> wrote:Using ref A a() { return mA; } requires us to have a member variable mA ( which is actually there in the example). One of the reasons for using the setter and getter functions instead of the raw member variable is that there is not actually a member variable. For example: A a() { Dataset ds = mDatabase.Execute("SELECT A,B FROM TABLE"); return A(ds[0][0],ds[0][1]); } void a(A a) { mDatabase.Execute(format("INSERT %d,%d INTO TABLE;",a.i,a.j)); } The only way I can see to handle this correctly is to use my proposal above. This could be a really valuable feature in D if correctly implemented. Being able to transparently change from a member variable in a struct to getters and setters on a struct to getters and setters on a class and in reverse order is really powerful and allows code to evolve in a much more fluid way. AlexHi, I just found a bug that comes out of the property syntax. The property syntax is great in that it allows a smooth transitionfromsimple code dealing with public member variables to the use of interfaces without needing to update the client code. i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being anintto being void A::bob(int i) instead of changing to A.bob(1). But this can introduce the bug I show below. Proposal : If the temporary returned by the property syntax getter function is modified, then the corresponding setter function needs to be calledwiththe temporary as argument. struct A { int i; int j; }; class B { A mA; public: A a() { return mA; } void a(A a) { mA = a; } }; int main() { B b; b.a.j = 10; // error b.a is a temporary. }This isn't a bug, it's a feature. What you wanted to use were ref returns (see http://www.digitalmars.com/d/2.0/function.html ) ref A a() { return mA; }
Feb 05 2009
Robert Jacques wrote:Also, the x.y.z = 10 not doing anything when y is a struct from your other post is a well known issue is all languages that have POD struct (As far as I know). The solution is to move x.y to a ref return property. Moving from POD members to functions in order to support more complex logic is the primary motivation of properties.in my company's product (anything that is difficult to initialize with all the proper fields) is a class, and anything remaining that is a struct has only read-only properties.
Feb 06 2009
Alex Burton wrote:Hi, I just found a bug that comes out of the property syntax.Yep, as was said, this is a "feature". Sadly I forget why, but I'm pretty sure ref returning doesn't solve all of the problems with properties, just this one (sorta). Also, D1 doesn't have ref returns, so if you're using D1 you're just plain outta' luck. This has been griped about for a few years now. There are also other serious shortcomings of the syntax. (Sorry, I'm too lazy to look up the old threads right now.) Given the "ref returns and properties" thread and a couple other posts that Andrei made, I suspect this is receiving some thought.
Feb 05 2009
Chad J wrote:Alex Burton wrote:Yah, I gotta say that the a.b.c = d catastrophe finally dropped the coin for me. AndreiHi, I just found a bug that comes out of the property syntax.Yep, as was said, this is a "feature". Sadly I forget why, but I'm pretty sure ref returning doesn't solve all of the problems with properties, just this one (sorta). Also, D1 doesn't have ref returns, so if you're using D1 you're just plain outta' luck. This has been griped about for a few years now. There are also other serious shortcomings of the syntax. (Sorry, I'm too lazy to look up the old threads right now.) Given the "ref returns and properties" thread and a couple other posts that Andrei made, I suspect this is receiving some thought.
Feb 05 2009