www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D vs C++ classes?

reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
What prevents unifying D classes with C++?

By that I mean: shouldn't it be possible to formulate an ABI for 
D classes that makes them fully C++ compatible?

Seems to me that D-interfaces can be implemented with C++ ABI for 
multiple inheritance for instance.
Jun 21 2021
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Monday, 21 June 2021 at 13:40:42 UTC, Ola Fosheim Grøstad 
wrote:
 What prevents unifying D classes with C++?
Multiple inheritance and Walter's strong opposition to said feature. - Alex
Jun 21 2021
parent reply Meta <jared771 gmail.com> writes:
On Monday, 21 June 2021 at 15:39:26 UTC, 12345swordy wrote:
 On Monday, 21 June 2021 at 13:40:42 UTC, Ola Fosheim Grøstad 
 wrote:
 What prevents unifying D classes with C++?
Multiple inheritance and Walter's strong opposition to said feature. - Alex
I guarantee you that Walter is far from the only one here with strong opposition to multiple inheritance.
Jun 21 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 21 June 2021 at 19:56:50 UTC, Meta wrote:
 I guarantee you that Walter is far from the only one here with 
 strong opposition to multiple inheritance.
You are not affected by it if you don't use it, but D classes are very close to C++ so it is a bit silly to not unify. D classes don't provide significantly different semantics from C++ IMHO. (Monitors can be viewed as a syntactical layer to some extent.)
Jun 21 2021
prev sibling next sibling parent reply zjh <fqbqrr 163.com> writes:
On Monday, 21 June 2021 at 19:56:50 UTC, Meta wrote:
 On Monday, 21 June 2021 at 15:39:26 UTC, 12345swordy wrote:
multiple inheritance is very good.I dont know why they are objective. 10+ years ago,they refuse to listen others' suggestion. I dont know if they still refuse now.
Jun 21 2021
next sibling parent reply IGotD- <nise nise.com> writes:
On Tuesday, 22 June 2021 at 02:13:33 UTC, zjh wrote:
 multiple inheritance is very good.I dont know why they are 
 objective.
 10+ years ago,they refuse to listen others' suggestion.
 I dont know if they still refuse now.
It's because the diamond problem. The diamond problem is purely an academic problem and it very seldom happens in the real world and if it does you probably did something wrong in your design. Happen to me once in 30 years because I messed up. Multiple inheritance is often flat, which means that one class inherits from several others at the same level. Instead of disallow multiple inheritance you can disallow the diamond pattern. D went another way with composition with template mixins. Nothing particular wrong with this model but I think the D documentation isn't clear about its intended use. Also the overlap with alias this makes it more confusing.
Jun 22 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 22 June 2021 at 09:04:05 UTC, IGotD- wrote:
 It's because the diamond problem. The diamond problem is purely 
 an academic problem and it very seldom happens in the real 
 world and if it does you probably did something wrong in your 
 design. Happen to me once in 30 years because I messed up. 
 Multiple inheritance is often flat, which means that one class 
 inherits from several others at the same level. Instead of 
 disallow multiple inheritance you can disallow the diamond 
 pattern.
It is usually best to not use multiple inheritance, but it would be better for the D eco system if D classes map to C++ since they are so close anyway.
Jun 22 2021
prev sibling next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 22 June 2021 at 09:04:05 UTC, IGotD- wrote:
 [snip]

 It's because the diamond problem. The diamond problem is purely 
 an academic problem and it very seldom happens in the real 
 world and if it does you probably did something wrong in your 
 design. Happen to me once in 30 years because I messed up. 
 Multiple inheritance is often flat, which means that one class 
 inherits from several others at the same level. Instead of 
 disallow multiple inheritance you can disallow the diamond 
 pattern.
 [snip]
Some other language had suggested something like below as a solution to the diamond problem class A { void a() {} } class B : A {} class C : A { disable a; } class D : B, C {} However, I was thinking what happens if you do something like A ac = new C(); How would the compiler handle that?
Jun 22 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 22 June 2021 at 11:13:52 UTC, jmh530 wrote:
 However, I was thinking what happens if you do something like
 A ac = new C();

 How would the compiler handle that?
Runtime error, but this is just a bad idea. If B and C inherits from A and specializes a() then a D that inherits from both B and C should be forced to implement a(). Not really a big issue, I think.
Jun 22 2021
prev sibling parent reply mw <mingwu gmail.com> writes:
On Tuesday, 22 June 2021 at 11:13:52 UTC, jmh530 wrote:
 On Tuesday, 22 June 2021 at 09:04:05 UTC, IGotD- wrote:
 [snip]

 It's because the diamond problem. The diamond problem is 
 purely an academic problem and it very seldom happens in the 
 real world and if it does you probably did something wrong in 
 your design. Happen to me once in 30 years because I messed 
 up. Multiple inheritance is often flat, which means that one 
 class inherits from several others at the same level. Instead 
 of disallow multiple inheritance you can disallow the diamond 
 pattern.
 [snip]
