www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Classes in D with betterC

reply Walter Bright <newshound2 digitalmars.com> writes:
https://lsferreira.net/posts/zet-1-classes-betterc-d/

by Luís Ferreira

It's currently on the front page of Hacker News:

https://news.ycombinator.com/
Nov 19 2021
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
And then there are issues such as 
https://issues.dlang.org/show_bug.cgi?id=21416 which killed off any 
chance of me using them internally.
Nov 19 2021
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 20 November 2021 at 05:37:42 UTC, rikki cattermole 
wrote:
 And then there are issues such as 
 https://issues.dlang.org/show_bug.cgi?id=21416 which killed off 
 any chance of me using them internally.
...and the implementation, as presented, falls apart due to not forwarding arguments correctly. Not insurmountable, of course, although `forward` really should be an intrinsic and not a library function. And due to looking for a `__dtor` instead of `__xdtor`. And due to the fact that ya can't use the proposed `destroy` function with a reference to base class and still call the destructor of derived class correctly, let alone infer attributes correctly. And due to it trusting the `pureFree` when it shouldn't. Can't see anything news-worthy here. This has been possible for ages, and is still limited to wazoo by classes being married to druntime, pessimized by lack of proper forwarding in the language, and can't be safe.
Nov 19 2021
parent reply =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Sat, 2021-11-20 at 06:15 +0000, Stanislav Blinov via Digitalmars-d-
announce wrote:
 On Saturday, 20 November 2021 at 05:37:42 UTC, rikki cattermole=20
 wrote:
 And then there are issues such as=20
 https://issues.dlang.org/show_bug.cgi?id=3D21416=C2=A0which killed off=
=20
 any chance of me using them internally.
=20 ...and the implementation, as presented, falls apart due to not=20 forwarding arguments correctly. Not insurmountable, of course,=20 although `forward` really should be an intrinsic and not a=20 library function. =20 And due to looking for a `__dtor` instead of `__xdtor`. And due=20 to the fact that ya can't use the proposed `destroy` function=20 with a reference to base class and still call the destructor of=20 derived class correctly, let alone infer attributes correctly.=20 And due to it trusting the `pureFree` when it shouldn't. =20 Can't see anything news-worthy here. This has been possible for=20 ages, and is still limited to wazoo by classes being married to=20 druntime, pessimized by lack of proper forwarding in the=20 language, and can't be safe.
I decided to have a simple approach just to show that it is easier now to do that without workarounds, and by workarounds, I mean using scope to fetch that info and use a fake dtor, or even before scope exists, the usage of runtime-less D call with betterC + objcopy, described [here](https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc. html). --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 21 2021
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Sunday, 21 November 2021 at 20:30:51 UTC, Luís Ferreira wrote:

 I decided to have a simple approach just to show that it is 
 easier now to do that without workarounds, and by workarounds, 
 I mean using scope to fetch that info and use a fake dtor, or 
 even before scope exists, the usage of runtime-less D call with 
 betterC + objcopy, described 
 [here](https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc. html).
I get that the news part is all about `__traits(initSymbol)`, which in this case is about instantiating a class without druntime. But that's just one line in the whole example. And the rest of the code? Construction may either fail altogether or cause unnecessary copies. Calling __dtor won't call destructors of base classes or derived classes. There may not even be a __dtor yet destruction may still be required through __xdtor, which still would not destruct base or derived classes. Deallocation can't be trusted since you don't have a facility to prove that no other references exist. If anything, the code shows how NOT to use classes, contrary to what your title or preface say ;) Even simple, an example should at least be correct, don't you think?
Nov 21 2021
parent reply =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Mon, 2021-11-22 at 03:36 +0000, Stanislav Blinov via Digitalmars-d-
announce wrote:
 On Sunday, 21 November 2021 at 20:30:51 UTC, Lu=C3=ADs Ferreira wrote:
=20
 I decided to have a simple approach just to show that it is=20
 easier now to do that without workarounds, and by workarounds,=20
 I mean using scope to fetch that info and use a fake dtor, or=20
 even before scope exists, the usage of runtime-less D call with=20
 betterC + objcopy, described=20
 [here](
 https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.
 html).
=20 I get that the news part is all about `__traits(initSymbol)`,=20 which in this case is about instantiating a class without=20 druntime.
Yes and this is by far harder than the past/previous approach, as you refered wrongly, "this has been possible for ages".
 But that's just one line in the whole example. And the rest of=20
 the code? Construction may either fail altogether or cause=20
 unnecessary copies.
