Comment by chubot

3 months ago

So in D, is it now natural to mix borrow checking and garbage collection? I think some kind of "gradual memory management" is the holy grail, but like gradual typing, there are technical problems

The issue is the boundary between the 2 styles/idioms -- e.g. between typed code and untyped code, you have either expensive runtime checks, or you have unsoundness

---

So I wonder if these styles of D are more like separate languages for different programs? Or are they integrated somehow?

Compared with GC, borrow checking affects every function signature

Compared with manual memory management, GC also affects every function signature.

IIRC the boundary between the standard library and programs was an issue -- i.e. does your stdlib use GC, and does your program use GC? There are 4 different combinations there

The problem is that GC is a global algorithm, i.e. heap integrity is a global property of a program, not a local one.

Likewise, type safety is a global property of a program

---

(good discussion of what programs are good for the borrow checking style -- stateless straight-line code seems to benefit most -- https://news.ycombinator.com/item?id=34410187)

> So in D, is it now natural to mix borrow checking and garbage collection?

I think "natural" is a bit loaded, there is native support in the frontend for doing both. You have to go out of your way to annotate functions with @live and it is still experimental(https://dlang.org/spec/ob.html). The garbage collection is natural and happens if you do nothing, but you can turn it off with proper annotations like @nogc(https://dlang.org/spec/function.html#nogc-functions) or using betterC(https://dlang.org/spec/betterc.html). There is also @safe, @system and @trusted(https://dlang.org/spec/memory-safe-d.html).

So natural is a stretch at the moment, but you can use all kinds of different techniques, what is needed is more community and library standardization around some solutions.

> is it now natural to mix borrow checking and garbage collection?

D is as memory safe as Rust is, when you use the garbage collector to allocate/free memory. If you don't use the GC in D, then there's a risk from:

    * double frees
    * memory leaks
    * not pairing the allocation with free'ing

Those last 3 is what the borrow checker handles.

In other words, with D, there is no point to using the borrow checker if one is using D's GC for memory management.

You can mix and match using the GC or manual memory allocation however it makes sense for your program. It is normal for D programmers to use both.

  • > D is as memory safe as Rust is, when you use the garbage collector to allocate/free memory.

    Does D also protects against data race?

    (I couldn't find an obvious answer after a bit of research, but I might have overlooked something)

> "gradual memory management" is the holy grail

I don't think gradual types are as holy grail as you make them out to be. In gradual typing, if I recall correctly, there was a large overhead when communicating between typed and untyped parts. But further

But lets say gradual memory management is perfect, you have to keep in mind the costs of having GC + borrow checking.

First thing, rather than focusing on perfecting GC or borrow checking, you divert your focus.

Second, you introduce an ecosystem split, with some libraries supporting GC and others supporting non-GC. E.g. you make games in C# and you want to be careful about avoiding GC, good luck finding fast enough non-GC libraries.

  • Not all languages using a GC are designed that way, where libraries are dependent on it. For example, in V (Vlang), none of their libraries need the GC. They also can freely mix memory management methods. There is no ecosystem split, but rather preferences.