digitalmars.D - toString ugliness
- Jerry (14/14) Dec 06 2008 toString() doesn't work inside a class member function.
- Jarrett Billingsley (2/16) Dec 06 2008 It's annoying but it's not enough to make me want to change anything. ;...
- Jerry (3/18) Dec 06 2008 As I'm thinking about this, why does this actually fail? The parameter ...
- Jarrett Billingsley (7/25) Dec 06 2008 As far as I know, it's because D does not use ADL (argument-dependent
- Ary Borenszweig (4/34) Dec 07 2008 But the overloading is obvious! It looks for toString(...) and it founds...
- Jarrett Billingsley (5/10) Dec 07 2008 That's why I said "*most* of the time" ;) I'll agree that it's a bit
- Ary Borenszweig (2/13) Dec 07 2008 Ah, I see. Well, I'd like to see such an example then. :-P
- Christopher Wright (11/27) Dec 07 2008 It usually won't be an issue, I think. You'll give your functions
- Nick Sabalausky (9/36) Dec 07 2008 I kind of like Ruby's requirement that accessing "this.whatever" *must* ...
- bearophile (7/14) Dec 07 2008 In Ruby you also use @@ for class variables (similar to static attribute...
- Sergey Gromov (8/38) Dec 07 2008 Not correct. C++ uses the same rules to build overload sets as D. That
- Christopher Wright (3/7) Dec 07 2008 I've been using C++ lately, and I'd put it a bit differently:
- Jarrett Billingsley (2/40) Dec 07 2008 Sorry.
- Jarrett Billingsley (7/25) Dec 06 2008 As far as I know, it's because D does not use ADL (argument-dependent
- Steve Schveighoffer (12/39) Dec 06 2008 Doesn't bother me at all. Using tango, I usually rename the appropriate...
- Ary Borenszweig (6/27) Dec 07 2008 It bothers me. Maybe it doesn't bother anyone else in this newsgroup
- bearophile (5/8) Dec 07 2008 I too have fallen in this little trap, but after the first time you lear...
toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name. It can be solved somewhat by documenting clearly that to!(string)(int) be used instead, which seems silly to me. I'm irritated by the 3 extra chars required to type a to!(type) template. .toString() works around the problem, but why should it be needed? This is unfortunate. Does this bother anyone else? If not, I'll return to my lurking cave :-)
Dec 06 2008
On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name. It can be solved somewhat by documenting clearly that to!(string)(int) be used instead, which seems silly to me. I'm irritated by the 3 extra chars required to type a to!(type) template. .toString() works around the problem, but why should it be needed? This is unfortunate. Does this bother anyone else? If not, I'll return to my lurking cave :-)It's annoying but it's not enough to make me want to change anything. ;)
Dec 06 2008
Jarrett Billingsley Wrote:On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:As I'm thinking about this, why does this actually fail? The parameter doesn't match the prototype for this.toString(), so why not match against the global function? Is this due to the behavior that override solves? Would marking Object.toString() as override fix the problem?toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name.
Dec 06 2008
On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn optonline.net> wrote:Jarrett Billingsley Wrote:As far as I know, it's because D does not use ADL (argument-dependent lookup). That is, it simply looks for the toString that is in the nearest enclosing scope, and if it doesn't match - too bad. Compare this behavior to C++, where it would then continue on, looking for a definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:As I'm thinking about this, why does this actually fail? The parameter doesn't match the prototype for this.toString(), so why not match against the global function? Is this due to the behavior that override solves? Would marking Object.toString() as override fix the problem?toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name.
Dec 06 2008
Jarrett Billingsley escribió:On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn optonline.net> wrote:But the overloading is obvious! It looks for toString(...) and it founds it in the class, but the overloading is wrong. So for me, it should keep looking in the enclosing scopes.Jarrett Billingsley Wrote:As far as I know, it's because D does not use ADL (argument-dependent lookup). That is, it simply looks for the toString that is in the nearest enclosing scope, and if it doesn't match - too bad. Compare this behavior to C++, where it would then continue on, looking for a definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:As I'm thinking about this, why does this actually fail? The parameter doesn't match the prototype for this.toString(), so why not match against the global function? Is this due to the behavior that override solves? Would marking Object.toString() as override fix the problem?toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name.
Dec 07 2008
On Sun, Dec 7, 2008 at 7:12 AM, Ary Borenszweig <ary esperanto.org.ar> wrote:That's why I said "*most* of the time" ;) I'll agree that it's a bit counterintuitive, but I'd rather have the compiler be a little stupid in this regard than to pay the price of unexpected function matches for a little bit of convenience.definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.But the overloading is obvious! It looks for toString(...) and it founds it in the class, but the overloading is wrong. So for me, it should keep looking in the enclosing scopes.
Dec 07 2008
Jarrett Billingsley escribió:On Sun, Dec 7, 2008 at 7:12 AM, Ary Borenszweig <ary esperanto.org.ar> wrote:Ah, I see. Well, I'd like to see such an example then. :-PThat's why I said "*most* of the time" ;) I'll agree that it's a bit counterintuitive, but I'd rather have the compiler be a little stupid in this regard than to pay the price of unexpected function matches for a little bit of convenience.definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.But the overloading is obvious! It looks for toString(...) and it founds it in the class, but the overloading is wrong. So for me, it should keep looking in the enclosing scopes.
Dec 07 2008
Ary Borenszweig wrote:Jarrett Billingsley escribió:It usually won't be an issue, I think. You'll give your functions descriptive names, and you won't have overloads in different scopes that take similar arguments. So any example I give will probably seem contrived. I certainly have only encountered this compiler error a bare handful of times, and only with toString. That said, errors of this kind would be difficult to track down, and the workaround is very simple once you know it -- and not that difficult to come up with if you don't. I think I came up using .toString without having anyone tell me about it, and if I hadn't, I would have used the fully qualified name (or an alias).On Sun, Dec 7, 2008 at 7:12 AM, Ary Borenszweig <ary esperanto.org.ar> wrote:Ah, I see. Well, I'd like to see such an example then. :-PThat's why I said "*most* of the time" ;) I'll agree that it's a bit counterintuitive, but I'd rather have the compiler be a little stupid in this regard than to pay the price of unexpected function matches for a little bit of convenience.definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.But the overloading is obvious! It looks for toString(...) and it founds it in the class, but the overloading is wrong. So for me, it should keep looking in the enclosing scopes.
Dec 07 2008
"Christopher Wright" <dhasenan gmail.com> wrote in message news:ghhbn3$2u32$1 digitalmars.com...Ary Borenszweig wrote:I kind of like Ruby's requirement that accessing "this.whatever" *must* be done like " whatever" (with the "this." part not being needed). Omitting the means you're talking about either a local identifier or a global one. I don't know if that stuff applies to member functions as well or if it's just member vars, but if it did apply to member funcs then that would certainly solve the "finding the correct toString" issue. Of course, that would probably be way too big of a syntax change for D, though.Jarrett Billingsley escribió:It usually won't be an issue, I think. You'll give your functions descriptive names, and you won't have overloads in different scopes that take similar arguments. So any example I give will probably seem contrived. I certainly have only encountered this compiler error a bare handful of times, and only with toString. That said, errors of this kind would be difficult to track down, and the workaround is very simple once you know it -- and not that difficult to come up with if you don't. I think I came up using .toString without having anyone tell me about it, and if I hadn't, I would have used the fully qualified name (or an alias).On Sun, Dec 7, 2008 at 7:12 AM, Ary Borenszweig <ary esperanto.org.ar> wrote:Ah, I see. Well, I'd like to see such an example then. :-PThat's why I said "*most* of the time" ;) I'll agree that it's a bit counterintuitive, but I'd rather have the compiler be a little stupid in this regard than to pay the price of unexpected function matches for a little bit of convenience.definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.But the overloading is obvious! It looks for toString(...) and it founds it in the class, but the overloading is wrong. So for me, it should keep looking in the enclosing scopes.
Dec 07 2008
Nick Sabalausky:I kind of like Ruby's requirement that accessing "this.whatever" *must* be done like " whatever" (with the "this." part not being needed). Omitting the means you're talking about either a local identifier or a global one. I don't know if that stuff applies to member functions as well or if it's just member vars, but if it did apply to member funcs then that would certainly solve the "finding the correct toString" issue. Of course, that would probably be way too big of a syntax change for D, though.In Ruby you also use for class variables (similar to static attributes of classes in D). I have often seen C++ code where the name of instance attributes are prefixed by "m_". In D now and then I use "this.somename" to avoid name clashes (for example with argument variables) or to make more explicit that a variable isn't local. Using a default prefix, like or $ to instance attributes in D2 code will make such code look a little ugly, but probably also more explicit too. (It's also short, shorter than "m_" and shorter than "this."). So I may end liking this syntax change. Bye, bearophile
Dec 07 2008
Sat, 6 Dec 2008 13:04:56 -0500, Jarrett Billingsley wrote:On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn optonline.net> wrote:Not correct. C++ uses the same rules to build overload sets as D. That is, a function declaration in an inner scope hides any function declarations with the same name in outer scopes. I /think/ there should be a good rationale behind this design. Actually, any declaration works like this. A variable declaration hides any declarations with the same name in the outer scopes. Probably functions follow this rule to make overloading more predictable.Jarrett Billingsley Wrote:As far as I know, it's because D does not use ADL (argument-dependent lookup). That is, it simply looks for the toString that is in the nearest enclosing scope, and if it doesn't match - too bad. Compare this behavior to C++, where it would then continue on, looking for a definition of toString that does match.On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:As I'm thinking about this, why does this actually fail? The parameter doesn't match the prototype for this.toString(), so why not match against the global function? Is this due to the behavior that override solves? Would marking Object.toString() as override fix the problem?toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name.
Dec 07 2008
Sergey Gromov wrote:Not correct. C++ uses the same rules to build overload sets as D. That is, a function declaration in an inner scope hides any function declarations with the same name in outer scopes. I /think/ there should be a good rationale behind this design.I've been using C++ lately, and I'd put it a bit differently: I think there /should/ be a good rationale behind its design.
Dec 07 2008
On Sun, Dec 7, 2008 at 5:54 PM, Sergey Gromov <snake.scaly gmail.com> wrote:Sat, 6 Dec 2008 13:04:56 -0500, Jarrett Billingsley wrote:Sorry.On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn optonline.net> wrote:Not correct. C++ uses the same rules to build overload sets as D. That is, a function declaration in an inner scope hides any function declarations with the same name in outer scopes. I /think/ there should be a good rationale behind this design. Actually, any declaration works like this. A variable declaration hides any declarations with the same name in the outer scopes. Probably functions follow this rule to make overloading more predictable.Jarrett Billingsley Wrote:As far as I know, it's because D does not use ADL (argument-dependent lookup). That is, it simply looks for the toString that is in the nearest enclosing scope, and if it doesn't match - too bad. Compare this behavior to C++, where it would then continue on, looking for a definition of toString that does match.On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:As I'm thinking about this, why does this actually fail? The parameter doesn't match the prototype for this.toString(), so why not match against the global function? Is this due to the behavior that override solves? Would marking Object.toString() as override fix the problem?toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name.
Dec 07 2008
On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn optonline.net> wrote:Jarrett Billingsley Wrote:As far as I know, it's because D does not use ADL (argument-dependent lookup). That is, it simply looks for the toString that is in the nearest enclosing scope, and if it doesn't match - too bad. Compare this behavior to C++, where it would then continue on, looking for a definition of toString that does match. Most of the time ADL leads to confusing behavior, which is why it was dropped in D.On Sat, Dec 6, 2008 at 11:21 AM, Jerry <jlquinn optonline.net> wrote:As I'm thinking about this, why does this actually fail? The parameter doesn't match the prototype for this.toString(), so why not match against the global function? Is this due to the behavior that override solves? Would marking Object.toString() as override fix the problem?toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name.
Dec 06 2008
On Sat, 06 Dec 2008 11:21:11 -0500, Jerry wrote:toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name. It can be solved somewhat by documenting clearly that to!(string)(int) be used instead, which seems silly to me. I'm irritated by the 3 extra chars required to type a to!(type) template. .toString() works around the problem, but why should it be needed? This is unfortunate. Does this bother anyone else? If not, I'll return to my lurking cave :-)Doesn't bother me at all. Using tango, I usually rename the appropriate toString module imports. i.e.: import Int = tango.text.convert.Integer; Int.toString(5); But you'd probably hate that. That's *4* more characters! Or you could alias it at the top of the module you want to use it in. alias toString toStr; The object.toString function is so well known, and so intuitive, I doubt there would be any possible way it would be changed. Nor would I want that to change. -Steve
Dec 06 2008
Jerry escribió:toString() doesn't work inside a class member function. import std.string; class A { void f() { string s = toString(5); } } This errors with junk.d(19): function object.Object.toString () does not match parameter types (int) This is a nuisance and a wart (though not a bug per-se). If the language really can't handle distinguishing this.toString() from toString(int), then std.string.toString really should have a different name. It can be solved somewhat by documenting clearly that to!(string)(int) be used instead, which seems silly to me. I'm irritated by the 3 extra chars required to type a to!(type) template. .toString() works around the problem, but why should it be needed? This is unfortunate. Does this bother anyone else? If not, I'll return to my lurking cave :-)It bothers me. Maybe it doesn't bother anyone else in this newsgroup because they already fell in that trap and they know the solution or the workarounds. For me, there shouldn't be a workaround, it should just work. If I, a human, can understand that toString(int) can't never, EVER, be confused with toString(), why can't the compiler see the same?
Dec 07 2008
Ary Borenszweig:It bothers me. Maybe it doesn't bother anyone else in this newsgroup because they already fell in that trap and they know the solution or the workarounds.I too have fallen in this little trap, but after the first time you learn to add a "." before toString. I use str()/repr() functions from my dlibs to avoid name clashes with toString() (see below), so I think that it may be better for the method and the global function to have different names. Python avoids such problem because the function and the method have different names: the global built-in functions are named str() and repr() and the methods are __str__() and __repr__(). (each function calls the relative method. If __str__ is absent, __repr__ is called as fallback). str() gives a human-readable textual representation of something, and repr() gives a string representation that whenever possible is the text you have to write to define that thing in the code, so generally eval(repr(x)) == x. Bye, bearophile
Dec 07 2008