www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Would the ownership model make D lang as complicated as Rust?

reply joe <jsjoesmith111111 gmail.com> writes:
In regards to this article 
https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/

I have a couple of questions,

1. I was wondering if this is going to make D lang just as 
complicated as Rust?
2. Would there be GC still if we use the ownership model?
Nov 13 2020
next sibling parent reply tsbockman <thomas.bockman gmail.com> writes:
On Saturday, 14 November 2020 at 05:33:24 UTC, joe wrote:
 2. Would there be GC still if we use the ownership model?
The garbage collector is not going away. For much (most?) user-space code, the benefits of GC far outweigh its down sides. The ownership model is primarily intended to benefit soft real-time applications, such as games, audio playback, operating systems, or very high performance web servers. If you're not writing code like this which requires low and consistent latency, then you can and probably should just go on using the garbage collector.
Nov 13 2020
parent reply joe <jsjoesmith111111 gmail.com> writes:
On Saturday, 14 November 2020 at 06:56:30 UTC, tsbockman wrote:
 On Saturday, 14 November 2020 at 05:33:24 UTC, joe wrote:
 2. Would there be GC still if we use the ownership model?
The garbage collector is not going away. For much (most?) user-space code, the benefits of GC far outweigh its down sides. The ownership model is primarily intended to benefit soft real-time applications, such as games, audio playback, operating systems, or very high performance web servers. If you're not writing code like this which requires low and consistent latency, then you can and probably should just go on using the garbage collector.
Can I replace the GC model with the ownership model?
Nov 14 2020
parent reply aberba <karabutaworld gmail.com> writes:
On Saturday, 14 November 2020 at 08:36:56 UTC, joe wrote:
 On Saturday, 14 November 2020 at 06:56:30 UTC, tsbockman wrote:
 On Saturday, 14 November 2020 at 05:33:24 UTC, joe wrote:
 2. Would there be GC still if we use the ownership model?
The garbage collector is not going away. For much (most?) user-space code, the benefits of GC far outweigh its down sides. The ownership model is primarily intended to benefit soft real-time applications, such as games, audio playback, operating systems, or very high performance web servers. If you're not writing code like this which requires low and consistent latency, then you can and probably should just go on using the garbage collector.
Can I replace the GC model with the ownership model?
Certain D features *few of them actually) are built with GC code so you can't swap them out. Unless there is a no-GC third-party alternative library you can plug in and use. See https://dlang.org/blog/the-gc-series/
Nov 14 2020
parent tsbockman <thomas.bockman gmail.com> writes:
On Saturday, 14 November 2020 at 12:00:32 UTC, aberba wrote:
 On Saturday, 14 November 2020 at 08:36:56 UTC, joe wrote:
 Can I replace the GC model with the ownership model?
Certain D features *few of them actually) are built with GC code so you can't swap them out. Unless there is a no-GC third-party alternative library you can plug in and use.
None of the D features that require the GC are essential; all can be replaced by alternative techniques, although *some* are more complex and error-prone. The only thing that can't be done without the D GC, is interfacing with library code that assumes its availability. Given that D can interface with C libraries (and some C++) rather easily, there really are no show-stoppers for nogc D. It's just extra work to get it right, and shouldn't be done without a good reason.
Nov 14 2020
prev sibling next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 11/13/20 9:33 PM, joe wrote:
 In regards to this article 
 https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/
 
 I have a couple of questions,
 
 1. I was wondering if this is going to make D lang just as complicated 
 as Rust?
 2. Would there be GC still if we use the ownership model?
I don't know whether he will cover those questions but Walter Bright's DConf Online 2020 keynote is on that topic: https://dconf.org/2020/online/index.html Ali
Nov 13 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/13/2020 9:33 PM, joe wrote:
 In regards to this article 
 https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/
 
 I have a couple of questions,
 
 1. I was wondering if this is going to make D lang just as complicated as Rust?
