Hacker News new | ask | show | jobs
by tombert 2757 days ago
I have wondered for awhile now why Rust is getting all this attention of being "Like C but safe and cool!", but no one would mention D.

I personally don't do systems programming because I'm not smart enough but the little bit I have done, I found D to be the most-natural feeling (even over Rust), and D has been around a lot longer.

I suppose timing is everything for these kinds of things.

8 comments

The main reason the way I see it is that a lot of people who still use C and C++ need maximum speed, and D is only memory-safe with its garbage collector enabled. This affects latency and adds overhead. For many cases using a garbage collector is fine, but D was trying to target video games and other spaces where the GC was not acceptable. So D allows you to turn the GC off, but then it's just a vastly less-mature C++ with similar safety footguns and worse library support. Rust actually fills a space that wasn't filled by anything else - memory safety without a garbage collector. You can write pretty ergonomic code in Rust (similar to how code would look in a dynamic and/or GC'd language) just like D, but where in D you would have to choose between highest-possible efficiency and safety, Rust gives you both at the same time.

This isn't to say that Rust is better than D, but it is to say that Rust targets a gap in the market whereas D is trying to have the same tradeoffs as C++ but be better, which is nowhere near as compelling for most developers who've invested a lot of time into learning C++. C++ developers don't use D for the same reason that most people don't switch from qwerty to dvorak even though it's technically more efficient. It's not such a qualitative change that it's worth the retraining.

> D is only memory-safe with its garbage collector enabled.

This is technically correct, but not pragmatically correct. D doesn't have every memory unsafe operation plugged, but it's pretty darned close, and does have the major ones covered (like array bounds checking, alternatives to pointers, RAII, etc.).

> library support

D has excellent library support.

> (like array bounds checking, alternatives to pointers, RAII, etc.).

Yeah but C++ has all of that, too, as well as a vastly broader ecosystem in the space of non-GC'd, ultra-high-performance languages.

C++'s array bounds checking is there only if you use vector<>, not regular arrays.
And D's bounds checking is only there if you don't use pointers or @trusted.

fyi std::array also has bounds checking, you're not limited to vector<> to have that.

D will give you compilation errors in @safe mode if you try to index off of a pointer.
Is the D GC actually that bad? Do we have benchmarks or something to prove that the GC means D is dead in the water? I always hear about this hypothetical danger of GC but my D usage hasn't found it and my D programs typically match or outperform my C++ programs. I mostly use it for numerical code, so maybe that's why I'm not feeling the pain of the GC?

To address your final point, I find D vastly superior to C++. Immensely, tremendously, bigly superior to C++. It's so nice, it's so pleasant, it's so easy. It's not an incremental change, it's a whole new world of no segfaults, no template metaprogramming, beautiful error messages, beautiful compile-time calculations.

There is no such thing as a "good GC" in this context. Game engines go to great lengths to do things:

1) Have bounded memory usage 2) Have consistent frame times

These goals are critical to maintain a consistent framerate on fixed-memory devices (aka, consoles). GCs, by their very nature, are not compatible with either of those goals. They need lots of spare memory to go fast, and they cause hiccups when collection happens. They are a non-predictable, non-consistent load.

If you're not working on a problem that is a sustained, consistent workload that needs sustained, consistent result generation then no, you probably won't see the same GC problems. GCs work great when the work is bursty or when the work has no latency associated with it. There's an awful lot of programs that fit in that model. Games just aren't one of them.

How are GCs not compatible with bounded memory use? Though many GCs size allocation arenas proportionally to the live data, there is no fundamental reason why the allocation arenas couldn't be fixed-size (of course, they must be large enough for good performance, etc.).
And yet there are GCs in Unity and Unreal Engine, the most popular game engines of today.
Only the scripting code is GCed. The core engine in both cases is C++ with manual memory management for the reasons stated above.
On Unity's case with some subsystems in the process of being replaced by HPC#.

