www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - classes structs

reply "David Currie" <curriedr iinet.net.au> writes:
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.
Sep 14 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
On Friday, 14 September 2012 at 22:18:57 UTC, David Currie:

 Could you answer me WHY??

Take a look at the D FAQ, maybe some of your questions are answered there, this will save some time to people here. And your questions that are missing in the FAQ are better added there, because they are quite basic and common. The keyword "scoped" you probably refer to is deprecated when it's used to allocate class instances on the stack. Currently there is emplace() to allocate class instances in-place. emplace() is not perfect and it's not much "safe", but maybe it will become good enough. Regarding the missing struct inheritance, take a look at "alias this" (and template mixins), to compose struct behaviors. It's not inheritance, but often it's quite handy. Bye, bearophile
Sep 14 2012
prev sibling next sibling parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
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.

I'm not comfortable with it either. But as you know, there is scoped!MyClass library solution. One thing I miss is a Scoped!MyClass struct so I could embed my classes into structs without using heap. Then a construct() function could be used on it to init members and to call constructors (emplace() may be used to do that).
 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??

For safety and for easier generic programming. You can always disable automatic initialization by using void initializer.
 ALL classes when declared are instantiated on the heap
 and their constructor called. Again I ask WHY??

This is wrong. Classes when declared are initialized to null (unless void initializer is used). They're not automatically instantiated. You must explicitly instantiate them using _new_ operator.
Sep 14 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Sep 15 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/18/2012 07:07 AM, David Currie wrote:
 [ALL CAPS]

It does not matter who is the loudest guy in the room. If you have a point to make, just make it. (Stating the conclusion is not making a point. Skipping forward and predicting polite refusal does not help.) Most of the statements in the OP are inaccurate. The best way to get in touch with the language is by reading the online documentation and by experimenting with the compiler (prepare for some bugs and unspecified corner cases). Reading the newsgroup helps too. Usually it is best to double-check any claims about the language expressed online, using the reference implementation.
Sep 18 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/20/2012 03:43 AM, David Currie wrote:
 On Tuesday, 18 September 2012 at 18:42:33 UTC, Timon Gehr wrote:
 On 09/18/2012 07:07 AM, David Currie wrote:
 [ALL CAPS]

It does not matter who is the loudest guy in the room. If you have a point to make, just make it. (Stating the conclusion is not making a point. Skipping forward and predicting polite refusal does not help.) Most of the statements in the OP are inaccurate. The best way to get in touch with the language is by reading the online documentation and by experimenting with the compiler (prepare for some bugs and unspecified corner cases). Reading the newsgroup helps too. Usually it is best to double-check any claims about the language expressed online, using the reference implementation.

Apologies for SHOUTING. I am unfamiliar with forum syntax and etiquette I merely wished *stressing* some words.

I see. I wouldn't stress more than one or two words per post anyway. It is fatiguing for the reader and tends to get annoying, without strengthening the point.
 What is OP and perhaps why are most statements inaccurate?

This is the original post: On 09/15/2012 12:19 AM, 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.

This is the default, but do as you wish.
 (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).

Built-in scoped classes are going away.
 This is effectively FORCED Java.

No. Forced means there is no other way.
 A D struct is on the stack

Not necessarily.
 and is NOT a class

Yes.
 and has NO inheritance.

Composition of value types and alias this achieve both inheritance and subtyping. There is no built-in method overriding facility for value types, so just use function pointers.
 I have issues with this philosophy.

 It seems FUNDAMENTAL to me that a programmer needs both stack and heap
 objects

This is not fundamental. Stack objects are just 'nice to have'. If there is an execution stack at all, of course.
 and should KNOW when to use each and should ALWAYS have a choice.

Well, he does. The preferred usage is prescribed at the declaration site. The programmer who defines the type should know better, but his decision can always be overridden if this appears to be fundamental.
 ALL struct VARIABLES when declared are initialised to their .init value.

Not all of them, no. S s = void;
 Just in case a programmer "forgets" to initialize them.

No, unless a programmer "forgets" to not initialize them.
 This is like using a sledgehammer instead of a scalpel.

It is like defaulting to the sledgehammer when the scalpel is usually not appropriate.
 Could you answer me WHY??
 ALL classes when declared are instantiated on the heap
 and their constructor called.

No. class C{} // no run time behaviour C c; // initialized to null
 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 ?

Because scoped classes conflict with the infinite lifetime model. One programmer's freedom restricts another programmer. It is always a matter of trade-offs. classes implement the Java model of OO. structs have few limitations, and if absolutely needed can be used together with unsafe constructs to [br|tw]eak the OO model. Depending on who you ask, this may actually be undesirable. The only way to get correct code is by proving it correct. Restricting the constructs the programmer uses can make a proof easier, so this can be a very good thing. Not that this would matter a lot for D at this point, of course, but reasoning about code is important even in languages that make this notoriously difficult.
 Of course I have more to say about this but I need answers to these
 questions to proceed.

 How does one get to the newsgroups. I only got here because Walter gave
 me a link. I would gratefully welcome links.