I acknowledge that is a thing to consider, when doing generic code. I'm going to be honest and say that I did't though about those cases at the time of writing. The particular case is not wrong however, it is just limitative to types without such qualifiers. If I went that far, probably there is a number of things wrong. What if I want an `immutable` version of T? I simply, didn't thought about it, mostly because the point of that zettelkasten was to show `__traits(initSymbol)` off.
 Calling __dtor won't call destructors of base=20
 classes or derived classes. There may not even be a __dtor yet=20
 destruction may still be required through __xdtor, which still=20
 would not destruct base or derived classes.
This is an undocumented feature that I didn't know about. I'm going to do a specification PR to amend it.
 Deallocation can't be=20
  trusted since you don't have a facility to prove that no other=20
 references exist.
Yes, that is totally wrong and should be fixed, alhtough trusting pureMalloc is fine.
 If anything, the code shows how NOT to use=20
 classes, contrary to what your title or preface say ;)
 Even simple, an example should at least be correct, don't you=20
 think?
I think you unproportionally scaled your argument -- the article is not a complete how-to guide in classes -- althouh I agree that a simple example like the one presented should be correct. Thanks for your input! I'm going to fix the issues you presented. --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 22 2021
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 22 November 2021 at 12:57:27 UTC, Luís Ferreira wrote:
 On Mon, 2021-11-22 at 03:36 +0000, Stanislav Blinov via 
 Digitalmars-d- announce wrote:
 On Sunday, 21 November 2021 at 20:30:51 UTC, Luís Ferreira 
 wrote:
 
 I decided to have a simple approach just to show that it is
 easier now to do that without workarounds, and by 
 workarounds,
 I mean using scope to fetch that info and use a fake dtor, or
 even before scope exists, the usage of runtime-less D call 
 with
 betterC + objcopy, described
 [here](
 https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.
 html).
I get that the news part is all about `__traits(initSymbol)`, which in this case is about instantiating a class without druntime.
Yes and this is by far harder than the past/previous approach, as you refered wrongly, "this has been possible for ages".
It has been, with workarounds. Which, even in that case, all the other problems still apply.
 But that's just one line in the whole example. And the rest of 
 the code? Construction may either fail altogether or cause 
 unnecessary copies.
I acknowledge that is a thing to consider, when doing generic code. I'm going to be honest and say that I did't though about those cases at the time of writing. The particular case is not wrong however, it is just limitative to types without such qualifiers. If I went that far, probably there is a number of things wrong. What if I want an `immutable` version of T? I simply, didn't thought about it, mostly because the point of that zettelkasten was to show `__traits(initSymbol)` off.
But that is my point. You're showcasing __traits(initSymbol) but that is not at all what your article advertises :)
 Calling __dtor won't call destructors of base classes or 
 derived classes. There may not even be a __dtor yet 
 destruction may still be required through __xdtor, which still 
 would not destruct base or derived classes.
This is an undocumented feature that I didn't know about. I'm going to do a specification PR to amend it.
Awesome!
 Deallocation can't be  trusted since you don't have a facility 
 to prove that no other references exist.
Yes, that is totally wrong and should be fixed, alhtough trusting pureMalloc is fine.
Yup.
 If anything, the code shows how NOT to use
 classes, contrary to what your title or preface say ;)
 Even simple, an example should at least be correct, don't you
 think?
I think you unproportionally scaled your argument -- the article is not a complete how-to guide in classes -- althouh I agree that a simple example like the one presented should be correct.
Have I? The article is named "Classes in D with betterC", the preface states "Did you know that you can use classes in D as better C? Yes, you read correctly, you can actually use classes in D with -betterC." It's not at all clear that all you *really* mean and want to address is instantiation thanks to __traits(initSymbol). Maybe it's a language or cultural issue? I'm not being bashful. "Use classes", at least to me, means, well, "use classes", and not "use a subset of classes that's really not much better than structs as you can't fully support inheritance anyway because destruction is a mess". In other words, in order to fully appreciate the message of your article, one has to already be aware of all the other issues. Which is a dangerous presupposition for a public article, especially not prefaced accordingly.
 Thanks for your input! I'm going to fix the issues you 
 presented.