Some other language had suggested something like below as a solution to the diamond problem class A { void a() {} } class B : A {} class C : A { disable a; } class D : B, C {} However, I was thinking what happens if you do something like A ac = new C(); How would the compiler handle that?
That language is called Eiffel, and in such case, C become abstract class, as I explained in this post: https://forum.dlang.org/post/ztawxnwydbxiymcqvzhr forum.dlang.org https://forum.dlang.org/post/ztawxnwydbxiymcqvzhr forum.dlang.org
Jun 22 2021
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 22 June 2021 at 13:42:30 UTC, mw wrote:
 [snip]
 However, I was thinking what happens if you do something like
 A ac = new C();

 How would the compiler handle that?
That language is called Eiffel, and in such case, C become abstract class, as I explained in this post: https://forum.dlang.org/post/ztawxnwydbxiymcqvzhr forum.dlang.org https://forum.dlang.org/post/ztawxnwydbxiymcqvzhr forum.dlang.org
Thanks, the name of the language wasn't coming to me but I recall the prior discussion. So if `C` becomes abstract, then the above line is prevented because you cannot instantiate an abstract class (correct? I can't test it on run.dlang.org right now and I'm not sure if it is `C c = new C()` that is prevented or this one). That's kind of limiting, no? Does that have any separate implications for: ```d A ad = new D(); B bd = new D(); C cd = new D(); D dd = new D(); ``` My thought would be that just `cd` would be prevented.
Jun 22 2021
parent reply mw <mingwu gmail.com> writes:
On Tuesday, 22 June 2021 at 14:54:42 UTC, jmh530 wrote:
 On Tuesday, 22 June 2021 at 13:42:30 UTC, mw wrote:
 [snip]
 However, I was thinking what happens if you do something like
 A ac = new C();

 How would the compiler handle that?
That language is called Eiffel, and in such case, C become abstract class, as I explained in this post: https://forum.dlang.org/post/ztawxnwydbxiymcqvzhr forum.dlang.org https://forum.dlang.org/post/ztawxnwydbxiymcqvzhr forum.dlang.org
Thanks, the name of the language wasn't coming to me but I recall the prior discussion. So if `C` becomes abstract, then the above line is prevented because you cannot instantiate an abstract class (correct? I
That's right.
 can't test it on run.dlang.org right now and I'm not sure if it 
 is `C c = new C()` that is prevented or this one). That's kind 
 of limiting, no?
Not at all. First it's by the programmer's design (if s/he chooses to do it in this way). Second: to solve diamond problem, undefine / rename a feature usually happen in D: Class D : B(disable a), C {} // so using C.a() Class D : B, C(disable a) {} // so using B.a() Note: this resolution in D, make A B C D all usable, non of them is abstract. Please check my github example.
 Does that have any separate implications for:
 ```d
 A ad = new D();
 B bd = new D();
 C cd = new D();
 D dd = new D();
 ```
 My thought would be that just `cd` would be prevented.
In your example, yes.
Jun 22 2021
next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 22 June 2021 at 15:14:02 UTC, mw wrote:
 [snip]
 Not at all. First it's by the programmer's design (if s/he 
 chooses to do it in this way).

 Second: to solve diamond problem, undefine / rename a feature 
 usually happen in D:

 Class D : B(disable a), C {} // so using C.a()

 Class D : B, C(disable a) {} // so using B.a()


 Note: this resolution in D, make A B C D all usable, non of 
 them is abstract.


 Please check my github example.
 [snip]
Thanks for the reply. The only github example I could find was in Eiffel https://github.com/mingwugmail/dlang_tour/tree/master/eiffel/mi Is that the right one?
Jun 22 2021
parent mw <mingwu gmail.com> writes:
On Tuesday, 22 June 2021 at 16:13:11 UTC, jmh530 wrote:
 On Tuesday, 22 June 2021 at 15:14:02 UTC, mw wrote:
 [snip]
 Not at all. First it's by the programmer's design (if s/he 
 chooses to do it in this way).

 Second: to solve diamond problem, undefine / rename a feature 
 usually happen in D:

 Class D : B(disable a), C {} // so using C.a()

 Class D : B, C(disable a) {} // so using B.a()


 Note: this resolution in D, make A B C D all usable, non of 
 them is abstract.


 Please check my github example.
 [snip]
Thanks for the reply. The only github example I could find was in Eiffel https://github.com/mingwugmail/dlang_tour/tree/master/eiffel/mi Is that the right one?
https://github.com/mingwugmail/dlang_tour/tree/master/eiffel/visitor
Jun 22 2021
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 22 June 2021 at 15:14:02 UTC, mw wrote:
 Class D : B(disable a), C {} // so using C.a()

 Class D : B, C(disable a) {} // so using B.a()
I don't really see the difference between this and forcing a reimplementation of `a()` that calls A's `a()`, B's `a()` or both.
Jun 23 2021
parent reply mw <mingwu gmail.com> writes:
On Wednesday, 23 June 2021 at 17:00:00 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 22 June 2021 at 15:14:02 UTC, mw wrote:
 Class D : B(disable a), C {} // so using C.a()

 Class D : B, C(disable a) {} // so using B.a()