Good question. That remains to be seen. In any case, you can use O/B on a function-by-function basis, you don't need to redesign and rewrite anything.
 2. Would there be GC still if we use the ownership model?
Yes, though you wouldn't bother using live functions if you used the GC. There's be no point.
Nov 15 2020
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 15/11/2020 10:09 PM, Walter Bright wrote:
 On 11/13/2020 9:33 PM, joe wrote:
 2. Would there be GC still if we use the ownership model?
Yes, though you wouldn't bother using live functions if you used the GC. There's be no point.
If you could turn on live for specific variables, then there would be a point. System resources (especially windowing related) absolutely needs a way to guarantee destruction and prevent moving a window ownership to another thread.
Nov 15 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/15/2020 1:21 AM, rikki cattermole wrote:
 If you could turn on  live for specific variables, then there would be a point.
I considered that, and concluded that it was too inconvenient to be used widely.
Nov 17 2020
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 18/11/2020 2:14 PM, Walter Bright wrote:
 On 11/15/2020 1:21 AM, rikki cattermole wrote:
 If you could turn on  live for specific variables, then there would be 
 a point.
I considered that, and concluded that it was too inconvenient to be used widely.
Unfortunately this is the kind of memory safety that users, as in non-programmers care about. They don't want zombie processes with ghost windows that they can't do anything with on top of every other window. It is one thing for an individual program to misbehave, it is another for it to hurt the system.
Nov 17 2020
prev sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Sunday, 15 November 2020 at 09:09:56 UTC, Walter Bright wrote:
 2. Would there be GC still if we use the ownership model?
Yes, though you wouldn't bother using live functions if you used the GC. There's be no point.
I thought live can avoid refs count with regard to resource management, and still get deterministic destruction. That would be valuable even if there is a gc around.
Nov 15 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/15/2020 1:29 AM, Sebastiaan Koppe wrote:
 I thought  live can avoid refs count with regard to resource management, and 
 still get deterministic destruction. That would be valuable even if there is a 
 gc around.
If you're using deterministic destruction, you don't need a gc :-) Anyhow, we can pick this up again after seeing my presentation on it at #DConfOnline
Nov 17 2020
prev sibling parent reply donallen <donaldcallen gmail.com> writes:
On Saturday, 14 November 2020 at 05:33:24 UTC, joe wrote:
 In regards to this article 
 https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/

 I have a couple of questions,

 1. I was wondering if this is going to make D lang just as 
 complicated as Rust?
 2. Would there be GC still if we use the ownership model?
