Jump to page: 1 2
Thread overview
toString ugliness
Dec 06, 2008
Jerry
Dec 06, 2008
Jerry
Dec 07, 2008
Ary Borenszweig
Dec 07, 2008
Ary Borenszweig
Dec 07, 2008
Christopher Wright
Dec 07, 2008
Nick Sabalausky
Dec 07, 2008
bearophile
Dec 07, 2008
Sergey Gromov
Dec 07, 2008
Christopher Wright
Dec 07, 2008
Ary Borenszweig
Dec 07, 2008
bearophile
December 06, 2008
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 :-)
December 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.  ;)
December 06, 2008
Jarrett Billingsley Wrote:

> 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.

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?

December 06, 2008
On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn@optonline.net> wrote:
> Jarrett Billingsley Wrote:
>
>> 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.
>
> 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?
>
>

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.
December 06, 2008
On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn@optonline.net> wrote:
> Jarrett Billingsley Wrote:
>
>> 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.
>
> 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?
>
>

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.
December 07, 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
December 07, 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?
December 07, 2008
Jarrett Billingsley escribió:
> On Sat, Dec 6, 2008 at 12:11 PM, Jerry <jlquinn@optonline.net> wrote:
>> Jarrett Billingsley Wrote:
>>
>>> 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.
>> 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?
>>
>>
> 
> 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.

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.
December 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
December 07, 2008
On Sun, Dec 7, 2008 at 7:12 AM, Ary Borenszweig <ary@esperanto.org.ar> wrote:
>> 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.

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.
« First   ‹ Prev
1 2