I don't really see the difference between this and forcing a reimplementation of `a()` that calls A's `a()`, B's `a()` or both.
There is nothing magic (which is a bad thing ^TM :-) about Eiffel's multiple inheritance. This demonstrate: MI can be done, and with the compiler's help, it can be done more easily. That's all. (I think we both are all arguing *for* MI be included in D, right :-)
Jun 23 2021
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Wednesday, 23 June 2021 at 17:12:38 UTC, mw wrote:
 On Wednesday, 23 June 2021 at 17:00:00 UTC, Ola Fosheim Grøstad 
 wrote:
 On Tuesday, 22 June 2021 at 15:14:02 UTC, mw wrote:
 Class D : B(disable a), C {} // so using C.a()

 Class D : B, C(disable a) {} // so using B.a()
I don't really see the difference between this and forcing a reimplementation of `a()` that calls A's `a()`, B's `a()` or both.
There is nothing magic (which is a bad thing ^TM :-) about Eiffel's multiple inheritance. This demonstrate: MI can be done, and with the compiler's help, it can be done more easily. That's all. (I think we both are all arguing *for* MI be included in D, right :-)
Good luck convincing walter on this. -Alex
Jun 23 2021
prev sibling parent mw <mingwu gmail.com> writes:
On Tuesday, 22 June 2021 at 09:04:05 UTC, IGotD- wrote:
 On Tuesday, 22 June 2021 at 02:13:33 UTC, zjh wrote:
 multiple inheritance is very good.I dont know why they are 
 objective.
 10+ years ago,they refuse to listen others' suggestion.
 I dont know if they still refuse now.
It's because the diamond problem. The diamond problem is purely an academic problem and it very seldom happens in the real world and if it does you probably did something wrong in your design. Happen to me once in 30 years because I messed up.
Forgive me to repeat: diamond problem is a solved problem, elegantly by Eiffel, see my previous post, and example on github: https://forum.dlang.org/post/deeuyrcwxjkjerpgqdjj forum.dlang.org
 Multiple inheritance is often flat, which means that one class 
 inherits from several others at the same level. Instead of 
 disallow multiple inheritance you can disallow the diamond 
 pattern.

 D went another way with composition with template mixins. 
 Nothing particular wrong with this model but I think the D 
 documentation isn't clear about its intended use. Also the 
 overlap with alias this makes it more confusing.
Jun 22 2021
prev sibling parent zjh <fqbqrr 163.com> writes:
On Tuesday, 22 June 2021 at 02:13:33 UTC, zjh wrote:
 On Monday, 21 June 2021 at 19:56:50 UTC, Meta wrote:
You can check inheritance conflicts at compile time. Once the conflict method is used, the full name is required, otherwise it cannot be compiled.
Jun 22 2021
prev sibling parent reply solidstate1991 <laszloszeremi outlook.com> writes:
On Monday, 21 June 2021 at 19:56:50 UTC, Meta wrote:
 I guarantee you that Walter is far from the only one here with 
 strong opposition to multiple inheritance.
Multiple inheritance induces a lot of headaches (added complexity, diamond inheritance, etc.), and even C++ devs try to avoid it at all costs. It rarely has any real-life use, that couldn't be solved with interfaces and mixins.
Jun 28 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 28 June 2021 at 20:35:25 UTC, solidstate1991 wrote:
 Multiple inheritance induces a lot of headaches (added 
 complexity, diamond inheritance, etc.), and even C++ devs try 
 to avoid it at all costs. It rarely has any real-life use, that 
 couldn't be solved with interfaces and mixins.
That isn't the point (if it is true). And actually, C++ stdlib uses it. Some C++ devs avoid virtual in general though, but that is another issue. The point is that you need multiple inheritance to unify D classes with C++ classes, but you don't have to use it if you don' want to, so there is no cost to having it. So basically only one big benefit, and no real disadvantages.
Jun 28 2021
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Monday, 28 June 2021 at 21:03:21 UTC, Ola Fosheim Grøstad 
wrote:
 On Monday, 28 June 2021 at 20:35:25 UTC, solidstate1991 wrote:
 Multiple inheritance induces a lot of headaches (added 
 complexity, diamond inheritance, etc.), and even C++ devs try 
 to avoid it at all costs. It rarely has any real-life use, 
 that couldn't be solved with interfaces and mixins.
That isn't the point (if it is true). And actually, C++ stdlib uses it. Some C++ devs avoid virtual in general though, but that is another issue. The point is that you need multiple inheritance to unify D classes with C++ classes, but you don't have to use it if you don' want to, so there is no cost to having it. So basically only one big benefit, and no real disadvantages.
We *Technically* have multiple inheritance in d via alias this, so that cat is out of the bag. I just wish walter would bite the bullet and implemented multiple inheritance properly, so that we could deprecate alias this as it is a redundant feature. - Alex
Jun 28 2021
prev sibling parent reply Bruce Carneal <bcarneal gmail.com> writes:
On Monday, 28 June 2021 at 21:03:21 UTC, Ola Fosheim Grøstad 
wrote:
 On Monday, 28 June 2021 at 20:35:25 UTC, solidstate1991 wrote:
 Multiple inheritance induces a lot of headaches (added 
 complexity, diamond inheritance, etc.), and even C++ devs try 
 to avoid it at all costs. It rarely has any real-life use, 
 that couldn't be solved with interfaces and mixins.