I can't answer your questions, but I can offer some observations based on my experience porting a personal finance application, originally written in C, to Rust (about 10,000 lines of code). I am retired from a long career in software development and project management. I wrote my first line of code 60 years ago. I have learned a lot of programming languages during all those years and I have never encountered anything as difficult to learn and use as Rust. Haskell is a walk in the park compared to Rust. Rust does what they say it will do -- deliver memory-safety without a garbage collector. But the incremental price you, the programmer, must pay for the absence of a GC is significant. Consideration of Rust require careful cost-benefit analysis. If you are about to write something that requires absolutely predictable latency, where you would normally reach for something like C or C++, then Rust is probably a better choice (I'm ignoring the issue of deadlines and whether you already know the language). They have done an excellent job, given the design constraints they have chosen. But if you are writing an ordinary application, such as my financial application, Rust is not appropriate, in my view (I suspected that going in, but I'm retired and also a bit of a programming language enthusiast, so I went ahead despite my doubts; had I been doing this in the real world of business, I like to think that the project manager part of me would have done something more sensible). I don't know exactly how Walter intends to proceed with adding Rust-like move semantics to D, but the little I know suggests that it will be optional. If I'm right, that's very wise. Move semantics and no GC for those who really need it (justifying its cost) and the luxury of the GC for those who don't.
Nov 15 2020
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 15.11.20 15:11, donallen wrote:
 
 I don't know exactly how Walter intends to proceed with adding Rust-like 
 move semantics to D, but the little I know suggests that it will be 
 optional. If I'm right, that's very wise. Move semantics and no GC for 
 those who really need it (justifying its cost) and the luxury of the GC 
 for those who don't.
And an unsound interface between the two so you can have your O/B and safety type checks and even get the luxury of some memory corruption anyway.
Nov 15 2020
next sibling parent reply M.M. <matus email.cz> writes:
On Sunday, 15 November 2020 at 14:34:24 UTC, Timon Gehr wrote:
 On 15.11.20 15:11, donallen wrote:
 
 I don't know exactly how Walter intends to proceed with adding 
 Rust-like move semantics to D, but the little I know suggests 
 that it will be optional. If I'm right, that's very wise. Move 
 semantics and no GC for those who really need it (justifying 
 its cost) and the luxury of the GC for those who don't.
And an unsound interface between the two so you can have your O/B and safety type checks and even get the luxury of some memory corruption anyway.
Are you sceptical of introducing O/B principles into current D, or is it just about how it's being discussed/implemented?
Nov 16 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 16.11.20 21:17, M.M. wrote:
 On Sunday, 15 November 2020 at 14:34:24 UTC, Timon Gehr wrote:
 On 15.11.20 15:11, donallen wrote:
 I don't know exactly how Walter intends to proceed with adding 
 Rust-like move semantics to D, but the little I know suggests that it 
 will be optional. If I'm right, that's very wise. Move semantics and 
 no GC for those who really need it (justifying its cost) and the 
 luxury of the GC for those who don't.
And an unsound interface between the two so you can have your O/B and safety type checks and even get the luxury of some memory corruption anyway.
Are you sceptical of introducing O/B principles into current D, or is it just about how it's being discussed/implemented?
I'm all for it, it's just that the specific approach that has been put forward does not work (in addition to being less expressive than what Rust has). I have suggested alternatives, but no discussion arose from it. Basically, you can't get useful O/B features that ensure memory safety using a function annotation, you'd need borrowed references and some library features. live is a function annotation because it is easier to implement; it's not a sound thing to do. At the same time the messaging around live has been contradictory, Walter on the one side essentially stated that it was just him messing around with new type checker features that may even turn out to be useful as linting hints to someone writing some system code and on the other side it was already being advertised as bringing Rust-like safety features to D. However, as far as I can tell, there is still no coherent design that would allow for that. (Looking forward to Walter's keynote though.)
Nov 16 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/15/2020 6:34 AM, Timon Gehr wrote:
 And an unsound interface between the two so you can have your O/B and safety 
 type checks and even get the luxury of some memory corruption anyway.
In Rust there are unsafe (i.e. unsound) functions, too. It's not possible to make Rust work without them.
Nov 17 2020
next sibling parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 18 November 2020 at 01:21:12 UTC, Walter Bright 
wrote:
 On 11/15/2020 6:34 AM, Timon Gehr wrote:
 And an unsound interface between the two so you can have your 
 O/B and safety type checks and even get the luxury of some 
 memory corruption anyway.
In Rust there are unsafe (i.e. unsound) functions, too. It's not possible to make Rust work without them.
In Rust, the borrow checker is still enabled in unsafe functions:
 You can take five actions in unsafe Rust, called unsafe 
 superpowers, that you can’t in safe Rust. Those superpowers 
 include the ability to:

    * Dereference a raw pointer
    * Call an unsafe function or method
    * Access or modify a mutable static variable
    * Implement an unsafe trait
    * Access fields of unions

 It’s important to understand that unsafe doesn’t turn off the 
 borrow checker or disable any other of Rust’s safety checks: if 
 you use a reference in unsafe code, it will still be checked.
Source: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
Nov 17 2020
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 18.11.20 02:21, Walter Bright wrote:
 On 11/15/2020 6:34 AM, Timon Gehr wrote:
 And an unsound interface between the two so you can have your O/B and 
 safety type checks and even get the luxury of some memory corruption 
 anyway.