Subscribe to news.digitalmars.com or use the web interface: http://forum.dlang.org/
Sep 20 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, September 15, 2012 03:58:50 Jonathan M Davis wrote:
 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.

You should keep in mind that D's general philosophy is to make the defaults safe but to allow you to do more powerful, dangerous stuff when you need to. The result is that it's just as powerful as C++ when you need it to be but that it's a lot safer in general, meaning that you're going to have fewer bugs in your code. A prime example of this is the fact that all variables are default- initialized. This way, you never have problems with variables being initialized to garbage, which can cause non-deterministic, hard-to-track-down bugs. But if you really need the extra speed of a variable not being initialized when it's declared, then you can initialize it to void. e.g. int i = void; This makes it so that code is far less error-prone in general while still allowing you to have the same down to the metal speed that C/C++ offers when you really need it. And it's that philosophy which governs a lot of D's features. - Jonathan M Davis
Sep 15 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Sat, 15 Sep 2012 13:05:47 +0200, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 if you really need the extra speed of a variable not being
 initialized when it's declared, then you can initialize it to void.

It's also worth noting that default-initialization may be elided when the optimizer finds that the variable is definitely initialized before use later in the code. -- Simen
Sep 15 2012
prev sibling next sibling parent "David Currie" <curriedr iinet.net.au> writes:
On Saturday, 15 September 2012 at 10:58:07 UTC, Jonathan M Davis 
wrote:
 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.

 You should keep in mind that D's general philosophy is to make 
 the defaults
 safe but to allow you to do more powerful, dangerous stuff when 
 you need to.
 The result is that it's just as powerful as C++ when you need 
 it to be but
 that it's a lot safer in general, meaning that you're going to 
 have fewer bugs
 in your code.

 A prime example of this is the fact that all variables are 
 default-
 initialized. This way, you never have problems with variables 
 being
 initialized to garbage, which can cause non-deterministic, 
 hard-to-track-down
 bugs. But if you really need the extra speed of a variable not 
 being
 initialized when it's declared, then you can initialize it to 
 void. e.g.

 int i = void;

 This makes it so that code is far less error-prone in general 
 while still
 allowing you to have the same down to the metal speed that 
 C/C++ offers when
 you really need it. And it's that philosophy which governs a 
 lot of D's
 features.

 - Jonathan M Davis

I have SO MANY issues with the above statements I wouldnt know where to start. I have been attempting to raise these (and many related) issues before. Firstly, responding in particular to Jonathan M Davis (albeit rather late), I concede your comments are made in good faith and are even ACCURATE. My problem is that they are INSUFFICIENT. I haven't announced to regular viewers that I STARTED these issues by writing direct to Walter (twice) that I had some language extension IDEAS I thought would be VALUABLE to ALL. Such Ideas would make a welcome addition to ANY language but for me D comes closest. (A C like language with NO header files alone is worth 50%). Naturally all he could really do was to send me along to the forums. However, I can see that if I am to receive the usual polite refusal, and I really wish to make a POINT I'd better be armed. I would need to be able to speak your language (learn D) before I should expect you to speak mine (implement My Ideas). I can see here that my best bet is to learn D. Can one learn it all online? What is the best D book?
Sep 17 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 18 Sep 2012 01:07:43 -0400, David Currie <curriedr iinet.net.au>  
wrote:

 On Saturday, 15 September 2012 at 10:58:07 UTC, Jonathan M Davis wrote:

 I haven't announced to regular viewers that I STARTED these issues by  
 writing direct to Walter (twice) that I had some language extension  
 IDEAS I thought would be VALUABLE to ALL. Such Ideas would make a  
 welcome addition to ANY language but for me D comes closest.
 (A C like language with NO header files alone is worth 50%).
 Naturally all he could really do was to send me along to the forums.

 However, I can see that if I am to receive the usual polite refusal,
 and I really wish to make a POINT I'd better be armed.

 I would need to be able to speak your language (learn D)
 before I should expect you to speak mine (implement My Ideas).
 I can see here that my best bet is to learn D.

 Can one learn it all online?  What is the best D book?