That isn't the point (if it is true). And actually, C++ stdlib uses it. Some C++ devs avoid virtual in general though, but that is another issue. The point is that you need multiple inheritance to unify D classes with C++ classes, but you don't have to use it if you don' want to, so there is no cost to having it. So basically only one big benefit, and no real disadvantages.
Making a new feature optional does not, of course, actually make it free. The cost includes, minimally, the cost of implementation and maintenance over the life of the compiler(s) and the debugging costs incurred by programmers encountering bugs in the, potentially complex, new compiler code. OTOH, if a feature addition provides a new best-practices capability that displaces error prone coding going forward, then the benefits could very well outweigh such costs over time. I'm hopeful that this is true of the template free metaprogramming additions proposed recently. I'm less hopeful regarding MI.
Jun 28 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 28 June 2021 at 23:17:36 UTC, Bruce Carneal wrote:
 Making a new feature optional does not, of course, actually 
 make it free.  The cost includes, minimally, the cost of 
 implementation and maintenance over the life of the compiler(s) 
 and the debugging costs incurred by programmers encountering 
 bugs in the, potentially complex, new compiler code.
The complexity that comes with multiple inheritance is the offset to the ancestor class, but that is already solved by the C++ ABI one chooses to conform to. The diamond problem isn't about what to do when merging members, which seem to have been what people have focused on in this thread, but whether you want the common ancestor A to have two instances or one instance. So in C++ you solve this by making the shared ancestor `virtual` if you want to have one ancestor instance. Which is a bit clumsy, but I guess this comes down to requirements inherited from C-style separate compilation. Still, C++ is what it is, so compilers have to deal with it regardless. Unifying C++ and D classes gets rid of one language construct (The D class). So it does make the language simpler for the user in my view.
Jun 28 2021
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Tuesday, 29 June 2021 at 06:52:03 UTC, Ola Fosheim Grøstad 
wrote:
 On Monday, 28 June 2021 at 23:17:36 UTC, Bruce Carneal wrote:
 Making a new feature optional does not, of course, actually 
 make it free.  The cost includes, minimally, the cost of 
 implementation and maintenance over the life of the 
 compiler(s) and the debugging costs incurred by programmers 
 encountering bugs in the, potentially complex, new compiler 
 code.
The complexity that comes with multiple inheritance is the offset to the ancestor class, but that is already solved by the C++ ABI one chooses to conform to.
This will basically cut any research and potential improvements into the compiler regarding oop that rely on type information being coded inside abi, right? Should we sacrifice any possible future improvements for this? What about additional annotations that are embedded in mangled name for the class methods?
 Still, C++ is what it is, so compilers have to deal with it 
 regardless. Unifying C++ and D classes gets rid of one language 
 construct (The D class). So it does make the language simpler 
 for the user in my view.
I personally don't think this is right approach. We basically are running after C++ to just add this interop stuff, while limiting ourselves in growth of oop aspect of D. I think the best alternative here would be to allow c++ class declarations (extern c++ ones) to be able to express multiple inheritance and other things related to c++ classes, rather bounding native D classes to c++ abi. Best regards, Alexandru.
Jun 29 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 30 June 2021 at 00:07:46 UTC, Alexandru Ermicioi 
wrote:
 This will basically cut any research and potential improvements 
 into the compiler regarding oop that rely on type information 
 being coded inside abi, right?
 Should we sacrifice any possible future improvements for this?
 What about additional annotations that are embedded in mangled 
 name for the class methods?
I don't think so, because one can grab runtime type information space that isn't used by C++. In the worst case one can just allocate space for unused virtual functions and use that for other stuff.
 I personally don't think this is right approach. We basically 
 are running after C++ to just add this interop stuff, while 
 limiting ourselves in growth of oop aspect of D.
I understand this sentiment, but what growth are you thinking of, though?
 I think the best alternative here would be to allow c++ class 
 declarations (extern c++ ones) to be able to express multiple 
 inheritance and other things related to c++ classes, rather 
 bounding native D classes to c++ abi.
Ok, but then we risk having some libraries making all their classes `extern (C++)` and thus forcing that onto the application programmer which then cannot get D typeinfo. So that is worse for the programmer, as he is then stuck with C++ typeinfo and lost out on whatever advantages D can add to C++-classes. For instance, I dislike having 3 different record-types: struct, class, C++-class. So I would probably just use "extern (C++) classes" when I need virtuals, "structs" otherwise and avoid "D classes"... What will happen when the eco-system grows? That is the tricky question.
Jun 29 2021
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Wednesday, 30 June 2021 at 06:23:17 UTC, Ola Fosheim Grøstad 
wrote:
 I don't think so, because one can grab runtime type information 
 space that isn't used by C++.