In Rust there are unsafe (i.e. unsound) functions, too. It's not possible to make Rust work without them.
`unsafe` functions are not unsound, as they don't claim to be safe.
Nov 17 2020
prev sibling next sibling parent reply Piotrek <nonexisting nonexisting-host.net> writes:
On Sunday, 15 November 2020 at 14:11:51 UTC, donallen wrote:
 I can't answer your questions, but I can offer some 
 observations based on my experience porting a personal finance 
 application, originally written in C, to Rust (about 10,000 
 lines of code).
[...] Thank you for sharing your experience.
 Rust does what they say it will do -- deliver memory-safety 
 without a garbage collector. But the incremental price you, the 
 programmer, must pay for the absence of a GC is significant.
A really critical point which is often omitted describing Rust's "memory-safety without a garbage collector" is that you can't use reference cycles in your data. (https://medium.com/hackernoon/why-im-dropping-rust-fd1c32986c88) And according to my (limited) academic knowledge, complete compile time automatic memory management isn't simply possible. (You have to use hacks like weak refs and other not fancy staff).
 If you are about to write something that requires absolutely 
 predictable latency, where you would normally reach for 
 something like C or C++, then Rust is probably a better choice
I haven't actually used (and seen) the Rust lang in embedded systems, but I read a comment from a guy whose complains I think may be correct. The Rust O/B system results in more usage of heap allocations. (or even requires it due to borrow checker's limitations). And in general, heap allocations can cause too high unpredictable delays (this is also very often ignored).
 I don't know exactly how Walter intends to proceed with adding 
 Rust-like move semantics to D, but the little I know suggests 
 that it will be optional. If I'm right, that's very wise. Move 
 semantics and no GC for those who really need it (justifying 
 its cost) and the luxury of the GC for those who don't.
I hope D will be still getting simpler (not less complex - meaning less powerful). Making good API (which boosts developers productivity) is so incredibly difficult that I appreciate more and more D developers' contributions to those all great libraries. Cheers, Piotrek
Nov 16 2020
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 16 November 2020 at 22:39:14 UTC, Piotrek wrote:
 And according to my (limited) academic knowledge, complete
 compile time automatic memory management isn't simply possible.
 (You have to use hacks like weak refs and other not fancy 
 staff).
In the general case no, because then the compiler would have to predict all relevant execution patterns. If you can deduce/impose an invariant order then it could, in theory.
Nov 16 2020
prev sibling parent reply IGotD- <nise nise.com> writes:
On Monday, 16 November 2020 at 22:39:14 UTC, Piotrek wrote:
 And according to my (limited) academic knowledge, complete
 compile time automatic memory management isn't simply possible.
 (You have to use hacks like weak refs and other not fancy 
 staff).
Correct and Rust itself is a proof of that. Rust has to often rely on reference counting where the compiler cannot determine the lifetime, typically when multiple ownership is required. Furthermore, the compiler cannot even always determine the borrow checker at compile time and programmer must use RefCell. RefCell basically inserts runtime checks that the compiler would otherwise be capable to infer at compile time. Rust try to market itself as a silver bullet for lifetimes and how safe it is but the reality is different. Rust started something interesting but I think that the Rust object lifetime model will be unique for Rust only. Pieces of the knowledge will be used in future compilers.
Nov 17 2020
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 17 November 2020 at 10:54:20 UTC, IGotD- wrote:
 On Monday, 16 November 2020 at 22:39:14 UTC, Piotrek wrote:
 And according to my (limited) academic knowledge, complete
 compile time automatic memory management isn't simply possible.
 (You have to use hacks like weak refs and other not fancy 
 staff).
Correct and Rust itself is a proof of that.
Rust is not proof of that. However, it is often difficult to prove properties of a graph that is transformed.
Nov 17 2020
parent reply Max Haughton <maxhaton gmail.com> writes:
On Tuesday, 17 November 2020 at 11:34:01 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 17 November 2020 at 10:54:20 UTC, IGotD- wrote:
 On Monday, 16 November 2020 at 22:39:14 UTC, Piotrek wrote:
 And according to my (limited) academic knowledge, complete
 compile time automatic memory management isn't simply 
 possible.
 (You have to use hacks like weak refs and other not fancy 
 staff).