"The D Programming Language" is the official book for D, written by one of the main contributors, Andrei Alexandrescu. http://www.amazon.com/The-Programming-Language-Andrei-Alexandrescu/dp/0321635361/ref=sr_1_1?ie=UTF8&qid=1347967853&sr=8-1&keywords=the+d+programming+language Note, this only covers the core language, and a bit of the library. The standard library is very much in flux, and so writing a book at this point would be a bit premature. If you want to learn the language as quickly as possible, this is probably the best way, the book is very good. I should note that many of the concepts in the book are not yet implemented, but the book is considered to be more official than the reference implementation. In other words, TDPL is what the language *should* be on official release. So you may run into several features that are described in the book, but don't work. You can, of course, learn very very much by reading the documentation, online at dlang.org. The documentation is more of a specification, but it should be quite possible to learn it that way (I did). The dlang.org documentation more closely follows the reference compiler, and is in fact, released along with the compiler. I will warn you, that there will very likely be no point at which you will be able to convince Walter to abandon his core beliefs and fundamentally modify D. There are certainly areas which are not yet set in stone, and in the library is probably the best place you will be able to influence the language. But I would advise you right now, do not expect to *ever* see D change it's policy towards class allocation on the stack. As you alluded to, we already have a way to allocate classes on the stack, and that way is being deprecated, due to the dangers it poses. That should give you a clue that the language designers are not really keen on introducing something similar, even if you feel it is better (I have first-hand experience with this, try convincing Walter that we need tail-const...). It's like trying to sell an iPhone to someone who had one and hated it. "Yeah, but this iPhone is even better than the last one!" doesn't really cut it (I'm looking at you, Nick :) I don't want to sound harsh, or build a strawman for your ideas (of which you likely have many that haven't been expressed here), but if they are of the same grain, you will likely be disappointed. However, I am fairly confident that you will enjoy D, even if it doesn't do things exactly the way you want. And D might even be able to do things the way you want, there are some incredibly smart people here who can use D's immense code generation power to build types that do exactly what you want without adding language features. There are so many things I wish D did differently, but it is still far and above better than any other language I use. And I also hope that you can contribute ideas that *are* able to be included in the language. I think everyone here is interested in improving D! Hope this helps. -Steve
Sep 18 2012
prev sibling next sibling parent "David Currie" <curriedr iinet.net.au> writes:
On Tuesday, 18 September 2012 at 18:42:33 UTC, Timon Gehr wrote:
 On 09/18/2012 07:07 AM, David Currie wrote:
 [ALL CAPS]

It does not matter who is the loudest guy in the room. If you have a point to make, just make it. (Stating the conclusion is not making a point. Skipping forward and predicting polite refusal does not help.) Most of the statements in the OP are inaccurate. The best way to get in touch with the language is by reading the online documentation and by experimenting with the compiler (prepare for some bugs and unspecified corner cases). Reading the newsgroup helps too. Usually it is best to double-check any claims about the language expressed online, using the reference implementation.

Apologies for SHOUTING. I am unfamiliar with forum syntax and etiquette I merely wished *stressing* some words. What is OP and perhaps why are most statements inaccurate? How does one get to the newsgroups. I only got here because Walter gave me a link. I would gratefully welcome links.
Sep 19 2012
prev sibling next sibling parent "Jesse Phillips" <jessekphillips+D gmail.com> writes:
I just wanted to reiterate what Steven has said here. If you will 
learn D with a plan to change it to your desires, you will be 
disappointed. That is not to say give no feedback, or attempt no 
change. For one, you are coming in way to late for a good number 
of changes (including when we go to v3). Steven already covered 
the other.


You will find that a lot has already been discussed, and many 
here have had their share of desires turned down. But we are here 
because D is not just moving in the right direction, for many it 
is already has great use-cases.

So welcome, and hopefully you'll stay.
Sep 19 2012
prev sibling parent "Nathan M. Swan" <nathanmswan gmail.com> writes:
On Thursday, 20 September 2012 at 01:42:26 UTC, David Currie 
wrote:
 On Tuesday, 18 September 2012 at 18:42:33 UTC, Timon Gehr wrote:
 On 09/18/2012 07:07 AM, David Currie wrote:
 [ALL CAPS]

It does not matter who is the loudest guy in the room. If you have a point to make, just make it. (Stating the conclusion is not making a point. Skipping forward and predicting polite refusal does not help.) Most of the statements in the OP are inaccurate. The best way to get in touch with the language is by reading the online documentation and by experimenting with the compiler (prepare for some bugs and unspecified corner cases). Reading the newsgroup helps too. Usually it is best to double-check any claims about the language expressed online, using the reference implementation.

Apologies for SHOUTING. I am unfamiliar with forum syntax and etiquette I merely wished *stressing* some words. What is OP and perhaps why are most statements inaccurate? How does one get to the newsgroups. I only got here because Walter gave me a link. I would gratefully welcome links.

OP = Original Post(er). They use a lot of abbreviations I don't know here: acronymfinder.com is your friend. The only inaccurate statement I noticed was that class constructors are called (null is the default). NMS
Sep 19 2012