I don't have in depth knowledge of C++, but doesn't your statement imply that it is reserved by C++ for future use?
 In the worst  case one can just allocate space for unused 
 virtual functions and use that for other stuff.
Imho feels more like a hack. Btw this doesn't answer the problem with mangling the method attributes.
 I understand this sentiment, but what growth are you thinking 
 of, though?
I don't have any dips to specify at the moment, but this doesn't mean there can't be in the future, dips that require specific abi incompatible with c++ one. For example what if there is a drive functionality?
 Ok, but then we risk having some libraries making all their 
 classes `extern (C++)`
And this is perfectly fine. This means that the lib is designed to be c++ interoperable.
 and thus forcing that onto the application programmer which 
 then cannot get D typeinfo.
This can be solved not only with just making D classes c++ compatible. What about enhancing D language to provide typeinfo wrappers over c++ ones when we ask for them with typeid statement? Clearly with current type info architecture where all of them are classes won't work, but what if we'd refactor them to be a set of interfaces? Compiler then would be able to spawn implementations of those interfaces, for 'D' classes as well as for extern c++ ones which would be just some wrappers over c++ typeinfo.
 So that is worse for the programmer, as he is then stuck with 
 C++ typeinfo and lost out on whatever advantages D can add to 
 C++-classes.
I'm sorry, but I feel like this is a very skewed opinion in favor of c++ interoperability, ignoring everything else just to get it.
 For instance, I dislike having 3 different record-types: 
 struct, class, C++-class. So I would probably just use "extern 
 (C++) classes" when I need virtuals, "structs" otherwise and 
 avoid "D classes"... What will happen when the eco-system 
 grows? That is the tricky question.
There are no c++ classes in D. There are D classes that are compatible with C++ abi, which in turn does remove some features from them that are not representable through c++ class semantics (typeinfo is just not one of them). So use extern c++ for d classes exposed outside to the c++ based apps that use your lib, and keep using standard d classes inside your lib. That's the purpose of any (extern xxx) statement.
Jun 30 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 30 June 2021 at 09:19:28 UTC, Alexandru Ermicioi 
wrote:
 I don't have in depth knowledge of C++, but doesn't your 
 statement imply that it is reserved by C++ for future use?
No, but ABIs can change obviously, so there is that.
 Btw this doesn't answer the problem with mangling the method 
 attributes.
Not sure what you mean here. You can have multiple names for the same entity?
 And this is perfectly fine. This means that the lib is designed 
 to be c++ interoperable.
Yes, but you get a split eco system.
 This can be solved not only with just making D classes c++ 
 compatible. What about enhancing D language to provide typeinfo 
 wrappers over c++ ones when we ask for them with typeid 
 statement?
It is possible to use fat pointers, but there is overhead.
 Clearly with current type info architecture where all of them 
 are classes won't work, but what if we'd refactor them to be a 
 set of interfaces?
Not sure how this would work?
 I'm sorry, but I feel like this is a very skewed opinion in 
 favor of c++ interoperability, ignoring everything else just to 
 get it.
Ok, but I think D has to make up its mind of whether C++ interoperability is going to be a goal and a selling point, meaning close to full interop, or just a bumper sticker.
 There are no c++ classes in D. There are D classes that are 
 compatible with C++ abi, which in turn does remove some 
 features from them that are not representable through c++ class 
 semantics (typeinfo is just not one of them).
I don't understand what you mean here, if you have extern c++ with full interop then you have c++ classes (runtime), but without things like multiple inheritance then D provides a subset of the c++ class type space.
 So use extern c++ for d classes exposed outside to the c++ 
 based apps that use your lib, and keep using standard d classes 
 inside your lib. That's the purpose of any (extern xxx) 
 statement.
But using D classes won't provide any real benefits for most programmers, so why bother? Also, can we assume that you know a priori what you need to send over to C++?
Jun 30 2021
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 30 June 2021 at 09:19:28 UTC, Alexandru Ermicioi 
wrote:
 I don't have in depth knowledge of C++, but doesn't your 
 statement imply that it is reserved by C++ for future use?
No, but ABIs can change obviously, so there is that.
 Btw this doesn't answer the problem with mangling the method 
 attributes.
Is this a problem, can't you have multiple names for the same entity in the object file?
 And this is perfectly fine. This means that the lib is designed 
 to be c++ interoperable.
Yes, but you get a split eco system.
 This can be solved not only with just making D classes c++ 
 compatible. What about enhancing D language to provide typeinfo 
 wrappers over c++ ones when we ask for them with typeid 
 statement?
It is possible to use fat pointers, but there is overhead.
 Clearly with current type info architecture where all of them 
 are classes won't work, but what if we'd refactor them to be a 
 set of interfaces?
Not sure how this would work?
 I'm sorry, but I feel like this is a very skewed opinion in 
 favor of c++ interoperability, ignoring everything else just to 
 get it.
Ok, but I think D has to make up its mind of whether C++ interoperability is going to be a goal and a selling point, meaning close to full interop, or just a bumper sticker.
 There are no c++ classes in D. There are D classes that are 
 compatible with C++ abi, which in turn does remove some 
 features from them that are not representable through c++ class 
 semantics (typeinfo is just not one of them).
