digitalmars.D - Omittable parens is an evil
- Koroskin Denis (59/59) Jul 19 2008 Sure, it's a handy feature for properties, but it is a source of too man...
- Mike (19/20) Jul 19 2008 This has come up multiple times - that's one of the few things where C# ...
- Nick Sabalausky (45/63) Jul 19 2008 I've always been in favor of this sort of thing as well. My reasoning is...
- Jarrett Billingsley (15/31) Jul 19 2008 I agree, but having to reimplement the opXxxAssign methods for every
- Bruno Medeiros (23/61) Aug 04 2008 I agree, there is not worth in having to define another accessor other
- Jarrett Billingsley (13/30) Aug 04 2008 I kind of like that. One of the things that a true property construct w...
- Bruno Medeiros (7/11) Aug 11 2008 Nowadays I'm much more busy than I used to be, so trying to keep with
- Nick Sabalausky (44/62) Jul 19 2008 I'm just kind of brainstorming possible improvements to the usual way of...
- Mike (17/17) Jul 19 2008 On Sat, 19 Jul 2008 21:42:22 +0200, Nick Sabalausky wrote:
- Nick Sabalausky (9/24) Jul 19 2008 My thought on that scenario was that if nothing within the "property int...
- Nick Sabalausky (8/67) Jul 19 2008 I'm not sure if I'm completely following you here. Are you basically say...
- Jarrett Billingsley (3/7) Jul 19 2008 It's true!
- Mike (9/16) Jul 19 2008 For me it's mostly that there's a clear _VISUAL_ distinction between "th...
- Manfred_Nowak (15/18) Jul 19 2008 Yes it is extremely extentable because one can incorporate calls to
- Nick Sabalausky (7/21) Jul 19 2008 When looking at code that accesses a property or uses an operator that i...
- Robert Fraser (3/30) Jul 19 2008 I agree. A property getter should be idempotent (cached values aside).
- Manfred_Nowak (7/8) Jul 20 2008 How can one assure this?
- Jarrett Billingsley (3/6) Jul 20 2008 Making it const/invariant?
- Ary Borenszweig (2/10) Jul 20 2008 Maybe marking the getter as const.
- Robert Fraser (9/21) Jul 20 2008 You can't, of course. You can mark it
- Manfred_Nowak (28/29) Jul 20 2008 The need for such a distinction is unclear to me, because it seems to
- Mike (9/9) Jul 20 2008 Hmm. I thought the whole thing since yesterday, and this is what I think...
- =?ISO-8859-1?Q?Tomasz_Sowi=f1ski?= (2/5) Jul 20 2008 now that's a good one!
- =?ISO-8859-1?Q?Tomasz_Sowi=f1ski?= (4/9) Jul 19 2008 I agree. When coding, at first, I was glad to be able to snip the parens...
- bearophile (5/6) Jul 20 2008 I agree that omittable parens is bad, I always put them.
- downs (5/13) Jul 20 2008 Seeing as I don't share your opinion on this topic, I humbly submit that...
- =?ISO-8859-1?Q?Tomasz_Sowi=f1ski?= (4/19) Jul 20 2008 I think functions should be called thisWay() and function addresses shou...
- Koroskin Denis (7/38) Jul 20 2008 I think it should be used to address to the function itself, like
- =?ISO-8859-1?Q?Tomasz_Sowi=f1ski?= (2/8) Jul 20 2008 Good idea... Now all we have to do is figure out what this stuff has to ...
- Nick Sabalausky (5/47) Jul 20 2008 I've always liked in other languages where the "function pointer/referen...
- downs (6/18) Jul 20 2008 For what it's worth, I'd hate that. A symbol is not its address.
- Simen Kjaeraas (13/44) Jul 20 2008 I usually think that a function called without parens should have no
- Bruno Medeiros (12/25) Aug 04 2008 I agree. In the few D code I've written, I've already run into several
- Manfred_Nowak (16/19) Jul 19 2008 Whre is the bug?
- Koroskin Denis (7/22) Jul 19 2008 I expected to get `FZv' or, better, `_D4test4Test4testMFZv' and not `v' ...
Sure, it's a handy feature for properties, but it is a source of too many bugs. I think that it is against the D design of avoiding features that are error-prone. Today I once again came across with a problem with them and it's still open: class Test { void test() {} } How do I get a mangle of Test.test? writefln(Test.test.mangleof); // Should be ok, but prints v, which is not what I need writefln((&Test.test).mangleof); // prints PFZv, which is a pointer to function writefln(__traits(getMember, new Test(), "test").mangleof); // prints v (void, return value) If you have other suggestions, please say, I need the solution. Custom mangling is not an option. The following example was shown in bugzilla and it once again proves that ommitable parens lead to errors: void main() { int run() { // do the stuff return 0; } Thread thread = new Thread(run); // run -> &run, this(int) is called instead of this(int delegate() dg). } Why not have special syntax for properties, like: class Array(T) { property T* ptr() { return _ptr; } property int length() { return _length; } void resize(int newSize) { // code here } int capacity() { // code here } private int _length; private T* _ptr; } Usage: Array!(int) array = new Array!(int); int len = array.length; array.resize = 100; // forbidden int capacity = array.capacity(); // okay It is a breaking change, sure, but it solves the design flaw and fix is trivial.
Jul 19 2008
On Sat, 19 Jul 2008 15:32:36 +0200, Koroskin Denis <2korden+dmd gmail.com> wrote:Why not have special syntax for properties, like:wins over D. If I may repeat a suggestion I made once, maybe Walter can be hypnotized into implementing it if I just repeat it often enough :) class foo { private int _bar; property int bar { opGet() { return _bar; } opSet(auto value) { _bar = value; } opAddAssign(auto value) { _bar += value; } // it's extremely extendable! } } -Mike -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jul 19 2008
"Mike" <vertex gmx.at> wrote in message news:op.uejk9fs8kgfkbn lucia...On Sat, 19 Jul 2008 15:32:36 +0200, Koroskin Denis <2korden+dmd gmail.com> wrote:I've always been in favor of this sort of thing as well. My reasoning is that "member variable" vs "getter/setter function" is an implementation detail, and implementation details should be possible to abstract away. The creator of a library/API/etc should be able to design their classes in way such that if a class has a property (for instance, the color of it), then the user of the object wouldn't have to stop and think "Ok, now is color accessed as a member variable or through getters/setters?". The library creator should be able to make it so that it's the same either way. Additionally, the ability to abstract away the "member variable" vs "getter/setter function" distinction would allow a library/API creator to develop like this: When first creating a class, the class has a property "x". At this point in time, there's nothing special that needs to be done when "x" is read from or written to. So implementing "x" as a member variable is perfectly sufficient. Later on, the class gains enhancements, some of which require additional actions to be taken whenever "x" is accessed. You're working on a library/API, so you don't want this change to be a breaking one. So instead of needing to religously implement all trivial and non-trivial properties as getters/setters right from day one in order to avoid this situation, all you'd need to do is say "Ok, property 'x' now needs getter/setter functionlity, so I'll convert it into this special 'property accessing' feature of the language instead of getter/setter functions, and that way my change won't break anything." A third reason: Project management (Although I really think of this sort of thing more as being "lead programmer" than "manager". A manager's role is administrative, they're there to make sure the developers have what they need to do their job - chairs, computers, tools, distraction-free workspace, competent co-workers, etc. It's not their role to go sticking their fingers into the code. But I digress.). Just like how the built-in unittests, documentation, invariants, and debug conditionals allow...whoever is in charge...to have one less thing to arbitrarily define in their "coding standards", this would alliviate the need to define a standard naming convention for getters/setters. Whatever standard variable naming convention exists would be sufficient. So, four reasons for a special "property accessing" syntax like the above: 1. The "member variable" vs "getter/setter function" distinction is an implementation detail, and as such, should be possible to abstract away. 2. User of a library doesn't always have to think "Ok, now is this property implemented as a member variable or as getters/setters?". 3. Creator of a library can change a member variable into a "getter/setter" of sorts without it being a breaking change, and without needing to religously implement all properties as getters/setters from day one. 4. Lead developer doesn't have to come up with an arbitrary "getter/setter" naming convention. They can simply say "Just use the built-in 'property accessing' syntax, and follow the usual variable naming conventions".Why not have special syntax for properties, like:wins over D. If I may repeat a suggestion I made once, maybe Walter can be hypnotized into implementing it if I just repeat it often enough :) class foo { private int _bar; property int bar { opGet() { return _bar; } opSet(auto value) { _bar = value; } opAddAssign(auto value) { _bar += value; } // it's extremely extendable! } } -Mike
Jul 19 2008
"Mike" <vertex gmx.at> wrote in message news:op.uejk9fs8kgfkbn lucia...On Sat, 19 Jul 2008 15:32:36 +0200, Koroskin Denis <2korden+dmd gmail.com> wrote:I agree, but having to reimplement the opXxxAssign methods for every property would quickly become tedious. A much simpler way to do it is to define that: obj.property op= expr; is exactly the same as: obj.property.opSet(obj.property.opGet() op expr); properties to overload the default behavior, but it'd at least have a reasonable fallback. In the initial designs for MiniD, when it was still a statically-typed language, I defined them exactly in this way, and then abstracted the idea by having a 'namespace' construct which could be used to implement properties, group symbols logically, and so on. None of this will ever get into D.Why not have special syntax for properties, like:wins over D. If I may repeat a suggestion I made once, maybe Walter can be hypnotized into implementing it if I just repeat it often enough :) class foo { private int _bar; property int bar { opGet() { return _bar; } opSet(auto value) { _bar = value; } opAddAssign(auto value) { _bar += value; } // it's extremely extendable! }
Jul 19 2008
Jarrett Billingsley wrote:"Mike" <vertex gmx.at> wrote in message news:op.uejk9fs8kgfkbn lucia...I agree, there is not worth in having to define another accessor other than get or set. My initial brainstorming gives me this design: class Foo { private int bar; int op_bar() { return bar; } // getter int op_bar(int value) { return bar = value; } // setter } No additional "property" syntax is required. You may note that this is more redundant (both the "int" type and the "bar" name have duplicate occurrences). However, if your properties have default getters and setters (the ones that only get and set respectively), then you can just use a mixin to avoid the redundancies: class Foo { private int bar; mixin(propGetSet!(bar)); }On Sat, 19 Jul 2008 15:32:36 +0200, Koroskin Denis <2korden+dmd gmail.com> wrote:I agree, but having to reimplement the opXxxAssign methods for every property would quickly become tedious. A much simpler way to do it is to define that: obj.property op= expr; is exactly the same as: obj.property.opSet(obj.property.opGet() op expr); properties to overload the default behavior, but it'd at least have a reasonable fallback.Why not have special syntax for properties, like:wins over D. If I may repeat a suggestion I made once, maybe Walter can be hypnotized into implementing it if I just repeat it often enough :) class foo { private int _bar; property int bar { opGet() { return _bar; } opSet(auto value) { _bar = value; } opAddAssign(auto value) { _bar += value; } // it's extremely extendable! }None of this will ever get into D.Most likely :( And it sucks because the implicit function call syntax is more problem than worth. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 04 2008
"Bruno Medeiros" <brunodomedeiros+spam com.gmail> wrote in message news:g77dh7$1k7q$1 digitalmars.com...My initial brainstorming gives me this design: class Foo { private int bar; int op_bar() { return bar; } // getter int op_bar(int value) { return bar = value; } // setter } No additional "property" syntax is required. You may note that this is more redundant (both the "int" type and the "bar" name have duplicate occurrences). However, if your properties have default getters and setters (the ones that only get and set respectively), then you can just use a mixin to avoid the redundancies: class Foo { private int bar; mixin(propGetSet!(bar)); }I kind of like that. One of the things that a true property construct would enable, however, is better information when introspecting types. I know that in writing the binding library for MiniD (and Kirk has encountered this in PyD as well), I've really wished that there were some way to get the getter/setter(s) of a property given a name, instead of having to derive those types and running the risk that the class writer did something weird, like having two params on the setter with the second one optional. If we had true properties, the language could be queried for this kind of information and types would be restricted.Most likely :( And it sucks because the implicit function call syntax is more problem than worth.I feel the same about const-correctness. Sigh, whatever. OT, you often tend to reply about two weeks late. Why is that?
Aug 04 2008
Jarrett Billingsley wrote:OT, you often tend to reply about two weeks late. Why is that?Nowadays I'm much more busy than I used to be, so trying to keep with the newsgroups is more complicated. I usually only have time for that in the weekends. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 11 2008
"Mike" <vertex gmx.at> wrote in message news:op.uejk9fs8kgfkbn lucia...On Sat, 19 Jul 2008 15:32:36 +0200, Koroskin Denis <2korden+dmd gmail.com> wrote:I'm just kind of brainstorming possible improvements to the usual way of doing properties. What if the above were adjusted into something like this (there's a few things I've done differently here): class foo { // Similar to how classes define an implict member "this", // "property int bar" defines an implicit "private int bar.value" // (Or maybe "protected int bar.value"? Or maybe adjustable somehow?). // This 1, elimininates the need to manually create "private _bar" // and 2, follows in the spirit of naming all constructors "this" // instead of having a different ctor name for each class // (and therefore achieves the same benefits - such as easier renaming). property int bar { // "get" and "set" can each be set separately to "public", "private", "protected" // (Maybe "protected" would be useless, though? Depends if these should // be overrideable.) get { return value; } set { value = set; } // The rvalue "set" is an implied param, and // works just like the implied "value" in // Never needed, but possibly allowed just for things like performance. opAddAssign(auto addend) { value += addend; } } private func() { Stdout.formatln("{}", this.bar); // Use property Stdout.formatln("{}", this.bar.value); // Sidestep property } } void main() { int x; auto f = new foo(); f.bar = 5; // ok x = f.bar; // ok f.func(); // ok, displays "5" twice f.bar.value = 7; // Illegal, "bar.value" is private to "foo" x = f.bar.value; // Illegal, "bar.value" is private to "foo" }Why not have special syntax for properties, like:wins over D. If I may repeat a suggestion I made once, maybe Walter can be hypnotized into implementing it if I just repeat it often enough :) class foo { private int _bar; property int bar { opGet() { return _bar; } opSet(auto value) { _bar = value; } opAddAssign(auto value) { _bar += value; } // it's extremely extendable! } } -Mike
Jul 19 2008
On Sat, 19 Jul 2008 21:42:22 +0200, Nick Sabalausky <a a.a> wrote: Hey - I like that implicit value declaration very much. However, there needs to be a way to declare pseudo properties (without the implicit value), so I'd add an initializer to the property: class foo { property int bar { value = void; // this is the initial value; void means that there is no implicit value // here be getters/setters } } Maybe something like that? -Mike -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jul 19 2008
"Mike" <vertex gmx.at> wrote in message news:op.uej2aznskgfkbn lucia...On Sat, 19 Jul 2008 21:42:22 +0200, Nick Sabalausky <a a.a> wrote: Hey - I like that implicit value declaration very much. However, there needs to be a way to declare pseudo properties (without the implicit value), so I'd add an initializer to the property: class foo { property int bar { value = void; // this is the initial value; void means that there is no implicit value // here be getters/setters } } Maybe something like that? -MikeMy thought on that scenario was that if nothing within the "property int bar" block actually accesses the implied "value" member (I would think that wouldn't be too hard to detect, but maybe I'm wrong), then any access to the implied "value" from outside the block would be either completely meaningless or a sign that something is being done wrong. So in that case, the implied "value" is sort of "optimized away" (in a mannar of speaking, since it's not exactly the same as normal "optimizing away") and any attempt to access it from outside the block becomes an error.
Jul 19 2008
"Koroskin Denis" <2korden+dmd gmail.com> wrote in message news:op.uejjwmv6n8fdl4 korden...Sure, it's a handy feature for properties, but it is a source of too many bugs. I think that it is against the D design of avoiding features that are error-prone. Today I once again came across with a problem with them and it's still open: class Test { void test() {} } How do I get a mangle of Test.test? writefln(Test.test.mangleof); // Should be ok, but prints v, which is not what I need writefln((&Test.test).mangleof); // prints PFZv, which is a pointer to function writefln(__traits(getMember, new Test(), "test").mangleof); // prints v (void, return value) If you have other suggestions, please say, I need the solution. Custom mangling is not an option. The following example was shown in bugzilla and it once again proves that ommitable parens lead to errors: void main() { int run() { // do the stuff return 0; } Thread thread = new Thread(run); // run -> &run, this(int) is called instead of this(int delegate() dg). } Why not have special syntax for properties, like: class Array(T) { property T* ptr() { return _ptr; } property int length() { return _length; } void resize(int newSize) { // code here } int capacity() { // code here } private int _length; private T* _ptr; } Usage: Array!(int) array = new Array!(int); int len = array.length; array.resize = 100; // forbidden int capacity = array.capacity(); // okay It is a breaking change, sure, but it solves the design flaw and fix is trivial.I'm not sure if I'm completely following you here. Are you basically saying that being able to call function foo by shortening "foo();" into "foo;" confuses the issue of whether you're referring to the function itself or actually trying to invoke it? If so, then 1. I should pay more attention because I didn't realize you could do that ;). And 2. I agree.
Jul 19 2008
"Nick Sabalausky" <a a.a> wrote in message news:g5tdll$2sjj$1 digitalmars.com...I'm not sure if I'm completely following you here. Are you basically saying that being able to call function foo by shortening "foo();" into "foo;" confuses the issue of whether you're referring to the function itself or actually trying to invoke it?It's true!
Jul 19 2008
On Sat, 19 Jul 2008 21:03:28 +0200, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:"Nick Sabalausky" <a a.a> wrote in message news:g5tdll$2sjj$1 digitalmars.com...For me it's mostly that there's a clear _VISUAL_ distinction between "this does something" (parens) and "this is data" (no parens); and in D there's no difference in this one (arbitrary) edge case. It's easy to "eyeball scan" code using parens pairs as visual anchors. -Mike -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/I'm not sure if I'm completely following you here. Are you basically saying that being able to call function foo by shortening "foo();" into "foo;" confuses the issue of whether you're referring to the function itself or actually trying to invoke it?It's true!
Jul 19 2008
Mike wrote:"this does something" (parens) and "this is data" (no parens)Compare this with this extract of your other posting:opAddAssign(auto value) { _bar += value; } // it's extremely extendable!Yes it is extremely extentable because one can incorporate calls to some arbitrary functions into the body of `opAddAssign': opAddAssign(auto value) { _bar += value; action(); procedure(); } ... bang!!! Your "clear _VISUAL_ distinction" has been lost. -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
Jul 19 2008
"Manfred_Nowak" <svv1999 hotmail.com> wrote in message news:g5tmqq$b99$2 digitalmars.com...Mike wrote:When looking at code that accesses a property or uses an operator that is overloadable, you don't usually need to know if extra processing is going on behind-the-scenes (typically only when optimizing). But when looking at code that involves a function, the distrinction between "invoked"/"not invoked" is almost always (if not always) a very important make-or-break matter."this does something" (parens) and "this is data" (no parens)Compare this with this extract of your other posting:opAddAssign(auto value) { _bar += value; } // it's extremely extendable!Yes it is extremely extentable because one can incorporate calls to some arbitrary functions into the body of `opAddAssign': opAddAssign(auto value) { _bar += value; action(); procedure(); } ... bang!!! Your "clear _VISUAL_ distinction" has been lost. -manfred
Jul 19 2008
Nick Sabalausky wrote:"Manfred_Nowak" <svv1999 hotmail.com> wrote in message news:g5tmqq$b99$2 digitalmars.com...I agree. A property getter should be idempotent (cached values aside). That cannot be assumed about all parameter-less functions.Mike wrote:When looking at code that accesses a property or uses an operator that is overloadable, you don't usually need to know if extra processing is going on behind-the-scenes (typically only when optimizing). But when looking at code that involves a function, the distrinction between "invoked"/"not invoked" is almost always (if not always) a very important make-or-break matter."this does something" (parens) and "this is data" (no parens)Compare this with this extract of your other posting:opAddAssign(auto value) { _bar += value; } // it's extremely extendable!Yes it is extremely extentable because one can incorporate calls to some arbitrary functions into the body of `opAddAssign': opAddAssign(auto value) { _bar += value; action(); procedure(); } ... bang!!! Your "clear _VISUAL_ distinction" has been lost. -manfred
Jul 19 2008
Robert Fraser wrote:A property getter should be idempotentHow can one assure this? -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
Jul 20 2008
"Manfred_Nowak" <svv1999 hotmail.com> wrote in message news:g5vgr4$1buh$2 digitalmars.com...Robert Fraser wrote:Making it const/invariant?A property getter should be idempotentHow can one assure this?
Jul 20 2008
Manfred_Nowak a écrit :Robert Fraser wrote:Maybe marking the getter as const.A property getter should be idempotentHow can one assure this? -manfred
Jul 20 2008
Manfred_Nowak Wrote:Robert Fraser wrote:You can't, of course. You can mark it invariant, but it may not be in the face of cached values or non-memory stores. It's just an assumption many people make and my own rule whether to make something a function or a property. It might be an argument for property specific syntax' though.A property getter should be idempotentHow can one assure this? -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
Jul 20 2008
Nick Sabalausky wrote:distrinction between "invoked"/"not invoked"The need for such a distinction is unclear to me, because it seems to be dependent on the level of abstraction one is able to tolerate. Example: `int a; a= 1;' can be imagined as writing the value `1' on some peace of paper labeled `a'. Under this abstraction one need not care about the physical quality or location of the paper or the writing utensil---or some agent watching that peace of paper and starting some strange action on detecting the value 1. I.e., although there might be some actions going on, when one assigns a value to a variable, they are moot. Please note, that it is the habit of thinking, that makes `f' passive and `f()' active. Digital Mars D introduces indeed a change of paradigm into this habit, by peeling off that hiding cover of abstraction. It should stay this way. The only shortcoming I see, is that there is no element in the language that expresses the wish to have no actions on using some identifier, which is similar to the wish to have some constant values. to express that one does not want anything executed, even if T represents a class with overloaded opAssign. -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
Jul 20 2008
Hmm. I thought the whole thing since yesterday, and this is what I think describes it best: foo. // <- subject foo; // <- object foo(); // <- verb So it's not a technical question at all, but a grammatical (it only affects syntax anyway). -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jul 20 2008
Mike Wrote:foo. // <- subject foo; // <- object foo(); // <- verbnow that's a good one!
Jul 20 2008
Mike Wrote:For me it's mostly that there's a clear _VISUAL_ distinction between "this does something" (parens) and "this is data" (no parens); and in D there's no difference in this one (arbitrary) edge case. It's easy to "eyeball scan" code using parens pairs as visual anchors.I agree. When coding, at first, I was glad to be able to snip the parens (makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart. Tomek
Jul 19 2008
Tomasz Sowiński:When coding, at first, I was glad to be able to snip the parens (makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart.<I agree that omittable parens is bad, I always put them. If parens become compulsive you don't need to use "&somefunc", you just use "somefunc" to denote the pointer/delegate and "somefunc()" to call it. Bye, bearophile
Jul 20 2008
bearophile wrote:Tomasz Sowiński:Seeing as I don't share your opinion on this topic, I humbly submit that this is not a problem with the language but with the coders, specifically, people who have used function pointers in C. Since I acquired D before I had much need for that atrocious syntax, &function has always made more sense to me. Because of this, I do not see a problem with foo or foo() - both are clearly not the function address. --downsWhen coding, at first, I was glad to be able to snip the parens (makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart.<I agree that omittable parens is bad, I always put them. If parens become compulsive you don't need to use "&somefunc", you just use "somefunc" to denote the pointer/delegate and "somefunc()" to call it. Bye, bearophile
Jul 20 2008
downs Wrote:bearophile wrote:I think functions should be called thisWay() and function addresses should be obtained &thisWay. But then we would have the question what should thisWay symbol mean without parens or ampersand? Maybe it shouldn't mean anything? or use it only to pass functions into other functions as arguments? hm... TomekTomasz Sowiński:Seeing as I don't share your opinion on this topic, I humbly submit that this is not a problem with the language but with the coders, specifically, people who have used function pointers in C. Since I acquired D before I had much need for that atrocious syntax, &function has always made more sense to me. Because of this, I do not see a problem with foo or foo() - both are clearly not the function address.When coding, at first, I was glad to be able to snip the parens (makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart.<I agree that omittable parens is bad, I always put them. If parens become compulsive you don't need to use "&somefunc", you just use "somefunc" to denote the pointer/delegate and "somefunc()" to call it. Bye, bearophile
Jul 20 2008
On Sun, 20 Jul 2008 23:56:26 +0400, Tomasz SowiƱski <tomeksowi gmail.com> wrote:downs Wrote:I think it should be used to address to the function itself, like typeof(func), func.stringof, func.mangleof, etc. func() <- function result &func <- function pointer func <- function itselfbearophile wrote:I think functions should be called thisWay() and function addresses should be obtained &thisWay. But then we would have the question what should thisWay symbol mean without parens or ampersand? Maybe it shouldn't mean anything? or use it only to pass functions into other functions as arguments? hm... TomekTomasz SowiƱski:(makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart.<When coding, at first, I was glad to be able to snip the parensI agree that omittable parens is bad, I always put them. If parens become compulsive you don't need to use "&somefunc", youjust use "somefunc" to denote the pointer/delegate and "somefunc()" to call it.Bye, bearophileSeeing as I don't share your opinion on this topic, I humbly submit that this is not a problem with the language but with the coders, specifically, people who have used function pointers in C. Since I acquired D before I had much need for that atrocious syntax, &function has always made more sense to me. Because of this, I do not see a problem with foo or foo() - both are clearly not the function address.
Jul 20 2008
Koroskin Denis Wrote:I think it should be used to address to the function itself, like typeof(func), func.stringof, func.mangleof, etc. func() <- function result &func <- function pointer func <- function itselfGood idea... Now all we have to do is figure out what this stuff has to do with const, to make Walter think about this :)
Jul 20 2008
"Koroskin Denis" <2korden gmail.com> wrote in message news:op.uelw2ttaenyajd worker...On Sun, 20 Jul 2008 23:56:26 +0400, Tomasz Sowiński <tomeksowi gmail.com> wrote:I've always liked in other languages where the "function pointer/reference" and "function itself" are considered one and the same. This just seems like extra unnecessary complexity.downs Wrote:I think it should be used to address to the function itself, like typeof(func), func.stringof, func.mangleof, etc. func() <- function result &func <- function pointer func <- function itselfbearophile wrote:I think functions should be called thisWay() and function addresses should be obtained &thisWay. But then we would have the question what should thisWay symbol mean without parens or ampersand? Maybe it shouldn't mean anything? or use it only to pass functions into other functions as arguments? hm... TomekTomasz Sowiński:(makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart.<When coding, at first, I was glad to be able to snip the parensI agree that omittable parens is bad, I always put them. If parens become compulsive you don't need to use "&somefunc", youjust use "somefunc" to denote the pointer/delegate and "somefunc()" to call it.Bye, bearophileSeeing as I don't share your opinion on this topic, I humbly submit that this is not a problem with the language but with the coders, specifically, people who have used function pointers in C. Since I acquired D before I had much need for that atrocious syntax, &function has always made more sense to me. Because of this, I do not see a problem with foo or foo() - both are clearly not the function address.
Jul 20 2008
Nick Sabalausky wrote:For what it's worth, I'd hate that. A symbol is not its address. It would be the same as saying "float f. I'd like f and &f to be the same. " It's simply not true. (I blame C) --downsI think it should be used to address to the function itself, like typeof(func), func.stringof, func.mangleof, etc. func() <- function result &func <- function pointer func <- function itselfI've always liked in other languages where the "function pointer/reference" and "function itself" are considered one and the same. This just seems like extra unnecessary complexity.
Jul 20 2008
Tomasz Sowiński <tomeksowi gmail.com> wrote:downs Wrote:I usually think that a function called without parens should have no side effects (except, of course, when used as the lhs. Also, debug code and logging are also allowed to have side effects). So, SomeFunc(); // is a valid line SomeFunc; // is invalid SomeVar = SomeFunc; // is valid (getter) SomeOtherFunc = SomeFunc(); // is valid (setter) Of course, this is only a coding standard I have set for myself, but I think it makes code easier to read and understand. As we all know, WTFs/min is the best way to measure code quality. http://www.osnews.com/images/comics/wtfm.jpg -- Simenbearophile wrote:I think functions should be called thisWay() and function addresses should be obtained &thisWay. But then we would have the question what should thisWay symbol mean without parens or ampersand? Maybe it shouldn't mean anything? or use it only to pass functions into other functions as arguments? hm... TomekTomasz Sowiński:(makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart.<When coding, at first, I was glad to be able to snip the parensI agree that omittable parens is bad, I always put them. If parens become compulsive you don't need to use "&somefunc", youjust use "somefunc" to denote the pointer/delegate and "somefunc()" to call it.Bye, bearophileSeeing as I don't share your opinion on this topic, I humbly submit that this is not a problem with the language but with the coders, specifically, people who have used function pointers in C. Since I acquired D before I had much need for that atrocious syntax, &function has always made more sense to me. Because of this, I do not see a problem with foo or foo() - both are clearly not the function address.
Jul 20 2008
Tomasz Sowiński wrote:Mike Wrote:I agree. In the few D code I've written, I've already run into several bouts with that problem. I'm sure it looked cool at first ("hey, here's a simple trick that allows one to implement properties cleanly"), but while it implements properties "cleanly", it messes up function invocation and introspection *a lot*... :( I think the ommitable parenthesis syntax should be removed, and a proper syntax for properties created (and I don't mind that the first is done before the second is). -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DFor me it's mostly that there's a clear _VISUAL_ distinction between "this does something" (parens) and "this is data" (no parens); and in D there's no difference in this one (arbitrary) edge case. It's easy to "eyeball scan" code using parens pairs as visual anchors.I agree. When coding, at first, I was glad to be able to snip the parens (makes code look cleaner), but then I came to the same conclusion - the illusory cleanness of code strikes back in the form of trouble with telling "something" and "do something" apart. Tomek
Aug 04 2008
Koroskin Denis wrote:writefln((&Test.test).mangleof); // prints PFZv, which is a pointer to functionWhre is the bug? writefln( typeof( Test.test).stringof); writefln( typeof( Test.test).mangleof); writefln( typeof( Test.test()).stringof); writefln( typeof( Test.test()).mangleof); prints (void())() v void v -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
Jul 19 2008
On Sun, 20 Jul 2008 01:26:53 +0400, Manfred_Nowak <svv1999 hotmail.com> wrote:Koroskin Denis wrote:I expected to get `FZv' or, better, `_D4test4Test4testMFZv' and not `v' nor `(void())()'. The only way I have found so far is to strip the function body and analyze compiler error message: Error 42: Symbol Undefined _D4test4Test4testMFZvwritefln((&Test.test).mangleof); // prints PFZv, which is a pointer to functionWhre is the bug? writefln( typeof( Test.test).stringof); writefln( typeof( Test.test).mangleof); writefln( typeof( Test.test()).stringof); writefln( typeof( Test.test()).mangleof); prints (void())() v void v -manfred
Jul 19 2008