Rainer Deyke wrote:
Andrei Alexandrescu wrote:
Rainer Deyke wrote:
1. C++'s object model, complete with polymorphic value types,
What designs make good use of polymorphic value types?

In a way, that's a loaded question, since C++ classes don't stay
polymorphic when passed around by value.  Actual polymorphic value types
that stay polymorphic when copied would be much more useful.  However,
even the limited polymorphic value types of C++ are useful.

I'll try to briefly reply to this (I've been offline since yesterday's storm when a thunder fried the cable modem).

Let's see:

  - Implementation inheritance of value types, even without actual
polymorphism, is useful.  See, for example, the curiously recurring
template pattern (and all of its uses).

    And, yes, you can achieve similar results in D by using template
mixins, but this is a specialized mechanism where C++ manages to do with
the same generalized mechanism used for polymorphism and interface
inheritance.

    I use inheritance of value types all the time.

Well I use it sometimes too, but it's so fraught with peril that virtually all coding standards I've ever seen, all books and magazine articles on the topic, all pundits, say one thing: don't. Better use composition.

  - Polymorphic references to value types are often useful.  D has
references to value types (in the form of 'ref' parameters and pointers)
but these are not polymorphic.  As an example, I would name the standard
C++ iostream.

    They're value types (non-copyable for the most part, but stored
directly instead of as pointers, with RAII), but they're often passed
around as polymorphic references.

    I use polymorphic references to value types occasionally.

I don't know what polymorphic references to value types mean, and I don't think iostreams are representative for the matter, or a good design in general.

  - C++ makes a clear distinction between a reference and the thing
being referenced.  Even if value types and polymorphism were mutually
exclusive, this distinction would be useful.  All types are consistently
treated as value types, even those types that reference another object.

This is incorrect. C++ references are not value types. The design of references in C++ is particularly poor.

  I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'.
I *like* having to write 'p->f();' instead of 'p.f();'.  It keeps my
code clearly and more explicit.

I understand, but that's a judgment call (e.g. explicit calls instead of operator overloading). Other people prefer the opposite.

  - C++ does not have separate rules for value types and reference
types.  All types are implicitly value types; values of all types can be
placed on the heap.  This simplifies the language by having just one set
of rules instead of separate rules for classes and structs.  Again, this
unification would be useful even if it was an error to declare a
variable of a polymorphic type as a direct variable.

Again, C++ has references which kind of introduce separate and very different rules.

deterministic destructors,  arbitrary copy constructors, and optional
lack of default constructor.
Struct have that except for default constructor. In D, currently default
constructors cannot execute code. This is a limitation that we might
need to address, although it has some advantages.

There are things that copy constructors can do that the post-blit
operator can't do.

Yes, mostly wrong things. I think it would be a huge loss if D copied C++'s model.

Also, unless I am mistaken, D can move value types
around in memory at will, which also invalidates designs that are useful
in C++.

C++ copy+destroy sequence has been an absolute pest for years. Rvalue references fix that by adding another layer of complexity. I'm very happy D didn't inherit that.


Andrei

Reply via email to