I don't understand what you mean here, if you have extern c++ with full interop then you have c++ classes (runtime), but without things like multiple inheritance then D provides a subset of the c++ class type space.
 So use extern c++ for d classes exposed outside to the c++ 
 based apps that use your lib, and keep using standard d classes 
 inside your lib. That's the purpose of any (extern xxx) 
 statement.
But using D classes won't provide any real benefits for most programmers, so why bother? Also, can we assume that you know a priori what you need to send over to C++? If there were substantive differences between D classes and C++ classes with virtuals, then one could argue that it would be a big loss. But I only see minor differences...
Jun 30 2021
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Wednesday, 30 June 2021 at 09:53:31 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 30 June 2021 at 09:19:28 UTC, Alexandru Ermicioi 
 wrote:
 Btw this doesn't answer the problem with mangling the method 
 attributes.
Is this a problem, can't you have multiple names for the same entity in the object file?
Ok, wasn't aware of that.
 And this is perfectly fine. This means that the lib is 
 designed to be c++ interoperable.
Yes, but you get a split eco system.
I don't think so. What will be split in there?
 Clearly with current type info architecture where all of them 
 are classes won't work, but what if we'd refactor them to be a 
 set of interfaces?
Not sure how this would work?
If you open object.d and check for TypeInfo symbols you'll notice that they are final classes. We should replace them with a set of interfaces (with nice names without uncompliant underscores by code style standards), and then let d compiler generate an implementation for each class it has compiled. This as said will allow us flexibility at providing type info for not just types used in the language itself, but also for type declarations of libs that are written in foreign language, and for types written in d and intended for use by code written in foreign language, such as C++. This will also make it quite easier to add interop added. When you'll invoke typeid, it will return the type info interface, or if it is sure that the variable contains a concrete type, and not a subtype, it may return the implementation of type info interface itself.
 I'm sorry, but I feel like this is a very skewed opinion in 
 favor of c++ interoperability, ignoring everything else just 
 to get it.
Ok, but I think D has to make up its mind of whether C++ interoperability is going to be a goal and a selling point, meaning close to full interop, or just a bumper sticker.
If you want full 100% interop, just use c++. There is bound to be shortcomings in interoperability, and imho we should not sacrifice the language, just for that. If this will be the future orientation for D I don't see the point of it having letter D, let's just rename it to C++++
 There are no c++ classes in D. There are D classes that are 
 compatible with C++ abi, which in turn does remove some 
 features from them that are not representable through c++ 
 class semantics (typeinfo is just not one of them).
I don't understand what you mean here, if you have extern c++ with full interop then you have c++ classes (runtime), but without things like multiple inheritance then D provides a subset of the c++ class type space.
1. My suggestion of allowing to express multiple inheritance, was for c++ class declarations only, i.e. class header files only. 2. Making them compatible with C++ abi doesn't imply that they are c++ classes, and hence should support all c++ features. They are still D classes or a subset of them that can be called by c++ code.
 So use extern c++ for d classes exposed outside to the c++ 
 based apps that use your lib, and keep using standard d 
 classes inside your lib. That's the purpose of any (extern 
 xxx) statement.
But using D classes won't provide any real benefits for most programmers, so why bother? Also, can we assume that you know a priori what you need to send over to C++?
Again this is a very skewed opinion that D is used only by C and C++ devs. I am PHP, and Java developer, and I want for D language to prevent me from doing stupid things with multiple inheritance such as the diamond problem. Hence I'm against it for supporting as core feature of OOP in D. It may be ok, if it is supported for c++ class declarations when you need to express a class hierarchy found in a lib written in c++.
 If there were substantive differences between D classes and C++ 
 classes with virtuals, then one could argue that it would be a 
 big loss. But I only see minor differences...
Let's not conflate two distinct domain objects into one. There is a class that is written in D, and there is one written in C++, they are not the same thing. Let's also clarify what full interoperability means. Per my understanding, this means that I can use all of libs written in c++, and then I can expose my D code to the c++ libs and allow them use it, but it does not mean, that I need to follow the c++ rules for the oop, or any other feature, otherwise, why not replace D lambdas, with std::function from c++? We need full interoperability...
Jun 30 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 30 June 2021 at 10:38:36 UTC, Alexandru Ermicioi 
wrote:
 On Wednesday, 30 June 2021 at 09:53:31 UTC, Ola Fosheim Grøstad 
 wrote:
 If you open object.d and check for TypeInfo symbols you'll 
 notice that they are final classes. We should replace them with 
 a set of interfaces (with nice names without uncompliant 
 underscores by code style standards), and then let d compiler 
 generate an implementation for each class it has compiled.
Do you mean using a function call to obtain specific type info?
 If you want full 100% interop, just use c++. There is bound to 
 be shortcomings in interoperability, and imho we should not 
 sacrifice the language, just for that. If this will be the 
 future orientation for D I don't see the point of it having 
 letter D, let's just rename it to C++++
