On Thursday, 12 July 2012 at 17:51:32 UTC, Andrei Alexandrescu
wrote:
On 7/12/12 1:40 PM, David Piepgrass wrote:
1. Most importantly, the C++ template approach is a big pain
for
large-scale systems, because in such systems you want to
create DLLs/SOs
and C++ has neither a standard ABI nor a safe way to pass
around
template instantiations between DLLs (in the presence of
changes to
internal implementation details). Similar problems exist for
D, yes?
It's a lot easier to define a standard ABI for classes than to
solve the
cross-DLL template problem.
The thing is, that can be done in an opt-in manner. People who
want methods in the root of the hierarchy can define a root
that defines them. But there's no way to opt out of inheriting
Object. Basically it's nice to not force people to buy into a
constrained environment without necessity.
But is the constrained environment we're talking about really all
that constrained?
- 'const' is not overly harsh if the user has machanisms to make
that mean 'logical const'.
- regarding the 5 vtable entries (destructor, toString, toHash,
opEquals, opCmp), well, that's only 20/40 bytes per process, and
maybe we don't need opCmp that much.
Although having these in Object seems constraining in one way,
removing them is constraining in a different way: you can no
longer provide collection classes for "any" object without
involving templates.
Wait a minute, though. Keeping in mind the problem of DLL
interoperability, and the constraints on using templated + many
DLLs together, what if D introduced the feature that Go and Rust
have, the ability to adapt any object to a compatible interface?
interface IComparable {
bool opEquals(IComparable rhs);
int opCmp(IComparable rhs);
}
class Foo { /* could contain anything */ }
So let's say we remove all the methods from Object, but we still
want people to be able to make a collection of "any object", such
as Foo, and pass this collection between DLLs safely. Moreover we
want only be a single instance of the collection class, defined
in a single DLL (so this collection cannot be a template class).
Since a class Foo does not declare that it implements
IComparable, and it might not even contain opCmp() and
opEquals(), we can't just cast to IObject. Not in the current D,
anyway.
But now add interface adaptation from Go/Rust. Foo might not
define opEquals and opCmp itself, but any client can add those
via UFCS, and the standard library would probably define opEquals
via UFCS as reference equality already. Thus it is possible for
any client to pretend that any class implements IComparable, by
adding the missing pieces (if any) and casting to IComparable.