digitalmars.D - D's "accessors" are like abusing operator overloads
- Nick Sabalausky (24/24) Mar 27 2009 I don't mean to put words in the Tango crew's mouths, but IMO this piece...
- Simen Kjaeraas (7/35) Mar 27 2009 I feel the problem here is that you can access a type's static members
- Nick Sabalausky (3/5) Mar 27 2009 That didn't even occur to me. That's certainly a problem too.
- Steven Schveighoffer (22/29) Mar 27 2009 Yes, that was my main beef with the compiler when I had to fix it. I'd ...
- Denis Koroskin (7/38) Mar 27 2009 int x = 5;
- Steven Schveighoffer (13/41) Mar 27 2009 Because init is a static member of the type. x.init is equivalent to
- Jarrett Billingsley (3/6) Mar 27 2009 In DMD pre-1.017, it would print 5. The language spec was changed
- Denis Koroskin (2/11) Mar 27 2009 Yeah, I know, but still uneasy with the spec change.
- Nick Sabalausky (7/9) Mar 27 2009 True, but a function's/class's/data-member's interface shouldn't help
- Michel Fortin (11/16) Mar 27 2009 Perhaps static being accessible from the instance is a problem, but you
- BCS (2/32) Mar 27 2009 One option would be to only allow that fn = v syntax where fn returns vo...
- Denis Koroskin (2/34) Mar 27 2009 Obscure rule and a bad idea in general. This way you can't do "a = b = c...
- BCS (5/13) Mar 27 2009 I'd say that chaining example would be a bad idea anyway. strange things...
- Derek Parnell (16/17) Mar 27 2009 A bit off topic, but what's so good about that coding style anyway?
- Nick Sabalausky (6/9) Mar 27 2009 I've been known to use it now and then if there's a few variables I'm
- Nick Sabalausky (20/26) Mar 27 2009 That still doesn't plug all the holes. Just because a function takes one...
- Christopher Wright (3/6) Mar 27 2009 I agree, it's a hack. I really enjoy using properties, too, but I think
I don't mean to put words in the Tango crew's mouths, but IMO this piece from 0.99.8's changelog is a great demonstration of what's wrong with D's sloppy "accessor" syntax: ------------- tango.time * TimeSpan.seconds(ulong), etc. is now replaced by TimeSpan.fromSeconds(ulong), etc. The original form causes problems when people write code like: auto ts = TimeSpan.seconds(60); ts.seconds = 30; // you would think this would assign 30 seconds to ts, but what it does is create a // temporary and throw it away. ------------- The fact that D lets you freely switch between "foo(x)" and "foo = x" (at least when you're not using a return value from foo) implies that passing one argument to a function is, in the general case, conceptually related to assigning a value. And that is an absurdity and abuse of syntax on the same level as pretending that string concatenation is an "addition" or that outputting is a "<<", etc. And this "solution" that Tango was forced to use as a result of that kludge doesn't totally solve the problem since it leaves symantic gibberish like this as perfectly-compileable: ts.fromSeconds = 30; // WTF is that supposed to mean?!? But it compiles anyway!
Mar 27 2009
On Fri, 27 Mar 2009 09:09:27 +0100, Nick Sabalausky <a a.a> wrote:I don't mean to put words in the Tango crew's mouths, but IMO this piece from 0.99.8's changelog is a great demonstration of what's wrong with D's sloppy "accessor" syntax: ------------- tango.time * TimeSpan.seconds(ulong), etc. is now replaced by TimeSpan.fromSeconds(ulong), etc. The original form causes problems when people write code like: auto ts = TimeSpan.seconds(60); ts.seconds = 30; // you would think this would assign 30 seconds to ts, but what it does is create a // temporary and throw it away. ------------- The fact that D lets you freely switch between "foo(x)" and "foo = x" (at least when you're not using a return value from foo) implies that passing one argument to a function is, in the general case, conceptually related to assigning a value. And that is an absurdity and abuse of syntax on the same level as pretending that string concatenation is an "addition" or that outputting is a "<<", etc. And this "solution" that Tango was forced to use as a result of that kludge doesn't totally solve the problem since it leaves symantic gibberish like this as perfectly-compileable: ts.fromSeconds = 30; // WTF is that supposed to mean?!? But it compiles anyway!I feel the problem here is that you can access a type's static members through an instance of it, not so much the property syntax. One could argue that auto foo = TimeSpan.seconds = 30; looks weird, but writing weird code is in no way dependent on property syntax. -- Simen
Mar 27 2009
"Simen Kjaeraas" <simen.kjaras gmail.com> wrote in message news:op.urfzx0ia1hx7vj biotronic-pc.osir.hihm.no...I feel the problem here is that you can access a type's static members through an instance of it, not so much the property syntax.That didn't even occur to me. That's certainly a problem too.
Mar 27 2009
On Fri, 27 Mar 2009 13:44:48 -0400, Nick Sabalausky <a a.a> wrote:"Simen Kjaeraas" <simen.kjaras gmail.com> wrote in message news:op.urfzx0ia1hx7vj biotronic-pc.osir.hihm.no...Yes, that was my main beef with the compiler when I had to fix it. I'd prefer static member functions not be callable on instances. On the other hand, accessing static members is sometimes convenient: ReallyReallyLongStructName n; n = n.init; Note that even with the poposed fix, this is valid code which makes for much confusion: TimeSpan.fromSeconds = 30; Which essentially does nothing, but looks like it's setting a static property. I agree with you that the designer of a class should be the one to define its interface, not the user. I've always wished for the ability to specify which functions should be properties and which ones should not. // a b c are properties a = b = c = 42; translates to: set_c(42); set_b(get_c()); set_a(get_b()); -SteveI feel the problem here is that you can access a type's static members through an instance of it, not so much the property syntax.That didn't even occur to me. That's certainly a problem too.
Mar 27 2009
On Fri, 27 Mar 2009 21:56:36 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Fri, 27 Mar 2009 13:44:48 -0400, Nick Sabalausky <a a.a> wrote:int x = 5; writefln(x.init); // prints 0; how is that possible? It should certainly be either disallowed or yield 5. int x = 5; writefln(typeof(x).init); // 0 as expected Now this one is fine."Simen Kjaeraas" <simen.kjaras gmail.com> wrote in message news:op.urfzx0ia1hx7vj biotronic-pc.osir.hihm.no...Yes, that was my main beef with the compiler when I had to fix it. I'd prefer static member functions not be callable on instances. On the other hand, accessing static members is sometimes convenient: ReallyReallyLongStructName n; n = n.init;I feel the problem here is that you can access a type's static members through an instance of it, not so much the property syntax.That didn't even occur to me. That's certainly a problem too.Note that even with the poposed fix, this is valid code which makes for much confusion: TimeSpan.fromSeconds = 30; Which essentially does nothing, but looks like it's setting a static property. I agree with you that the designer of a class should be the one to define its interface, not the user. I've always wished for the ability to specify which functions should be properties and which ones should not. // a b c are properties a = b = c = 42; translates to: set_c(42); set_b(get_c()); set_a(get_b()); -Steve
Mar 27 2009
On Fri, 27 Mar 2009 15:13:16 -0400, Denis Koroskin <2korden gmail.com> wrote:On Fri, 27 Mar 2009 21:56:36 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Because init is a static member of the type. x.init is equivalent to int.init. If you want a different default, I think you do something like: typedef int myint = 5; myint x; writefln(x.init); // prints 5On Fri, 27 Mar 2009 13:44:48 -0400, Nick Sabalausky <a a.a> wrote:int x = 5; writefln(x.init); // prints 0; how is that possible?"Simen Kjaeraas" <simen.kjaras gmail.com> wrote in message news:op.urfzx0ia1hx7vj biotronic-pc.osir.hihm.no...Yes, that was my main beef with the compiler when I had to fix it. I'd prefer static member functions not be callable on instances. On the other hand, accessing static members is sometimes convenient: ReallyReallyLongStructName n; n = n.init;I feel the problem here is that you can access a type's static members through an instance of it, not so much the property syntax.That didn't even occur to me. That's certainly a problem too.It should certainly be either disallowed or yield 5. int x = 5; writefln(typeof(x).init); // 0 as expected Now this one is fine.yeah, that works, but I don't like it as much. I suppose it wouldn't be horrible to use typeof(x) everywhere you need static data, but it does make things much nicer, especially when you have things like enums or constants to just access them. -Steve
Mar 27 2009
On Fri, Mar 27, 2009 at 3:13 PM, Denis Koroskin <2korden gmail.com> wrote:int x = 5; writefln(x.init); // prints 0; how is that possible? It should certainly be either disallowed or yield 5.In DMD pre-1.017, it would print 5. The language spec was changed with that version.
Mar 27 2009
On Fri, 27 Mar 2009 22:37:39 +0300, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Fri, Mar 27, 2009 at 3:13 PM, Denis Koroskin <2korden gmail.com> wrote:Yeah, I know, but still uneasy with the spec change.int x = 5; writefln(x.init); // prints 0; how is that possible? It should certainly be either disallowed or yield 5.In DMD pre-1.017, it would print 5. The language spec was changed with that version.
Mar 27 2009
"Simen Kjaeraas" <simen.kjaras gmail.com> wrote in message news:op.urfzx0ia1hx7vj biotronic-pc.osir.hihm.no...One could argue that auto foo = TimeSpan.seconds = 30; looks weird, but writing weird code is in no way dependent on property syntax.True, but a function's/class's/data-member's interface shouldn't help facilitate weird code. The creator of the function/class/data-member knows the semantics of whatever interface they're creating, so *they* are the proper ones who should have to choose between function syntax and property syntax, *not* the user of the interface.
Mar 27 2009
On 2009-03-27 04:45:26 -0400, "Simen Kjaeraas" <simen.kjaras gmail.com> said:I feel the problem here is that you can access a type's static members through an instance of it, not so much the property syntax. One could argue that auto foo = TimeSpan.seconds = 30; looks weird, but writing weird code is in no way dependent on property syntax.Perhaps static being accessible from the instance is a problem, but you can easily work around the problem by making the function's name clearer by adding a verb. If you had: auto foo = TimeSpan.createFromSeconds = 30; it'd still look strange, sure, but the intent would still be pretty clear. So in short functions that perform an action should have a verb. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Mar 27 2009
Hello Nick,I don't mean to put words in the Tango crew's mouths, but IMO this piece from 0.99.8's changelog is a great demonstration of what's wrong with D's sloppy "accessor" syntax: ------------- tango.time * TimeSpan.seconds(ulong), etc. is now replaced by TimeSpan.fromSeconds(ulong), etc. The original form causes problems when people write code like: auto ts = TimeSpan.seconds(60); ts.seconds = 30; // you would think this would assign 30 seconds to ts, but what it does is create a // temporary and throw it away. ------------- The fact that D lets you freely switch between "foo(x)" and "foo = x" (at least when you're not using a return value from foo) implies that passing one argument to a function is, in the general case, conceptually related to assigning a value. And that is an absurdity and abuse of syntax on the same level as pretending that string concatenation is an "addition" or that outputting is a "<<", etc. And this "solution" that Tango was forced to use as a result of that kludge doesn't totally solve the problem since it leaves symantic gibberish like this as perfectly-compileable: ts.fromSeconds = 30; // WTF is that supposed to mean?!? But it compiles anyway!One option would be to only allow that fn = v syntax where fn returns void.
Mar 27 2009
On Fri, 27 Mar 2009 18:53:51 +0300, BCS <none anon.com> wrote:Hello Nick,Obscure rule and a bad idea in general. This way you can't do "a = b = c = 42;"-style chaining.I don't mean to put words in the Tango crew's mouths, but IMO this piece from 0.99.8's changelog is a great demonstration of what's wrong with D's sloppy "accessor" syntax: ------------- tango.time * TimeSpan.seconds(ulong), etc. is now replaced by TimeSpan.fromSeconds(ulong), etc. The original form causes problems when people write code like: auto ts = TimeSpan.seconds(60); ts.seconds = 30; // you would think this would assign 30 seconds to ts, but what it does is create a // temporary and throw it away. ------------- The fact that D lets you freely switch between "foo(x)" and "foo = x" (at least when you're not using a return value from foo) implies that passing one argument to a function is, in the general case, conceptually related to assigning a value. And that is an absurdity and abuse of syntax on the same level as pretending that string concatenation is an "addition" or that outputting is a "<<", etc. And this "solution" that Tango was forced to use as a result of that kludge doesn't totally solve the problem since it leaves symantic gibberish like this as perfectly-compileable: ts.fromSeconds = 30; // WTF is that supposed to mean?!? But it compiles anyway!One option would be to only allow that fn = v syntax where fn returns void.
Mar 27 2009
Hello Denis,On Fri, 27 Mar 2009 18:53:51 +0300, BCS <none anon.com> wrote:I'd say that chaining example would be a bad idea anyway. strange things would start happening if b or c altered the value or returned a different type. One option, if you insist on chaining working, would be to restrict it to void returns and have the expression evaluate to the RHS.One option would be to only allow that fn = v syntax where fn returns void.Obscure rule and a bad idea in general. This way you can't do "a = b = c = 42;"-style chaining.
Mar 27 2009
On Fri, 27 Mar 2009 18:57:50 +0300, Denis Koroskin wrote:This way you can't do "a = b = c = 42;"-style chaining.A bit off topic, but what's so good about that coding style anyway? I still think that readibilty and maintability is enhanced by coding ... // Set all to same value a = 42; b = 42; c = 42; or even ... // Set all to c's value c = 42; b = c; a = c; -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Mar 27 2009
"Derek Parnell" <derek psych.ward> wrote in message news:b3ttq8dh6euj.6tg6gfg6kfnj.dlg 40tude.net...On Fri, 27 Mar 2009 18:57:50 +0300, Denis Koroskin wrote:I've been known to use it now and then if there's a few variables I'm initing to the same value (assuming of course that the whole point is for the variables to start out at the same value). It's certainly not a huge improvement, but I see nothing wrong with it.This way you can't do "a = b = c = 42;"-style chaining.A bit off topic, but what's so good about that coding style anyway?
Mar 27 2009
"BCS" <none anon.com> wrote in message news:a6268ff401a8cb7cd0afe22784 news.digitalmars.com...That still doesn't plug all the holes. Just because a function takes one argument and returns void still doesn't necessarily imply that it does something that could be reasonably considered "setting". --------- Stdout.formatln = "Hello"; // Still doesn't make much sense --------- class Foo { // Complex set of private data members here void MutateFooInPlace(bool optionA) { // Do some sort of fancy in-place mutation of Foo // "optionA" is some sort of algorithm-adjusting option. } } auto f = new Foo(); f. MutateFooInPlace = false; // Even worse! ---------ts.fromSeconds = 30; // WTF is that supposed to mean?!? But it compiles anyway!One option would be to only allow that fn = v syntax where fn returns void.
Mar 27 2009
Nick Sabalausky wrote:I don't mean to put words in the Tango crew's mouths, but IMO this piece from 0.99.8's changelog is a great demonstration of what's wrong with D's sloppy "accessor" syntax:I agree, it's a hack. I really enjoy using properties, too, but I think
Mar 27 2009