Correct and Rust itself is a proof of that.
Rust is not proof of that. However, it is often difficult to prove properties of a graph that is transformed.
Rice's theorem means you can't just let the compiler do it for you, however rust doesn't do that. What Rust shows us that a conservative approach (i.e. annotations from the programmer and the exact rules the borrow checker allows) is more than enough to guarantee safety and manage memory productively. D is already going in the right direction, the only issue really is that (as they are now) pointers are insufficiently expressive to be both safe and (say) act like C++ smart pointers and work with their de/allocators automatically. Ideally we would use structs but Rusts move by default semantics are an advantage we don't have.
Nov 17 2020
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 17 November 2020 at 18:02:00 UTC, Max Haughton wrote:
 Rice's theorem means you can't just let the compiler do it for 
 you,
We probably can't, but since we are talking finite entities you can enumerate all possibilities in finite time, so you need a different line of argumentation I think. > What Rust shows us that a
 conservative approach (i.e. annotations from the programmer and 
 the exact rules the borrow checker allows) is more than enough 
 to guarantee safety and manage memory productively.
Yes, and there are many other ways to annotate and constrain the search space. Clearly not trivial... But this is not the end, it is the beginning...
 D is already going in the right direction, the only issue 
 really is that (as they are now) pointers are insufficiently 
 expressive to be both safe and (say) act like C++ smart
Yes, you need a type system that differentiate more to make it tractable...
Nov 17 2020
prev sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
On Tuesday, 17 November 2020 at 10:54:20 UTC, IGotD- wrote:
 On Monday, 16 November 2020 at 22:39:14 UTC, Piotrek wrote:
 And according to my (limited) academic knowledge, complete
 compile time automatic memory management isn't simply possible.
 (You have to use hacks like weak refs and other not fancy 
 staff).
Correct and Rust itself is a proof of that. Rust has to often rely on reference counting where the compiler cannot determine the lifetime, typically when multiple ownership is required. Furthermore, the compiler cannot even always determine the borrow checker at compile time and programmer must use RefCell. RefCell basically inserts runtime checks that the compiler would otherwise be capable to infer at compile time. Rust try to market itself as a silver bullet for lifetimes and how safe it is but the reality is different. Rust started something interesting but I think that the Rust object lifetime model will be unique for Rust only. Pieces of the knowledge will be used in future compilers.
Rust got the ball rolling for the ideas prototyped in Cyclone and Linear Lisp. Even if the language dies tomorrow, it has already made a mark on Swift, D, Chapel, ParaSail, C++, Haskell, Idris(2), F*, Dafny and probably others. This is where I see the evolution of systems languages, some form of GC (yes it includes RC as algorithm) alongside some kind of support for linear/affine types for those critical code sections. It doesn't need to be perfect, just good enough.
Nov 17 2020
parent reply donallen <donaldcallen gmail.com> writes:
 Even if the language dies tomorrow, it has already made a mark 
 on Swift, D, Chapel, ParaSail, C++, Haskell, Idris(2), F*, 
 Dafny and probably others.
I'd be very interested in knowing where you think Rust has influenced Haskell. There is certainly a lot of influence in the other direction, e.g., Haskell classes -> Rust traits.
Nov 17 2020
parent Paulo Pinto <pjmlp progtools.org> writes:
On Tuesday, 17 November 2020 at 17:00:12 UTC, donallen wrote:
 Even if the language dies tomorrow, it has already made a mark 
 on Swift, D, Chapel, ParaSail, C++, Haskell, Idris(2), F*, 
 Dafny and probably others.