You're welcome :)
Nov 22 2021
next sibling parent =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Tue, 2021-11-23 at 05:25 +0000, Stanislav Blinov via Digitalmars-d-
announce wrote:
 Have I? The article is named "Classes in D with betterC", the=20
 preface states "Did you know that you can use classes in D as=20
 better C? Yes, you read correctly, you can actually use classes=20
 in D with -betterC." It's not at all clear that all you *really*=20
 mean and want to address is instantiation thanks to=20
 __traits(initSymbol).
Yes, maybe I expressed myself wrongly. Using only the term `use` can be vague, but I don't think the article is as missleading as you painted. What is the point of having classes without being possible to instantiate them? I can see limitative usefulness on it if the only objective on using D as better C is to expose a C++ API without actually using it in better C. Plus, you can define the class externally and just use it in better C. The problem before `__traits(initSymbol)` is that you can't realisticly use them in a fairly sane way. And by sane way I mean no need to manually remove generated runtime hooks from a seperate non-betterC compilation unit (`-defaultlib=3D -c`) or usage of `pragma(mangle)` to simulate runtime TypeInfo. I would say the sanest way of doing this is not even using custom allocators and instead make `new` behave like C++ in D as better C, but I'm not sure about the implications of that.
 Maybe it's a language or cultural issue? I'm not being bashful.=20
 "Use classes", at least to me, means, well, "use classes", and=20
 not "use a subset of classes that's really not much better than=20
 structs as you can't fully support inheritance anyway because=20
 destruction is a mess".
=20
 In other words, in order to fully appreciate the message of your=20
 article, one has to already be aware of all the other issues.=20
 Which is a dangerous presupposition for a public article,=20
 especially not prefaced accordingly.
=46rom what I understood the inheritance problem, destruction problem and the other issues presented above are bugs of the implementation, not the language itself. --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 23 2021
prev sibling parent reply workman <workman gmail.com> writes:
On Tuesday, 23 November 2021 at 05:25:46 UTC, Stanislav Blinov 
wrote:
 Maybe it's a language or cultural issue? I'm not being bashful. 
 "Use classes", at least to me, means, well, "use classes", and 
 not "use a subset of classes that's really not much better than 
 structs as you can't fully support inheritance anyway because 
 destruction is a mess".

 In other words, in order to fully appreciate the message of 
 your article, one has to already be aware of all the other 
 issues. Which is a dangerous presupposition for a public 
 article, especially not prefaced accordingly.

 Thanks for your input! I'm going to fix the issues you 
 presented.
You're welcome :)
If you can only create C++ class object but can not destroy them, and can not support dynamic cast, then C++ class object is not working. Maybe the title could be "You can use C++ in betterC but they are not working", or add into prefaced section. There is no roadmap about when it could be work, or plan to fixed should also be mentioned.
Nov 25 2021
parent =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Fri, 2021-11-26 at 05:53 +0000, workman via Digitalmars-d-announce
wrote:
 If you can only create C++ class object but can not destroy them,=20
 and can not support dynamic cast,=C2=A0 then C++ class object is not=20
 working.
=20
 Maybe the title could be "You can use C++ in betterC but they are=20
 not working", or add into prefaced section.
=20
 There is no roadmap about when it could be work, or plan to fixed=20
 should also be mentioned.
You can do both things, according to the current language specification. The destructors may have bugs, but you should be able to do destruction in a correct implementation. The dynamic cast is perfectly doable too, you just need to implement your own typeinfo, and it is not that hard and unusual. A clear example of that is LLVM. They use their own implementation of TypeInfo, see [here](https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html). So, arguing that classes doesn't work just because RTTI is not an intrinsic is not fair. The whole point of betterC is to prohib the usage or the runtime hooks or depend on any runtime related symbol and, in C++, std::type_info and typeid() is an interface provided by the C++ runtime, similar to D runtime. --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 26 2021
prev sibling next sibling parent reply tsbockman <thomas.bockman gmail.com> writes:
On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright 
wrote:
 https://lsferreira.net/posts/zet-1-classes-betterc-d/

 by Luís Ferreira