And in Unreal you can use GC in whatever components you feel like, it is a matter of weighting where it makes sense.

Electron is a very popular application framework today.
On what concerns video games, all major engines do use GC on gameplay code, including variations of C++ GCs.
emphasis on gameplay code. And even there, if you target 60fps (sure a minority of developers), then GC is a liability at best.
But that is exactly the point. One should not constrain productivity just based on hypothetical goals, web scale and such similar arguments.

Doing the next Fortnite, Crysis or ground breaking AR/VR/Ray Tracing? Sure, every ms/byte counts.

Doing a typical Flash like casual game, game prototypes at Ludum Dare, participating at IGF? Having a GC around isn't the biggest concern.

> Doing a typical Flash like casual game, game prototypes at Ludum Dare, participating at IGF? Having a GC around isn't the biggest concern.

But for those cases, what would move you to use D instead of an entirely memory-safe language like Python or Lua?

To justify using D for games, you'd need to find a use-case where speed (e.g. targeting 60fps) is high-priority enough to be writing a lot of low-level code; and yet, where "having a CG around" still won't cause problems. Can you think of one?

Yes, because it compiles to native code and has relatively fast compile times.

Some AAA studios do use D instead of a C++ based script language exactly for that.

Actually GC can decrease overhead depending on your use of memory since it only frees when memory when it's needed.
> GC ... only frees when memory when it's needed.

This is actually one of the worst features of GC where game development is concerned. Memory usage isn't the main problem to be solved in game engines, it's consistency of execution time.

In that context, even if you're spending more resources on memory allocation/deallocation overall, it's much better to know that you can consistently fit that overhead into the 16 milliseconds you have for this frame rather than having it mediated by a system you do not have direct control over.

There are also other advantages to having more direct control over memory management than is typically allowed by garbage-collected languages. For instance, CPU cache-coherency can be a major performance concern when dealing with the type of computation required for games. Without being able to lay out memory and deal with memory in a precise way, there are whole categories of optimization which are not really possible.

"Overhead" is a term with many definitions.

Non-conservative GCs use a lot of extra metadata to be able to figure out what's a pointer and what isn't. Conserative GCs leak.

In both cases GCs cut into worse case latency.

> Conserative GCs leak.

Yes, but usually the leak is bounded [0], although I'm not aware they evaluated real-world gaming engines. But I guess frame jitter is the bigger problem there.

[0] https://www.hboehm.info/gc/bounds.html

D had a closed source reference compiler for a long time, and didn't have any major backers.

Rust had Mozilla backing early, and was fully open and transparent in terms of community feedback, and wasn't just making a language that had high level features, but was pioneering a new category of language that added tons of safety guarantees at compile time by default using a new paradigm of enforcing borrowing and ownership.

These safety guarantees are not just in regards to memory safety, but also in regards to data races.

D seems to allow memory safety guarantees, but not by default, and I believe it is enforced at runtime not compiletime.

So Rust was at once more accessible and more exciting.

D's only runtime memory safety feature is array bounds checking. (The same as Rust, I believe.) The rest is compile time.

D's compile time memory safety focusses on:

1. @safe and @system code

2. disallowing unsafe pointer operations

3. safe alternatives to pointers

4. controlling escaping of pointers

5. controlling the scope of addresses

Rust has other runtime memory safety checking, like RefCell.
D's compiler was never "closed source" if by that you mean "source not visible". It had a weird non-open source license for a long time, but the source has always been visible.

The weird license did use to scare me away, but that's very much a thing of the past now and now it has a standard free license.

https://news.ycombinator.com/item?id=14060846

I don't think D's features are any less exciting than Rust's, but Rust has had a lot of RESF backed by Mozilla.

Source code being visible doesn't make it open source. It had a personal-use-only license, which isn't a valid OSSI license (which is what makes something open source).
That's why I qualified it with "if that's what you mean by closed source". I don't know if all source is either open or closed and anything that isn't OSI-approved is closed. I don't think that's what people usually mean by "closed source".