Runtime compatibility does not equate compile time limitations, so it isn't really all that limiting given the current D semantics. The difference between D and C++ on the compile time level isn't really touched.
 1. My suggestion of allowing to express multiple inheritance, 
 was for c++ class declarations only, i.e. class header files 
 only.
 2. Making them compatible with C++ abi doesn't imply that they 
 are c++ classes, and hence should support all c++ features. 
 They are still D classes or a subset of them that can be called 
 by c++ code.
You need to be able to specialize C++ classes in order to have full C++ library interop. So it is a given requirement that you need to be able to declare/define/instantiate extensions of C++ classes in D, in order to have basic C++ interop.
 Let's not conflate two distinct domain objects into one. There 
 is a class that is written in D, and there is one written in 
 C++, they are not the same thing.
You need to be able to extend the one in C++ from D in order to integrate, so it basically is the same thing. Most modern C++ libraries are also heavily templated so to have basic interop you actually need to translate D code to C++. That is, if C++ interop is a goal. Most people don't want 50% interop they expect close to 99% interop. If only 50% is the goal, then maybe just stick to C interop and forget about C++, most people don't care for 50% anyway.
 Let's also clarify what full interoperability means. Per my
 understanding, this means that I can use all of libs written in
 c++, and then I can expose my D code to the c++ libs and allow
 them use it, but it does not mean, that I need to follow the
 c++ rules for the oop, or any other feature, otherwise, why not
 replace D lambdas, with std::function from c++? We need full
 interoperability...
std::function is just a buffer, but yes, D does need something comparable although in C++ std::function is a last resort, you would typically use a template instead.
Jun 30 2021
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Wednesday, 30 June 2021 at 12:22:07 UTC, Ola Fosheim Grøstad 
wrote:
 Do you mean using a function call to obtain specific type info?
Well, it doesn't matter what happens under `typeid` call, it can either be some inlined code that fetches the typeinfo object or call to a templated function. Note I don't suggest changing the way how type info are generated, or where they are being stored, only that they should be hidden and available only through a set of interfaces found in object module.
 If you want full 100% interop, just use c++. There is bound to 
 be shortcomings in interoperability, and imho we should not 
 sacrifice the language, just for that. If this will be the 
 future orientation for D I don't see the point of it having 
 letter D, let's just rename it to C++++
Runtime compatibility does not equate compile time limitations, so it isn't really all that limiting given the current D semantics. The difference between D and C++ on the compile time level isn't really touched.
True we can make the compiler emit c++ compliant abi classes for non extern c++, but this creates a risk of falling into situation where all devs will just skip adding extern c++ the class expecting that 'it should work' while it may not to.
 You need to be able to specialize C++ classes in order to have 
 full C++ library interop. So it is a given requirement that you 
 need to be able to declare/define/instantiate extensions of C++ 
 classes in D, in order to have basic C++ interop.
I think this is already supported by D? You can already extend a C++ class, this still doesn't mean we should support all C++ class features because of that. The derived class will still be an extern (C++) D class even if the parent is a C++ class. I guess in this case interoperability should also be at inheritance level.
 Let's not conflate two distinct domain objects into one. There 
 is a class that is written in D, and there is one written in 
 C++, they are not the same thing.
You need to be able to extend the one in C++ from D in order to integrate, so it basically is the same thing. Most modern C++ libraries are also heavily templated so to have basic interop you actually need to translate D code to C++. That is, if C++ interop is a goal. Most people don't want 50% interop they expect close to 99% interop. If only 50% is the goal, then maybe just stick to C interop and forget about C++, most people don't care for 50% anyway.
Which leads us to conclusion, that we can't afford a 99% interop between C++ and D, unless someone is ready to pour lots of resources into supporting templated code. The point I try to make is, that we shouldn't equate D classes to C++ classes, at language level nor on abi level. This will be similar to how D went with all classes should inherit from a common Object ancestor logic, which was found to be problematic for D users, since it added constraints on the integration with other features of D language, such as safe, pure or etc. Basically C++ interop should be opt in, as it is now, where you can declare a class that it can interface with C++ code.
Jun 30 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 30 June 2021 at 14:13:23 UTC, Alexandru Ermicioi 
wrote:
 Which leads us to conclusion, that we can't afford a 99% 
 interop between C++ and D, unless someone is ready to pour lots 
 of resources into supporting templated code.
That is a fair point. A 50% solution won't work for future and upcoming C++ libraries, only for older libraries (which eventually disappear).
 Basically C++ interop should be opt in, as it is now, where you 
 can declare a class that it can interface with C++ code.
I actually think D has to make a strategic choice, either support C++ really really well, or depart from C and C++ and provide some novel useful features.
Jul 01 2021
next sibling parent reply zjh <fqbqrr 163.com> writes:
On Thursday, 1 July 2021 at 11:26:23 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 30 June 2021 at 14:13:23 UTC, Alexandru Ermicioi 
 wrote:
D `should not` forget the original intention: D is a system level language. C++ is our good friend. I always say `compete with C++` and `learn from C++`. `Better C++` is always good for attracting people. Recently, I find V language, and its many feature are copying from `D` language,though `Go++,rust--`. And now they have `24000` star. I always say `Better C++` is the right way.
Jul 01 2021
next sibling parent zjh <fqbqrr 163.com> writes:
On Thursday, 1 July 2021 at 12:18:38 UTC, zjh wrote:
 On Thursday, 1 July 2021 at 11:26:23 UTC, Ola Fosheim Grøstad
 Recently, I find V language, and its many feature are copying 
 from `D` language,though `Go++,rust--`.
 And now they have `24000` star.
`V` has just 10 times as many stars as `D`.
Jul 01 2021
prev sibling next sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Thursday, 1 July 2021 at 12:18:38 UTC, zjh wrote:
 On Thursday, 1 July 2021 at 11:26:23 UTC, Ola Fosheim Grøstad 
 wrote:
 On Wednesday, 30 June 2021 at 14:13:23 UTC, Alexandru Ermicioi 
 wrote:
D `should not` forget the original intention: D is a system level language.
D is a general purpose programming language not just systems programming language.
 C++ is our good friend.
 I always say `compete with C++` and `learn from C++`.
This should not be only from C++, but all languages.
 `Better C++` is always good for attracting people.
I'm not against better C++ interop, and would like to have it. I'm against adjusting core features of D just to make it compatible with C++ without using extern (C++) modifier, in other words not opt in.
 Recently, I find V language, and its many feature are copying 
 from `D` language,though `Go++,rust--`.
 And now they have `24000` star.
 I always say `Better C++` is the right way.
Well, I'm also for better C++ interop, just not for the sake of sacrificing flexibility of a language to evolve.
Jul 01 2021
prev sibling parent Jack Applegame <japplegame gmail.com> writes:
On Thursday, 1 July 2021 at 12:18:38 UTC, zjh wrote:
 Recently, I find V language, and its many feature are copying 
 from `D` language`.
What features did V copy from D?
Jul 02 2021
prev sibling parent zjh <fqbqrr 163.com> writes:
On Thursday, 1 July 2021 at 11:26:23 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 30 June 2021 at 14:13:23 UTC, Alexandru Ermicioi 
 wrote:
you are right. For example,proving `vectors and AA ` for `Better C`. `Better C` can compete with `C++`, But `D` also need infrastructure like containers `(vectors/arrays/associative arrays)` for `Better C`. otherwise ,like me,without them ,I can do nothing.
Jul 01 2021
prev sibling next sibling parent sighoya <sighoya gmail.com> writes:
On Monday, 21 June 2021 at 13:40:42 UTC, Ola Fosheim Grøstad 
wrote:
 What prevents unifying D classes with C++?

 By that I mean: shouldn't it be possible to formulate an ABI 
 for D classes that makes them fully C++ compatible?
+1 for that, never understood the reason against this given that we live in the 20ies now. If performance is the problem, you wouldn't choose virtual dispatch anyway. If safety is the problem, then disambiguation by scoping is the solution.
 Seems to me that D-interfaces can be implemented with C++ ABI 
 for multiple inheritance for instance.
Yes, but interfaces can't have fields. I find D should better interop with C++ classes without the `extern` sh!t, and supporting multiple inheritance should work out of the box. Who wants to manually create thousands of classes to interop with a c++ framework?
Jun 21 2021
prev sibling next sibling parent reply Mathias LANG <geod24 gmail.com> writes:
On Monday, 21 June 2021 at 13:40:42 UTC, Ola Fosheim Grøstad 
wrote:
 What prevents unifying D classes with C++?

 By that I mean: shouldn't it be possible to formulate an ABI 
 for D classes that makes them fully C++ compatible?

 Seems to me that D-interfaces can be implemented with C++ ABI 
 for multiple inheritance for instance.
The main reason they can't be ABI compatible is the TypeInfo AFAIR. But `extern(C++)` does the job just fine.
Jun 21 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 21 June 2021 at 17:55:25 UTC, Mathias LANG wrote:
 The main reason they can't be ABI compatible is the TypeInfo 
 AFAIR.
 But `extern(C++)` does the job just fine.
Does this mean that you make all your classes `extern(C++)` ? Can I define `extern(C++)` classes in D and instantiate them in D just fine and pass them to C++?
Jun 21 2021
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 21 June 2021 at 17:55:25 UTC, Mathias LANG wrote:
 The main reason they can't be ABI compatible is the TypeInfo 
 AFAIR.
Hm, but I think D could extend C++ type info? I believe the C++ standard for runtime reflection will be extended though. Not sure what that implies for the ABI.
Jun 21 2021
prev sibling parent reply Guillaume Piolat <first.name domain.tld> writes:
On Monday, 21 June 2021 at 13:40:42 UTC, Ola Fosheim Grøstad 
wrote:
 What prevents unifying D classes with C++?
https://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545 There are books dedicated to explaining the C++ object model, so sure, let's emulate that!
Jun 22 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 22 June 2021 at 16:17:58 UTC, Guillaume Piolat wrote:
 There are books dedicated to explaining the C++ object model, 
 so sure, let's emulate that!
There are books for everything. The C++ runtime model isn't all that complicated.
Jun 23 2021