Great! `__traits(initSymbol, T)` will solve some problems for my current project. Some other `class` related issues I've run into trying to get going with classes in dasBetterC: `extern(C++) class` dynamic casts are completely broken: https://issues.dlang.org/show_bug.cgi?id=21690 The GC never calls `extern(C++) class` instance destructors: https://issues.dlang.org/show_bug.cgi?id=21693 Non-mutable `extern(D) class` `scope` instances cannot be created: https://issues.dlang.org/show_bug.cgi?id=21692 Template breaks return annotation for `class` reference returned by struct method: https://issues.dlang.org/show_bug.cgi?id=22528
Nov 20 2021
parent =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Sat, 2021-11-20 at 08:04 +0000, tsbockman via Digitalmars-d-announce
wrote:
 On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright=20
 wrote:
 https://lsferreira.net/posts/zet-1-classes-betterc-d/
=20
 by Lu=C3=ADs Ferreira
=20 Great! `__traits(initSymbol, T)` will solve some problems for my=20 current project. =20 Some other `class` related issues I've run into trying to get=20 going with classes in dasBetterC: =20 `extern(C++) class` dynamic casts are completely broken: https://issues.dlang.org/show_bug.cgi?id=3D21690 =20 The GC never calls `extern(C++) class` instance destructors: https://issues.dlang.org/show_bug.cgi?id=3D21693 =20 Non-mutable `extern(D) class` `scope` instances cannot be created: https://issues.dlang.org/show_bug.cgi?id=3D21692 =20 Template breaks return annotation for `class` reference returned=20 by struct method: https://issues.dlang.org/show_bug.cgi?id=3D22528
I will put them in my task list and see what I can do about it, when I have some time ;) --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 21 2021
prev sibling next sibling parent reply zjh <fqbqrr 163.com> writes:
On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright 
wrote:
 https://lsferreira.net/posts/zet-1-classes-betterc-d/

 by Luís Ferreira
[I have translated it into Chinese](https://fqbqrr.blog.csdn.net/article/details/121441466)
Nov 20 2021
parent reply =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Sat, 2021-11-20 at 08:40 +0000, zjh via Digitalmars-d-announce
wrote:
 On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright=20
 wrote:
 https://lsferreira.net/posts/zet-1-classes-betterc-d/
=20
 by Lu=C3=ADs Ferreira
=20
=20 [I have translated it into=20 Chinese](https://fqbqrr.blog.csdn.net/article/details/121441466)
Great! --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 21 2021
parent reply zjh <fqbqrr 163.com> writes:
On Sunday, 21 November 2021 at 20:32:24 UTC, Luís Ferreira wrote:

 Great!
I usually translate without asking the author's permission.
Nov 21 2021
parent =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Mon, 2021-11-22 at 00:49 +0000, zjh via Digitalmars-d-announce
wrote:
 On Sunday, 21 November 2021 at 20:32:24 UTC, Lu=C3=ADs Ferreira wrote:
=20
 Great!
=20 I usually translate without asking the author's permission. =20
It is fine to do it :) --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 22 2021
prev sibling next sibling parent zjh <fqbqrr 163.com> writes:
On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright 
wrote:
 https://lsferreira.net/posts/zet-1-classes-betterc-d/

 by Luís Ferreira
[I have translated it into Chinese](https://fqbqrr.blog.csdn.net/article/details/121441466).
Nov 20 2021
prev sibling next sibling parent reply Vladimir Marchevsky <vladimmi gmail.com> writes:
On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright 
wrote:
 Classes in D with betterC
I had a hope it's about changes in language/runtime...
Nov 20 2021
next sibling parent reply russhy <russhy gmail.com> writes:
as much as i love betterC

i think if we see classes in betterC, then we should have them 
require the *

otherwise it's repeating the same mistakes as D

betterC already is niche on its own, so let's do the move?
Nov 20 2021
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 21/11/2021 3:13 PM, russhy wrote:
 betterC already is niche on its own, so let's do the move?
Except -betterC is not niche at all. It is simply the language with any of the runtime dependencies disabled. No language level changes have to be made for this. Both full D and -betterC should eventual converge as we make druntime pay as you go.
Nov 20 2021
prev sibling parent russhy <russhy gmail.com> writes:
If -betterC get classes, can we please make them require to have 
the same syntax as structs/classes in C++

     MyClass* class = alloc!MyClass;


otherwise i don't think the name "betterC" should remain.. that 
would be repeating same D's mistake (in my opinion)
Nov 20 2021
prev sibling parent zjh <fqbqrr 163.com> writes:
On Saturday, 20 November 2021 at 04:58:52 UTC, Walter Bright 
wrote:

`betterC` needs official support `library`, otherwise it is 
walking on one foot.
Nov 20 2021