I'd be very interested in knowing where you think Rust has influenced Haskell. There is certainly a lot of influence in the other direction, e.g., Haskell classes -> Rust traits.
Check Linear Haskell.
Nov 17 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/15/2020 6:11 AM, donallen wrote:
 I don't know exactly how Walter intends to proceed with adding Rust-like move 
 semantics to D, but the little I know suggests that it will be optional. If
I'm 
 right, that's very wise. Move semantics and no GC for those who really need it 
 (justifying its cost) and the luxury of the GC for those who don't.
It's a similar approach to how D does functional programming. You can do FP in D on a totally incremental approach, function by function. And just like doing OOP in D, you can use it in parts of your program and not in other parts.
Nov 17 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 18.11.20 02:19, Walter Bright wrote:
 On 11/15/2020 6:11 AM, donallen wrote:
 I don't know exactly how Walter intends to proceed with adding 
 Rust-like move semantics to D, but the little I know suggests that it 
 will be optional. If I'm right, that's very wise. Move semantics and 
 no GC for those who really need it (justifying its cost) and the 
 luxury of the GC for those who don't.
It's a similar approach to how D does functional programming. You can do FP in D on a totally incremental approach, function by function. And just like doing OOP in D, you can use it in parts of your program and not in other parts.
This works for `pure`, but not ` live`, because it is not an issue for an impure function to call a `pure` one, but if a non-` live` function calls a ` live` one, the arguments may violate invariants that ` live` users want to rely on. In any case, `pure` is transitive. ` live` is not even transitive, so you get the same problems the other way around.
Nov 17 2020
parent reply Max Haughton <maxhaton gmail.com> writes:
On Wednesday, 18 November 2020 at 01:38:27 UTC, Timon Gehr wrote:
 On 18.11.20 02:19, Walter Bright wrote:
 On 11/15/2020 6:11 AM, donallen wrote:
 [...]
It's a similar approach to how D does functional programming. You can do FP in D on a totally incremental approach, function by function. And just like doing OOP in D, you can use it in parts of your program and not in other parts.
This works for `pure`, but not ` live`, because it is not an issue for an impure function to call a `pure` one, but if a non-` live` function calls a ` live` one, the arguments may violate invariants that ` live` users want to rely on. In any case, `pure` is transitive. ` live` is not even transitive, so you get the same problems the other way around.
I think in the first case it would not be unreasonable to not allow a live function (in safe code at least) to be called where it cannot be guaranteed to be safe even in a more conservative analysis that what live ends up being. My personal opinion is that as soon as the ownership is ready, safe should imply it. Assuming it is properly specified it seems like a better way of doing things than having a big list of do's and dont's for safe code.
Nov 17 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 18.11.20 03:23, Max Haughton wrote:
 On Wednesday, 18 November 2020 at 01:38:27 UTC, Timon Gehr wrote:
 On 18.11.20 02:19, Walter Bright wrote:
 On 11/15/2020 6:11 AM, donallen wrote:
 [...]
It's a similar approach to how D does functional programming. You can do FP in D on a totally incremental approach, function by function. And just like doing OOP in D, you can use it in parts of your program and not in other parts.
This works for `pure`, but not ` live`, because it is not an issue for an impure function to call a `pure` one, but if a non-` live` function calls a ` live` one, the arguments may violate invariants that ` live` users want to rely on. In any case, `pure` is transitive. ` live` is not even transitive, so you get the same problems the other way around.
I think in the first case it would not be unreasonable to not allow a live function (in safe code at least) to be called where it cannot be guaranteed to be safe even in a more conservative analysis that what live ends up being. ...
Sure, but then you get two incompatible sub-languages, there's no good reason to want that and I think Walter agrees.
 My personal opinion is that as soon as the ownership is ready,  safe 
 should imply it.
Absolutely not. live is incompatible with tracing GC, but this is one of the main ways current D achieves memory safety. It would be a huge mess without any justification.
 Assuming it is properly specified it seems like a 
 better way of doing things than having a big list of do's and dont's for 
 safe code.
Or, you know, just add borrowing and ownership properly without botching the design. None of this fooling around is actually necessary...
Nov 17 2020