classes structs
Jonathan M Davis
jmdavisProg at gmx.com
Sat Sep 15 03:58:50 PDT 2012
On Saturday, September 15, 2012 00:19:07 David Currie wrote:
> At the risk of appearing ignorant, I don't know everything about
> D.
> However in D I have noticed the following.
>
> It is a policy decision in D that a class is ALWAYS on the heap
> and passed
> by REFERENCE. (I know there is a keyword to put a class object on
> the stack
> but this is not facile and needing a workaround is poor language
> design).
> This is effectively FORCED Java.
> A D struct is on the stack and is NOT a class and has NO
> inheritance.
>
> I have issues with this philosophy.
>
> It seems FUNDAMENTAL to me that a programmer needs both stack and
> heap
> objects and should KNOW when to use each and should ALWAYS have a
> choice.
>
> ALL struct VARIABLES when declared are initialised to their .init
> value.
> Just in case a programmer "forgets" to initialize them.
> This is like using a sledgehammer instead of a scalpel.
> Could you answer me WHY??
> ALL classes when declared are instantiated on the heap
> and their constructor called. Again I ask WHY??
>
> Why can't the programmer have the freedom to build his own objects
> when he wants to with the compiler advising of errors ?
>
> Of course I have more to say about this but I need answers to
> these questions
> to proceed.
Classes are polymorphic. They have inheritance and virtual functions.
Polymorphism makes no sense with a variable on the stack. Having inheritance
with objects on the stack risks object slicing (
http://en.wikipedia.org/wiki/Object_slicing ). Sure, you _can_ have a
polymorphic object which is on the stack (which is why C++ allows classes on
the stack and why D has std.typecons.scoped), but it's the sort of thing that
tends to be begging for bugs.
The designers of D decided that it's was cleaner and safer to separate objects
which were meant to be polymorphic and those which were meant to be non-
polymorphic (as is often considered best practice in C++), and since having
polymorphic objects means that you're not using their polymorphism and having
them on the stack can be dangerous, it was decided to follow Java and C#'s
example and make all classes into reference types which live on the heap
(though unlike Java and C#, we _can_ put such objects on the stack if we
really want to via std.typecons.scoped). But unlike Java and C#, we have
structs which are full-on objects with constructors and destructors and are
the same in classes in pretty much every way except that they have no
polymorphism and normally go on the stack.
The result is safer than what C++ has but is still very powerful. And since
it's arguably best practice not to put objects which are meant to use
polymorphism on the stack in C++ anyway, it's not even really restricting you
from much in comparison to C++ (and std.typecons.scoped makes it possible to
put classes on the stack if you really want to, making the restrictions even
less).
You can like it or not, but separating structs and classes and making classes
reference types on the heap is a design decision based on the best practices
and common bugs in C++. And it works very well. Upon occasion, it can be
limiting (hence why we have std.typecons.scoped), but I don't think that
you're going to find very many D programmers who think that the separation of
structs and classes was a bad idea.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list