I also freely granted that dmd's ad-hoc license wasn't open source despite having visible source.

> D had a closed source reference compiler for a long time, and didn't have any major backers.

In addition, wasn't there for a while two separate and incomparable versions of the standard library that fragmented the community?

That was 9 years ago and the second is no longer maintained (for about 2 years at this point).
That's fair, I suspected that people who knew more about this stuff had a reason.
Compiling slower than C++ is not exciting.
just to be clear, p0nce is referring to rust's compile time. D is known to have very fast compile times (unless you are doing very template heavy meta programming..)
Rust brought something new that no other language had: memory safety through statically enforcing object ownership and borrowing. Anyone who has done manual memory management already is familiar with those concepts, and how difficult that can be to track in large systems. Whenever a language is able to abstract pervasive concepts to first-class entities in a language, it becomes attractive to people who deal with those concepts on a regular basis.

D, from what I am aware of, did not offer any new abstractions. Rather, it was an attempt to do all of the existing abstractions in a better way. Which is laudable, but it can be hard to convince people to switch to a language when it offers only iterative improvements.

I'm excited for Rust because it might be finally time for a better safer embedded language (no GC is basically required here) and I like using it for little tools where I process huge text files.

Zero copy (in a safe way) makes everything super high speed.

We are working on improving scope atm which is quite an improvement. Tieing exceptions into it too to remove allocations.
> I have wondered for awhile now why Rust is getting all this attention of being "Like C but safe and cool!", but no one would mention D.

D is still build around a GC so it doesn't really fit into a discussion about GC free languages. Unless you want to focus on its "better C" subset, which I think puts it at a disadvantage compared to any language not fundamentally designed around the presence of a GC.

Nah, -betterC gives you an advantage over C. It isn't meant to give you an advantage over languages like C++. Its in the name after all ;)
You can use -betterC and link with C++ code, too.
D is in an awkward spot. C++/Rust folks dislike it for using a GC. Java/C#/Javascript folks dislike it for being too C++ like with pointers, templates and all. The people who use it don't care about language wars and just enjoy their tool.
I can identify several traits that helped Rust be more marketable over D.

First is that Rust is making tooling a central issue they're working on. Right now you can install VSCode and get a Rust plugin with a single click or get a VisualStudio plugin with a single click, and that gets you intellisense right away. I'm pretty sure that Rust's editor tooling has reached and surpassed D's in a comparatively tiny timeframe.

Second, Rust comes with an opinionated build system and module system out of the box, while D just has a compiler, you need to figure out building yourself and use a separate package manager. This is something you would be very comfortable with if you're a C/C++ programmer, but not so if you're using pretty much any other mainstream language. These days it's expected that the language comes with a compiler, build system and package manager.

Third, Rust is more novel, thus more interesting. It's a new language combining new programming paradigms in a novel way. Go has channels and goroutines, Rust has the borrow checker and zero overhead compile-time memory safety. D has... it's trying to be a better C++. It's succeeding very well, but its features aren't exciting.

In conclusion, Rust has come out the gate with great marketing, with novel and interesting features not seen before in a system programming language, and with great tooling support for the current generation of developers who don't want to bother with learning arcane Makefiles (or CMakefiles as the case may be today). D is just a better C++ with the same friction to use as the language it's trying to replace, but without the top-notch tooling that exists for C++. Rust on the other hand also doesn't have tooling quite as good as C++, but it's not replacing C++ in existing projects, it's used for new projects.

