Bug or Feature? compile error: to!string(const Object)

Wanderer via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 2 04:33:54 PDT 2014


On Wednesday, 2 July 2014 at 09:24:39 UTC, Jonathan M Davis via 
Digitalmars-d wrote:
> The ~ operator has nothing to do with toString. Strings are 
> arrays, and ~
> works with arrays already. ~ doesn't work with Object and will 
> only work with
> user-defined types which define opBinary!"~". The only thing 
> that removing
> toString from Object will affect would be the ability to call 
> toString on
> Object directly instead of on a reference of a derived class 
> type, which
> really doesn't lose much, since it's arguably a horrible idea 
> to be passing
> Object around anyway. All of the code in druntime and Phobos 
> which deals with
> toString is already templated, so it doesn't need to operate on 
> Object
> directly and doesn't need toString to be on Object, just on the 
> derived types
> that a program declares.
>
> Having toString, opEquals, opCmp, and toHash on Object is 
> fundamentally broken
> in the face of const, @safe, nothrow, etc. because we're forced 
> to either put
> the attributes on them or not. If we put them on them, then 
> those functions
> are restricted by those attributes, which is unacceptable in 
> many cases (e.g.
> a class which lazily loads its members would not work with a 
> const opEquals),
> and if we don't put those attributes on them (as is currently 
> the case), then
> you can't do things like have call toString on a const object.
>
> Given the power of D's templates, we do not need to put 
> opEquals, toString,
> opCmp, or toHash on Object. Languages like Java and C# are 
> forced to, because
> they do not have proper templates and thus have to use Object 
> directly in many
> cases. We do not have that problem, and putting those functions 
> on Object is a
> mistake from early in D's design that we need to correct in 
> order to be able
> to use @safe, const, nothrow, etc. with classes correctly.
>
> - Jonathan M Davis

"~" operator has to do with toString(), because it performs 
string concatenation (at least documentation says so) and 
toString() is the common way to convert arbitrary object into a 
string.

Having ~ operator implemented the way you explained - via 
opBinary!"~" in each class and not in Object class - looks like a 
bad idea to me, because 1) the same concatenation code will be 
duplicated across various classes, including user-defined ones, 
and 2) user-defined classes can define "~" in some uncommon way 
which would confuse everyone who uses these classes. Java's 
approach (one common implementation of the "+" operator for 
strings concatenation) only requires user classes to define 
toString() method without redefining string operations, which is 
convenient.

"Languages like Java and C# are forced to, because they do not 
have proper templates and thus have to use Object directly in 
many cases."

That's not exactly true. The main reason why Object class has 
these methods, is the ability to define general contracts for 
these methods. For example, Object defines once and for all that 
toString() returns String representing object's contents, or that 
equals() and hashCode() results comply with each other. If you 
remove these methods from Object, you will dispense these 
contracts as well, forcing programmers to implement these methods 
in least predictable way. That will cause chaos.


More information about the Digitalmars-d mailing list