One case where D significantly outpaces Rust is in its ability to interface with C++. This gives it a significant edge in being considered for use in C++ projects, and I would expect that there are many cases of mixed D and C++ usage among the D success stories. Rust's lack of C++-compatibility story (I will be interested to hear how Mozilla integrate it with their C++ code!) is really what's holding the language back for my use-cases. The C ABI may be the lingua franca of low-level code, but a significant amount of native code is written in C++ and I need to interface with it natively via the platform's dominant C++ ABI. D would really shine in mixed C++ projects, but it really needs a turnkey solution for intellisense integration, i.e. better tooling. It would also need seamless debugger integration, letting me trivially step through D, C++ and C code in a mixed setting, and letting me place breakpoints, watch memory, etc.

> (I will be interested to hear how Mozilla integrate it with their C++ code!)

There was a good blog post about this the other day: https://news.ycombinator.com/item?id=18588543

The Rust community is extremely hostile, especially against other languages, and D in particular.
I think I know what you are talking about, there does seem to be a general sense of elitism in the Rust community. Kind of a thought that Rust is the best language for almost any task, why would you use anything else? I think that thought process is present in many software communities however.

I have found the Rust community to be one of the most helpful and welcoming to beginners, and I don't believe this to be contradictory of what I have mentioned before. Rust developers want their community to grow so to spread the good word. Maybe it comes off too strong sometimes by pointing out where Rust has strengths against other languages, but if that is the among worst the community does, I would consider the community pretty friendly.

Really? The few times I've used Rust, the people on the IRC channel were really nice to me and helped me get bootstrapped.
Its not hostile. Its aggressive in selling the strong points of the language. Having said that, I do wish newer languages spring up that adapt the good stuff from Rust. I can never like Rust syntax.
A ludicrous amount of engineering has gone into the Rust compiler, the extensive documentation in RFCs about its design, the huge language docs that took a million man hours to make, RLS is another huge undertaking...

I do forsee Rust getting a Coffeescript of its own. I'm in love with the control flow model of the language but always felt some things that were in from day one (like double colon :: namespace delimiters, ampersand references, asterisk pointers and dereferencing, semicolons, curly braces, etc) were just wholesale copied from the languages de jour of the day because the focus was on the borrow checker as an innovative feature. So the semantics and ergonomics were completely phoned in early on, and by the time the modern development process around the language and compiler matured the glyphs were so totally entrenched there was no way to reconsider any of it.

A syntactic wrapper that gives you the types and behaviors of Rust with beautification like whitespace significance over mandatory brace delimiters and semicolons (like Python) with single colon (or maybe even dot) namespacing and such would be an insanely hard project (because parsing Rust is already insanely hard, and a lot of work went into minimizing compiler passes to parse grammar so keeping that with less control characters to work with in an intuitive way sounds like a substantial exercise in ergonomics) that compiled to ugly normal Rust would be fantastic to help newbies avoid the "glyphic overload" I easily see happen to anyone I try to preach Rust to.

I totally agree re the ergonomics. It really feels to me as if a lot of C/C++ conventions were copied over, with no justification beyond "this is what system programming languages look like".
It would be ironic if D language did precisely that.
Where do you see that happening? I'd love to tell some people to cut it out!
In this post about D, the top comments are about how great Rust is. But mentioning D in a post about Rust is like sticking your head into a bee-hive.
The top comment is about how much they love D, and wonder why others don’t. So people are answering that question.

I don’t see how that’s the Rust community hating other languages, but answering a question about preference. They’re all respectful answers.

I don’t see it here, sorry :/

The Rust Community is:

    Welcoming
    Inclusive
    Developers prioritize mentorship
    RFC process
    Energizing

It's written in the Rust Marketing Handbook so it's true: https://rust-lang.github.io/rust-marketing/pitches/community...
Not at all, they even put up with my schizophrenic arguments of C++ vs Rust vs whatever.
In my experience the rust community has been incredibly welcoming and nice.
Because there is no big company behind D. Rust isn't good as boasted. But firefox and HN willing to blow the bubble. That's their company's strategy.
> Rust isn't good as boasted

What do you mean? What's being boasted about Rust and what makes it untrue?