Hacker News new | past | comments | ask | show | jobs | submit login
Driving with D (dlang.org)
351 points by pjmlp on June 1, 2021 | hide | past | favorite | 181 comments



Hi, I'm the author of the article. Feel free to ask any questions you may have.

I have to go to bed, I have work in about 4 hours, so I'll reply when I can.


This is what I love HN for. Every now and then there's a submission like this that makes me go: "How do you even...".

That being said, is there maybe somewhere a more thorough write-up about the whole thing? You know, with more in-depth technical details, gotchas, and so on? I'm sure many people would enjoy reading that!

Thanks for posting!


Thank you so much for the kind words :)

Sorry, no. I don't have a blog or website or anything. The closest thing I have to a devlog are some posts in a private Facebook group dedicated to the Holden Commodore.

I think this project is almost 12 months old now.


This project sounds awesome. I hope you will find some time later to post it on the web. So much legendary information is stuck in Facebook, and difficult to find, or just lost forever.


I'll try to get some website up in the future!


What are the legal hurdles you had to jump to get this hack approved for street use? As car modders know all too well, this can often be the hardest task.


Fortunately, and surprisingly, this project was smooth sailing on the legal front.

I contacted a VicRoads certified engineer in regards to the project and got the all clear.

Even my insurance was OK with it.

I think it's because most of the legislation is aimed at engine modifications.


That's cool. Over here (Sweden) it's not easy (if at all possible) to get these kinds of things approved.


That really sucks :(


I follow the car modding scene and to be honest, in the U.S. there don't seem to be anything preventing this from being street legal. Even in California, something like this being a non-engine mod I don't see it being an issue.


Agree. If you start messing with the engine, and heaven help you, emission related equipment, you are going to have a long journey, and a lot of bumps along the way. Anything else? Pretty much, have at it.


It's very much the same in Australia.

The approval I got from the engineer was due to the following points:

1. The 6 speed came out of a newer generation of the model.

2. My controller has some safety features.

3. My controller emulates factory hydraulic behaviour. Had I implemented something like a transbrake, I would have been in for a very long ride of red tape.


Hi,

Firstly, Congratulations. This is no trivial accomplishment. Here are the questions I have.

1. Normally, cars come with their own ECUs for the engine. Interfacing with them requires knowledge about the underlying firmware used afaik. Did you happen to reverse engineer the firmware so that you could interface your own electronics with the provided ECU ?

2. How did you make the car believe that your 6 speed automatic transmission was a 4 speed automatic ?

3. > "the ability to go ahead and change the way it works whenever I want." - Could you please elaborate what you mean by this ?

Again, I am amazed by what you have accomplished. My inner mechanical engineer is so keen to know how this all came together. I think everyone would definitely appreciate if you could provide a rough overview of how you achieved these things. Thank you :)


1. I don't interface to my car's electronics over serial or CAN bus. Instead, I interface by emulating actuators and sensors the 4 speed gearbox computer expects.

2. I'd like to introduce you to "manualisation" [0]. It's where the solenoids of the 4 speed are wired directly to the gear selector switch. The 4 speed computer is surprisingly tolerant of this, and it forms the basis of my interface.

My interface provides enough information to the 4 speed computer to stop it from erroring out or putting my car into limp mode. However, it is aware that something has changed because changes in engine RPM do not correlate with its shift commands.

3. I mean in terms of software. I can modify the behaviour of my box more than a standard tune can. I can add a 0-100KM/h tracker to my system, or shift lights, I can fundamentally change the decision making process in shifting (for the moment it's torque based), etc.

I could go out on a limb and a GPS module and a map; it'd select a gear based on the corner angle and speed or so.

Thank you for kind words :) If you have any other questions, ask away!

[0] https://youtu.be/H1T6vr44Zak


Thank you for your reply. That is quite enlightening. I am quite surprised that the Transmission Control Unit(TCU) is tolerant of the solenoid modification. However, I have two questions though.

1. So based on my understanding, engine speed sensor readings are sent to the TCU which in turn regulates the solenoids(There might be other sensors as well but for my question, I think they aren't that important). So in order for your modification to work, you have to get these CAN frames, understand the reading, regulate your 6 speed auto gearbox and then create a CAN frame that would imitate the sensors of the 4 speed auto gearbox(to basically tell the TCU that the gearbox has been regulated correctly). You can in principle neglect the actuator commands that are sent by the TCU to the solenoids since you are regulating it on your own. However, in order to do this, you have to understand the CAN frames being used and also the protocol used(address based or message based). How did you figure this out ? Or is my understanding wrong here ?

2. Did you use FreeRTOS for your STM32F407 component ?

I really appreciate you taking the time to answer the questions :)


I was quite surprised, too. Maybe it was a little gift from Holden to the burnout bogans?

1. My apologies, I've confused you. CAN communications are purely internal for my system, it doesn't communicate via CAN to the car's computers.

The sensors and actuators give or accept voltage signals, and my controller inputs or outputs those accordingly. For example, the 4 speed has some pressure sensors to monitor the valve body behaviour, and I send some HI or LO voltage signals in emulation of it.

2. I do use FreeRTOS for the 407. I don't need to, since I use a super loop and all my memory is either static or allocated on the stack.


Ah okay. This simplifies the setup a lot. I had done some testing and validation of ECUs 9 years ago. So my questions were based on the understanding I had developed back then. Thank you for clarifying it. Again, awesome work :)


If my car relied heavily on CAN (like the next generation Commodore) I probably would have sold it.

I love CAN bus (for my own designs), but I don't see the effort of attempting to reverse engineer GM's format as worth it, especially since I had no prior experience with CAN.

Thank you :) I've got another D automotive project which I hope to write about soon.


Sorry for my late reply. I'm currently at work- I'll make sure to reply when I knock off. Have a great day :)


No problem at all. Take your time :)


You're a wizard. I wouldn't have a clue where to start with a project like this.


Thank you!

I spend a tonne of time in the reference manual for the 6 speed, and things clicked for what my next steps should be. It was really about trying to familiarise myself with the problem as much as possible.


No questions, but let me just congratulate you on a wonderful hack, very well done!


Thank you so much for the kind words :D


Long live Holden, long live the ute!! Thanks for keeping your VZ alive


I plan to keep it for a while yet!


Out of curiosity, what is your job?


I'm a full time university student (20 y/o). I work part time as a labourer for a crane truck company.


He said he's gone to bed, but he's a student.


I must have missed that comment, just saw "I have work in about 4 hours"


It was on our discord, I should've said. Feel free (to anyone) to join if you'd like to learn more about D.


Any reasons D never caught on more? No big tech company anchor behind it?


I used D for a while. It improves several things over C++, among them:

- More powerful metaprogramming capabilities.

- Better module and library system.

- Nicer syntax.

The problem IMO is it's just not enough to justify a total move from C++ -> D. The syntax of C++ can't really be fixed, but the other aspects can be improved without a new language.

Furthermore, many of the other downsides of C++ are still present:

- The complexity of the language, and then the sheer number of different ways of doing the same thing.

- Some pretty dark corners in the way stdlib/language feature were implemented that seemed hard to ever fix.

- The way behaviour is specified in the language is very tied to the underlying hardware: rather than explicitly describing behaviour in terms of an abstract machine, it works more in the way C++ is specified where we all know it operates on an abstract machine thanks to compiler optimizations, but the spec likes to pretend it doesn't...

And then there are problems that are introduced by D, such as the fact that a safe subset exists, but depends on GC, so there's a weird split where no "safe code" can be used in contexts where GC is unsuitable.

Contrast this to Rust, where:

- There is a true step-change in bringing safe code to all contexts, not just those where GC can be used.

- It's missing a lot of the complexity of C++. Rust is hard because it has concepts that are foreign to a lot of programmers, but the total number of features is low (compared to C++) so there are fewer surprising ways they can interact.

- Rust is a suitable replacement for C, not just C++, because it's not just adding more features.


D is easy to pick up, and has three really fast compilers. It feels like a very practical language.

Rust in comparison feels much less practical - glacial compile times and byzantine rules about manging memory. It may be 'safer' but that's a moot point when I find it all so unintuitive that I'm not going to be able to make anything with it anyway.

And I really question what these situations are where you can't have garbage collection in 2021. Hard real time systems, sure, but that's not what 99% of people are using rust for. Maybe people just like the challenge.


>And I really question what these situations are where you can't have garbage collection in 2021.

Game development, anything with a UI (GC pauses frustrate users), anything that needs high performance (scientific applications, data analysis), you name it. Ownership semantics have a side-benefit of automatic thread safety; something that is less important than memory safety (because many programs can work in one thread but almost no programs can work without allocation) but extremely valuable when needed.


>Game development

C# Unity, Lua Love 2D,...

>anything with a UI (GC pauses frustrate users)

Millions of C#, Java, Python, Javascript UI apps

>anything that needs high performance (scientific applications, data analysis)

Numpy, Julia,...

Using non garbage collected languages for 99% of apps today is a waste of time, and i'm saying this as mostly an embedded developer.


You listed a bunch of engines written in C and C++.


How does that matter? You said "game development", not "writing a game engine". You said "data analysis", not "writing linalg algorithms", in which case we'd all have to bow to Fortran anyway.

Your argument also doesn't apply to GUI apps, anyway. C# and Java amount to a huge number of such apps, and they're self-hosted.

GC languages are vastly more productive that manual-memory languages, and for the vast majority of users, that is worth the performance hit.


If your suggestion is, "GC languages can be used to write anything so long as whatever parts can't be written in a GC language are written in a non GC language," then yes that's true. But it's also a tautology.


If you need to stay away from the GC because of some practical reason, you can always write C/C++/Rust. You implied that this is a frequent situation when it isn't. Your example of "anything with a UI" was quite a bad one.

Most projects are better off written in a GC language because the productivity benefits outweigh the performance costs.


There is a lot being said about productivity gains from GCed languages, but can you actually point me to any research showing these gains are real?

My anecdotal, unscientific experience shows that GC is a double-edged sword that maybe makes writing simple programs slightly faster, at the expense of a much worse maintainability once the code base gets big. And non-memory resource management in GCed languages without RAII is a really huge PITA that kills all productivity gains.

GC allowed memory safety until Rust happened, and that was a big gain, but now that point is moot.


In practice it is even not true, because there is a non-zero cost of interfacing between managed runtime and native non-managed code. Therefore not every piece of code that would theoretically benefit from writing in a non-managed language, could be actually rewritten.


Unreal then,

https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScrip...

Or you prefer anything written in DirectX or Metal?

Chapter 5 from The Garbage Collection Handbook.

https://gchandbook.org/contents.html


Unreal is written in C++ but, like Unity, can be scripted in other languages. Like unity it fits the "GC language for high level scripting of non-gc code" pattern. There is certainly no debate about the feasibility of implementing game logic in Lua. Reference counting in graphics drivers is not comparable to GC in Java or C# because its lack of generality permits the use of faster algorithms that don't GC pause. Swift is a workable systems language with reference counting built in, but you should bear in mind that it doesn't have "a garbage collector" per se, like you would imagine when you hear that a language is GC'd.


Reference counting pauses when cascading deletions take place, it well known domino effect.

C# allows for GC free regions with GC.TryStartNoGCRegion, manual memory management via MarshalServices, stackalloc, Span<>() and value types.

Almost forgot Unreal C++ is GC based for entities and anything Blueprint related.


Audio plugins is one case. Dplug disables the GC because of an issue on MacOS. So far there is no workaround so we have to write @nogc code.


On Windows you can use C# for audio plugins.

https://docs.microsoft.com/en-us/windows/uwp/audio-video-cam...


I am learning Rust and SPARK2014, and I would think SPARK2014/Ada would be a better fit for high-integrity software for verifiable, embedded software than Rust. This was the older article that stimulated me to look at Ada and then SPARK2014 again:

https://www.embedded.com/spark-2014-why-i-am-backing-a-predi...

EDIT: Cool list of SPARK2014/Ada embedded projects: https://blog.adacore.com/tag/embedded%20development


Ada is absolutely great, it's a shame that is was "closed" behind really expensive compilers and government work in the past.

GNAT Aux could use some help too:

http://www.dragonlace.net/


That's probably true for now. But only because there's no equivalent to SPARK for Rust yet. Rust + something like SPARK could be really amazing.


There are some things that attempt to come close. Prusti by ETH Zurich is maybe the closest.

https://github.com/viperproject/prusti-dev

https://www.pm.inf.ethz.ch/research/prusti.html

    extern crate prusti_contracts;
    use prusti_contracts::*;

    #[requires(something)]
    #[ensures(result >= a && result >= b)]
    #[ensures(result == a || result == b)]
    fn max(a: i32, b: i32) -> i32 {
        if a > b {
            a
        } else {
            b
        }
    }
Ada seems like a fantastic language though, and the 202x edition brought some niceties to the language.


I am an Ada/SPARK novice, but on first look Prusti seems to deal with contracts, but I am not sure how much more of the Ada/SPARK system it may covergg. I used to dislike Ada and SPARK due to their verbosity, but after studying some of the embedded work in them, and what they bring to the table, I am no longer put off by that or syntax. I've seen Julia and even Elixir projects in areas that would better suit Ada/SPARK, but I think it is due to their popularity rather than applicability. But things like Elixir's Nerves platform is very interesting in bringing the BEAM to the embedded world, and I love Pluto notebooks for Julia, but for high-integrity software I think I'll try and leverage Ada/SPARK's capabilities and pedigree for now. I will look further into Prusti this weekend.


Rust's type system still lacks the expressivity of Ada. Rust has a lot to teach Ada (and you see this coming out from AdaCore's blog recently with efforts to add lifetime analysis to SPARK), but Rust has a ton to learn from Ada as well.


I agree, but I just turned 57 (been programming since 1978 for fun), and there is so much already done in Ada that powers SPARK that it will be a while for it to be tried and true. Although, with all the work on theorem provers and such, maybe it will be exponential and I'll be around to see it. I really like Zig too, but I am staying with Rust because of its inertia. At heart, I love J/APL, but I use them for wholly different reasons.


Interesting work in that direction https://www.youtube.com/playlist?list=PL-uEDsw-7yRLYMEdlvh4u... Rust verification Workshop 2021


> such as the fact that a safe subset exists, but depends on GC,

@safe works perfectly fine and exactly the same in @nogc code as in GC-enabled code.


My mistake - SafeD was introduced since I stopped using D, so I was going off this article:

https://dlang.org/articles/safed.html#safed-subset

> When you enter SafeD, you leave your pointers, unchecked casts and unions at the door. Memory management is provided to you courtesy of Garbage Collection.

Does D provide the necessary tooling to be able to expose a safe API for something which needs to allocate memory, without needing a GC?


You are stuck with dropping to @trusted and calling the appropriate allocator API.

Following that you will want to check for null ext. to make it actually @safe in practice and not just typed as such.



That's a bit disingenuous. Memory allocations in D require either GC or non-local unsafe code.

I'm aware that D has @live, a WIP attribute that mimics Rust semantics, but it's not remotely ready for production.


The idea that Rust is suitable to replace C and D isn't is odd to me. It's really not hard to do + we (unlike some languages, not sure about rust) actually test on embedded targets via GCC.


What I meant by this is: if you are starting a project today, and have to choose between C and C++, there are certain reasons why you might choose C over C++.

Those same reasons would apply for choosing C over D. They might not apply for choosing C over Rust.


I can't think of a reason that would apply here. For me at least if I were on a toolchain so crap I had to use C you'd have to pay me a lot of money not to work on something else.


All my embedded design work has been in C as i don't need all the extra cruft.

Also anything i want to be very fast on limited hardware i also use C and C only.

As for any hobby programming i do on the side, C is usually my goto choice, unless i want to be very esoteric.. following along the lines of: "The enemy of art is the absence of limitations."


I find that C actually gets in my way compared to D when I am writing code with limited resources. The end result is semantically the same but with D I can avoid macros, inline asm is easier etc.


while this makes all the sense in the world to even a seasoned C programmer...

I've been doing it so long I could write macros in my sleep, and inline asm is a fun little exercise.

Though i absolutely agree, especially with someone newer, that could be a major road block. Might want to learn D just to be more efficient (even though I will never abandon my first love completely)


Almost the only reason I would choose c over c++ for embedded would be if the c++ compiler was garbage for the platform or the team wouldn't allow it.


Except that Rust compilers seem incredibly hard to implement, as opposed to C.


To give some perspective: mrustc is written mostly by one person, in C++ and it caught up to 1.39.0 recently - meaning it can "compile" rustc itself (without any type safety validation) as opposed to arbitrary Rust code.

Also C++ compilers are hard too. And optimizing C compilers are hard too...


That is very true but absolutely fine because then some fine set of engineers can do the hard lifting parts and rest of the ecosystem can thrive on stable base that core establishes. That is how things work in most of industries, not everybody is writing a compiler (or even suitable for writing one!), but the complexity compilers remove lets you build more complex pieces of engineering.


I don't think minimal compiler complexity is a real requirement as much as safe and reliable software is.

CPU fabs aren't easy, yet we're fine with that.


It matters for portability. I'm not saying it's the most important requirement, of course, but it's C strongest point.


Do you need to build an entire compiler or "just" the backend/code generation to port something? Although "just" a code generation for Rust means building one for LLVM, which I'm sure is harder than some C compilers out there.


The things that make D special - culturally even - are quite niche so while it's been extremely profitable for many who do use D, D is sometimes not an easy sell in the sense that the things that D makes easy are not things you encounter in the first few minutes of using a language.

Also: Marketing, a lot decisions are made based on nothing, we're too modest (to be blunt).


As far as I know D's original design strategy, was to be a simpler to use C++ with a GC, but with the same expressive power

Over time, this proved to be a bad strategy, C++ key strength became RAII (deterministic memory management), so the GC became a failed strategy

The maintainers tried to move in different directions, adding manually memory management, making the GC optional, moved D to be a C replacement, with the -betterc compiling option, and many other tweaks and features added overtime, but nothing really caught on


This isn't a very good summary of how the language evolved.

D has basically always had the ability to not use the GC, it's only recently that we've taken an interest in replacing C. The GC has been written in D for a very long time, that wouldn't be the case if the language didn't allow manual memory from day 1.

BetterC is a nice-to-have rather than a language dialect.

Having a GC is an absolute godsend for getting clean code out of the door quickly.


on the point of the GC being a good thing to have, this is true, but not when your main objective is to replace C++, C++ key advantage being RAII deterministic manual memory management

You cant replace C++ with GC language, even 10 years ago this should have been evident to a seasoned developers such as Walter Bright and Andrei Alexandrescu

Sometimes great developers are bad product managers

Anyway, with Rust and Go, D have no where to go, I don't think it should be fixed to appeal to a wider user base, the only good strategic move they can do today, it make it better for the current user base, they have few big users, they should focus on them and the language will fade once those users move on to something else


Then don't use the GC? Ignoring that a lot of C++ developers are practically incompetent and completely unable to separate their ideology from the actual requirements of their software (I note that not one single even anecdote has been mentioned regarding the GC in this thread), D gives you the tools to do that already. I work argue not as polished as C++, but that really doesn't matter if you set out to write a new project.

Also, if you think existing D users are going to replace D with Go I don't know what to say to you. Go and Rust are literally punchlines without a need for a joke in discussions I've had with many senior people at these companies (Mostly Go). The reasons why people use D are so utterly detached from everything that has been discussed in this thread that I don't know what to say to you. Go is a bad programming language, pure and simple, good ecosystem, awful language.


You surely can, it depends on the domain.

"Lockheed Martin reviewed various options for the Aegis Open Architecture including the programming language and execution environment for the system. In their experiments, they found that HotSpot Java code ran comparable to C++ on an experimental 250 millisecond periodic workload. At the same time, they found that the Java language provided superior abstraction and encapsulation than C++, and they judged that retraining their existing staff of CMS-2 programmers to become effective in Java would have lower risks than attempting to train them in C++."

https://www.ptc.com/en/blogs/plm/ptc-perc-virtual-machine-te...

So there you have it, Java powering battleship weapons targeting systems, after replacing C++.


HotSpot was not the mainstream JVM I see now its been opensourced, and apparently, np longer in active development, and I dont know how much of it made it into mainstream Java

Java is one of the top 3-5 most popular languages, and have huge backing

So its understandable that people found a way to make it fast, and honeslty, i dont really know how much effort does this require, but it seems from your example, it less than what C++ need

This all in all, seem counter intuitive, if Java is really as fast as C++, why is it that mainstream knowledge suggest otherwise

Either, your example is hiding something, or there is other reasons people still use C++ when they need high performance

D was meant to replace C++ not be a fast Java like language, I would argue, it achieved neither

D wanted to be a mainstream language, this is why the adopted the C/C++/Java style of programming, and again they didnt achieve this objective

D is not instinct, it still have a small dedicate user base, I just wholeheartedly think, today, you have far better options: Rust, Go, OCaml , C# , Kotlin


My example is not hiding anything beyond the fact that most people are clueless about how big Java ecosystem actually is.

Not everyone is doing Websites or Android apps.

PTC isn't using Hotspot, rather their own JVM implementation.

Just like C++, Java enjoys multiple implementations.

Just like C++, the best ones for embedded deployment with soft real time capabilities, are commercial, directly supported by hardware vendors.

D's biggest failure so far is not having a Google or Apple behind it, that would push the language no matter what naysayers have to say against the language.

Just like on iOS and Android, wanna play? Here are the allowed list of toys.


D had Andrei Alexandrescu behind it for years, he worked at facebook for a while and tried to push D there, and they did used D for while

Andrei is a big deal i would say

Since then FB moved on the build their own Ocaml based language reasonml

Julia doesn't have a big company behind, yet the language is steadily climbing the popularity ladder (and i doubt they have anyone at the calibre of Andrei Alexandrescu, but again, good pogrammer is not a good program manager)

D is not popular, because its leader failed at making it popular, they failed to give the qualities that would make it popular


Last time I checked MIT is rather big.

Facebook never really adopted D beyond a C++ preprocessor written in D.

And yes the community is rather lousy with language marketing, which is completely unrelated to technical achievements.


A product failed, blame the product owner (designer, maker, etc..)

Why are you refusing to blame the product owner

D is not a good language, it really is not, it doesn't offer any compelling advantage to justify accepting its flaw

Or simply put, its a bad product A bad product doesnt have to be trash, just enough bad design issue to make it bad I would strongly recommend new developers not to touch it there are far better option

Say it as it is, its simple, its the truth

Its functional, people use it, but its bad C++ is also bad, but its so overwhelmingly popular that you might want to learn it D is bad, and is unpopular


>D was meant to replace C++ not be a fast Java like language, I would argue, it achieved neither.

Cannot comprehend your logic here, one of the Java objectives was also to replace C++. It kind of achieved the objective by consistently being top 3 languages since its introduction and it achieved that by not even natively compiled, unlike D. Based on Java story, it seems that having no GC is not a required condition for success. I'd had imagined if Java is not being invented the entire Android eco-system (the world's most popular operating system) will be written in C++.

>D wanted to be a mainstream language, this is why the adopted the C/C++/Java style of programming, and again they didnt achieve this objective

Not sure what is your point here since almost every programming languages wanted to be a mainstream language including Ruby, regardless whether the author admit it or not.

>D is not instinct, it still have a small dedicate user base, I just wholeheartedly think, today, you have far better options: Rust, Go, OCaml , C# , Kotlin

I think you meant 'extinct'. Time will eventually tell and no need to be so negative. When Python was 20 years old (about the same age as D today), it literally was playing a 2nd or 3rd fiddle to PHP, TCL, Perl, R, Ruby and Matlab in their respective domains, and look where is Python now? I believe even Guido did not have predicted the astronomical rise of Python at the time.


> your main objective is to replace C++

D's main objective is to be useful. I did some hobby C++ that I replaced with D, but my main D migration was actually from PHP.


Would it be fair to say that for some time (I wouldn't know exactly when it started) D has evolved to serve the needs of the D community rather than to attract new people?


Attracting new people is basically never (with exception of the C stuff) been the driving force behind efforts influencing D's design.

Another anecdote - Someone who hires people in D has told me definitely that D being small means that hiring for them is usually just seeing some code, i.e. there hasn't been an eternal September let's say. They can onboard people who don't know the language, but knowing D is a very good cultural (programming is easy!) filter.


Thanks, that's interesting.


No it wouldn't be fair to say that.

Lots of stuff exist specifically to help with onboarding people into the community. Like the recent announcement of adding a C parser into the frontend.


Certainly not the sole reason, but the mix of language features puts it into a weird spot: You have great control over memory layout and can easily embed assembler, which would be perfect for performance sensitive software like games. Yet "default" D comes with a garbage collector and - more importantly - language features that require said GC.

If you want to go the noGC route, you have to refrain from using certain language constructs, which puts you in a similar spot as with C++...

And if you actually want a GC, you might find the simple linear allocator of D to be lacking...

D is a very cool language, but it is also a lot like QTified C++... Which, well, already exists...


> language features that require said GC

A whole two features:

1. concatenating strings using the ~ operator. You can concatenate strings using malloc if you prefer.

2. closures that escape the context of the function they enclose. Instead, write a struct with fields representing the values, and make the lambda a member function of that struct. Allocate the struct instance any way you wish.

The GC is a convenient feature with lots of nice uses. Programming in D is not impaired by not using it.


Maybe something changed, but I thought array concatenation with ~, associative and dynamic arrays as well as exceptions rely on the GC as well.

It's a short list, for sure, but thats not the point: Anyone looking into using D without GC will see that there are some language features that require special care.

At that point it becomes a valid question why one should learn about the pitfalls of GC free D, when one already knows that about the currently used language.

GC free D is low friction, but seemingly not low enough for uptake from interested parties.


> array concatenation with ~, associative and dynamic arrays as well

Yes. Walter was referring to the operator itself. Strings are arrays.

> as well as exceptions

It's not exceptions themselves, but the `new` operator. It directly allocates from the GC. That said, there is a plan to enable @nogc exceptions.

> At that point it becomes a valid question why one should learn about the pitfalls of GC free D, when one already knows that about the currently used language.

People who already know another language and are happy with it have no reason to switch. Why would they? It's people who aren't completely satisfied with a given language that are going to be more open to looking at others. And so of course then it's a matter of weighing pros and cons. Do I like the syntax? Does it feel intuitive? Am I comfortable using it? Do I find the pain points blockers or minor annoyances?

There is nothing special about D in this regard. If you aren't looking for a new language, you aren't going to try it. And if you are, you either like it or you don't.

WekaIO wrote the world's fastest filesystem in D. They did it without the GC, and went so far as to write their own GC_free standard library (which they open sourced). Their CEO talked about why in this interview:

https://dlang.org/blog/2018/12/04/interview-liran-zvibel-of-...

That said "GC-free D" is not a major selling point of the language. You will not find the maintainers recommending anyone start a D project fully GC-free unless there is a very specific use case, like that of WekaIO or the blog post author. The allocation patterns in D are different than they are in Java or C#, it's clearly defined when a collection may trigger, the @nogc attribute provides compiler enforcement for avoiding GC allocations in specific functions, a command-line switch can warn you about the same if you find @nogc too much to think about (because employing @nogc does require more consideration of your architecture), and other switches can help minimize the impact of GC.

So the tools are there for anyone who needs them. There are definitely rough edges and we are forever in need of improvement, but everything is usable and people are using D in production right now.


> That said, there is a plan to enable @nogc exceptions.

It's been implemented.



I'm surprised you mentioned memory allocation without spotting the memory allocators in the standard library. Andrei designed the library and as far as I can tell no other language comes close when it comes to composable allocators.


I dunno why you assume that I don't know about them...

Apart from that, they came pretty late, are still in experimental, and don't change the fact that only a subset of D is usable without GC.

I very much like D, I really do, but I never encountered a usecase where the pros of using D outweight the cons. It sits in a very very weird spot design-wise, and while Walter and Andrei tried their best to get rid of the most common problems, not much of that effort resulted in actual useful change: Still no other GC than the default linear one, the stdlib is still not fully noGC usable (and probably never will), and "proper" compile time functions are still not done, after quite a few years now...

Which is a shame, D is very close to being the perfect C++ replacement.


If you don't want to use the GC, why the concern about its implementation?

I have no idea what you mean by "proper" compile time functions. D's CTFE is excellent.


Ultimately, for any language to become popular, it must bring something radically new on the table (e.g. Java: relative performance, simplicity and safety; Python: immediacy; etc.), and/or have a big company behind. D doesn't have any of the two (unfortunately! I do appreciate the language).

This viewpoint is typically represented by the question "what can I do in X that I can't in C++?".

Something I personally find interesting is the thought experiment: if Golang was written by a small actor, and D by a big one, which one would have succeeded?


I don't know that it's essential that a big company be behind a language. What's essential is that the tooling and the libraries be top-notch. That's beyond the reach of an individual, or even a small team. But a large company can easily provide the resources to do that.

(The third essential is that a language do something significantly better or easier than existing languages. A language can't just be "does the same as C, but with a bit different syntax", unless it's radically better syntax. Switching languages has a cost; your new language has to pay back that investment or it won't get used.)


I can't remember where I heard this, but there's a principle that a competing product can't just be 10% better. To justify the cost of switching, it has to be 10X better.


Honestly, I believe it is much more about marketing than one might expect.


Agree. I think this is one of the reasons Ada has seen (and continues to see) so little use.


Coming from the Pascal side of programming, the syntax doesn't help to gain adoption in hacker community that grew out of UNIX culture.

In a way I think it is a kind of revenge that most newer languages adopt Pascal style variable and type declarations.


That's kind of an uncharitable way to say, "Rust has a welcoming and beginner-friendly community". It's not like there's a marketing team buying Facebook ads.


I think that's your vision of marketing. Marketing by word of mouth because you really like a product is still marketing, and the Rust community is really good at that.

The Rust community realized early that if they wanted to succeed, they had to talk about Rust a lot, show good examples, be beginner friendly to avoid people picking it up and dropping it quikly. But that "marketing" is also things like a really good package manager, really good compiler errors, a really good VSCode extensions. Many communities don't have this (especially the new ones) and this makes developing in Rust more of a joy than in let's say OCaml or even JS.


I don't know if I'd say beginner (an initio) friendly but we have some really clever people on our forums who have a lot of time for new people.

There will be a book on dlang.org soon, that's the one thing I think we're lacking at the moment.


Rust had Mozilla blog posting about it for a long time.

https://hacks.mozilla.org/2016/07/shipping-rust-in-firefox/

Let's not pretend marketing is just paid Facebook/Google ads.


Ha, only unexpected if you haven't been watching how every other language adoption goes. Otherwise I agree. :)


Not different enough to be worth switching from Java/C++ with their much bigger and more established communities. This was especially true earlier in it's history when it required GC. Now it doesn't, but it has to compete with Rust which can also offer memory safety.


Funkwerk, one of the first companies to adopt D back in 2008, switched their passenger information system from Java and C++ to D. They weren't just on the look out for something different. They had a real problem to solve, tried out a few languages, and settled on D. They're still using it today (they moved from D1 to D2). And if you're riding certain rail networks in Europe, you're benefiting from it.

https://dlang.org/blog/2017/07/28/project-highlight-funkwerk...


> Not different enough to be worth switching from Java/C++ with their much bigger and more established communities.

Companies using Java or C++ don't switch because a language is "sufficiently different". I've been involved in programming language discussions for decades and I've never heard of a company switching to a language because it was different from what they were already using, though being too different is a common reason for not switching.

{For those not aware, D has intentionally kept compatibility with C as a priority, to the point that you can set a compiler flag and restrict yourself to "betterC". You can translate C code to D without making many changes to it.}


"Different" is not a reason to switch, but "not different enough" is a reason not to switch.

When switching is costly, the potential upside must be big. When the other language seems similar, the upside also seems limited. When there are few differences, you can rationalize staying with the old language, because it may catch up with the features, or you can emulate the missing features, or just live without them, if the differences are small.


This is getting into a fuzzy area where one person's big difference is another person's small difference. I'd consider D templates to be a small difference from C++ templates in terms of the language[1] but big enough in terms of productivity that it would make sense to start a new project in D over C++ for that reason alone.

[1] A random commenter on HN might well conclude that there's no benefit to D's templates without using them.


The D compiler speaks C11 now, it'll be ready for prime time in two or three releases based on speaking to Iain and Walter.


Just added C11 anonymous structs last night!


I saw, as long as the code stays clean I think we're going to be kicking ourselves this only happened now.


So far, it's shaping up nicely. I am indeed kicking myself for not doing it a while ago, but I'm a better programmer now than then, and it's going to be a better job.


But Go came and succeeded. Would you attritube this to Google's marketing, products like Docker/Kubernetes, or the simplicity of the language? Maybe something else?


Google's marketing, products like Docker/Kubernetes, and worshiping of UNIX key figures.


Symmetry Investments, a $4.5bn assets-under-management hedge fund, sponsors Dlang.

No major tech company behind Dlang.


Symmetry are a bit bigger than that now. They use D extensively and it's been very good for them.

Edit: Why am I being downvoted for repeating publicly available information?


A company that probably understands risk-reward.


A lot of people have mentioned a lot of reasons, marketing, corporate support, etc...

I think a language technology needs at least one, but ideally a few, flag ship projects using it. It provides some examples for people to see, it shows the "why" and then it also connotes that it's living and good. I don't think it has to be big, just good. Ripgrep is a prime example, there are a few other smaller tools in Rust that are nice, well put together tools that do a nicer or better job than the old standards.

You can talk about why something is nice or better, but actually showing people that it is probably convinces more.


I feel like a large reason for that is that D is a properly boring language and I mean that in the best way possible. I have yet to be unpleasantly surprised by D in the way other languages seem to be specifically designed towards.

While this makes D a deeply pleasant language to use, it also makes it tough to sell. It doesn't have any whizz bang features you can get across in an elevator pitch.


Plenty of great answers above already. What I also think is a valid argument is that in order to appreciate the language, one has to be a seasoned developer hence many heated discussions on HN or Reddit. It reminds me of Lua, where at least one person would mention something about 1-index arrays and nil element behaviour.


I think there are just two big factors - garbage collection and tools. When it was made garbage collection seemed reasonable, but with modern C++ and rust we now know that tracking ownership through different scopes solves the same problems very well with none of the downsides of garbage collection. If you look at D, Julia, C#, Java, Ocaml, etc. etc. over and over you see people eventually fighting with the garbage collection over throughput and latency.

D to my knowledge has never fully transitioned to garbage collection being a thing of the past.

For tools I think D fell into a common trap, which is to just keep working on the language itself. Eventually the lack of debugger, real time syntax checking and auto completion take their toll and something like C++ seems better even with the rough edges of the language itself.


It's trying to please C++ fanboys too much, who then get outraged about some other D feature and go back to C++ again.


D chose GC.


Challenging to overcome languages like C++, Rust, Java, and C#. D seems to sit somewhere in between, a better C++, but with (optional) GC. The thing is, Java and C# are already making strides into that space.


D was released 9 years before Rust, making it unlikely that rust had much influence on D adoption.


This is Hacker News.


I am curious to see where Java are C# are making progress towards optional GC.

This specific article talks about using No GC aka "betterC".

D has GC by default; the use of GC is convenient and mainstream as most popular languages show - Java/C#/Python etc. What D gives is the unique ability to do No GC programming for the cases where GC is not desirable. Very few languages offer this capability.

Zig is interesting in this arena, but it approaches the problem from the other angle. It is manual memory management by default, but you can explicitly choose which memory management technique you want to use - at compile time.


C# has added a lot of control over memory layout. Span [0], structs etc. I am hoping they add more D like features (@nogc) to the language. Java itself has just made strides on reducing GC pause times [1].

Granted, this isn't optional GC, but does D really give you that? Don't you lose the entire ecosystem and stdlib with -asBetterC? Why would I choose that over rust/zig/c++?

FWIW, I am a big fan of D.

[0] https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/...

[1] https://malloc.se/blog/zgc-jdk16


> Granted, this isn't optional GC, but does D really give you that? Don't you lose the entire ecosystem and stdlib with -asBetterC?

-betterC is not the only way to avoid the GC in D, just the most extreme. The original motivation for -betterC was to ease porting C code to D. Walter has used it for that to port a good bit of his old C code over. But it's also suited for the space in which the blog author is using it, and some people just prefer it. You always have access to the existing C ecosystem, but there are people writing -betterC libraries in the D ecosystem. And as more people use it, I expect that space will grow.


If one sets the requirement of having manual memory management in a mixed language, then:

1. either they don't use any library, including the standard one,

2. or the (standard) libraries must be written in both manual and managed memory management versions.

Additionally, the language must include extra syntax for memory allocation and access. This doesn't event include safety-related semantics, like Rust, which would be very hard to bolt-in (language-wise).

I hardly see any advantage in Java/C# having this functionality; Oracle is actually putting lots of effort into improving their garbage collectors. Java does actually have manual memory management (through Unsafe), although it's rudimentary; for the reason mentioned, I doubt it will ever be improved/expanded.


Back when D originally debuted, I couldn't separate it in my mind from C# and Java, despite the fact that you could manage your own memory. It felt like it fit into the same space, yet didn't have a compelling ecosystem. (Competing standard libraries did not help their case!)

That's at least why I glossed over it.


Java and C# also offered similar capabilities when D appeared.

Granted on Java side it required sun.misc.Unsafe, JNI or Real-Time JSR, while on C# side, a mix of structs, SafeHandle, MarshalInterop, unsafe and eventually C++/CLI.

So while not as pleasant as D, the cost to drop those eco-systems wasn't worth the cost to switch, and now 10 years later those eco-systems have doubled down on improving the experience for low level coding.

This makes it quite hard to sell D to those potential users.


> Uniform Function Call Syntax (UFCS)

> This has made my code significantly clearer. My code can accurately follow the flow of data without polluting my stack with single-use variables, nesting many function calls, or other sorts of clutter.

This is also pretty common practice in Haskell. Though Haskeller's typically have a higher tolerance for reading their code backwards. (But you don't need to. It's easy to define operators that arrange your code in the other direction.)


I use D every day for own business and it's a pleasure. Nice work!


Thank you! Your post about D without its runtime is a fantastic read.


What for exactly you use it?


Products in https://www.auburnsounds.com/ also PDF generation, SIMD, static websites (CommonMark), and a lot of internal tools. There is a wide gamut of applicability. (EDIT: I have become that blurb programmer :o )


Audio plugins like VST.

He created dplug, a framework for audio plugins in D a pretty great feat!


UFCS example uses units, which looks neat, but assigns injectorWidth to a variable injectorTime, which seems wrong?


The units are a mix of D's UFCS and metaprogramming. I find it helps keep track of which units are used where in the code base, and stops me from accidently running operations on wrong unit types and such.

Injector width / time pretty much means the same thing (at least in my code base). My apologies for the confusion.


I believe width is referring to pulse width, which should be a time unit.


Bingo!


I use D every day at work (inherited codebase) and the UFCS bothers me to no end. I try not to use it.


That's understandable. Not for everyone.

Different situation, but I do admit when I first got into D I was wary of the UFCS feature and I avoided it, too.

Over time it felt a bit more natural and I began to appreciate it.


There are "bad" uses of UFCS, and good ones (sometimes depending on preference). For example, I hate code like `1.writeln`.

The major feature that it provides is pipelining (as shown in the article)


Adding a method to a class you don't control is also useful.


> I hate code like `1.writeln`

Meh... after not more than my first month into D this syntax grew on me and now I just use `1.writeln` everywhere. More than a few years later, I can't think of a single issue this has ever caused me.


Can you expound upon why you feel that way?


UFCS as a concept is fantastic but the one hangup is that D's language server implementation by the community and its IDE integration can't handle it because of the complexity.

https://github.com/Pure-D/serve-d

https://github.com/Pure-D/code-d

(I can't remember if the Visual Studio extension, VisualD handles UFCS or not)

http://rainers.github.io/visuald/visuald/StartPage.html

It's possible to implement, because Nim's language server handles UFCS, but atm D's doesn't do it (it's written pretty much by one people)

So personally I avoid UFCS except for very simple/common function like "to!" because it breaks the intellisense for that call.

Though if I knew the language inside and out probably I wouldn't care.

It's still my "favorite" language.

-----

SIDE NOTE: This single person wrote the D lang server, and has maintained it, written and maintained the VS Code extension, and other fundamental tooling + libs for years.

https://github.com/sponsors/WebFreak001

If you use D and feel like sponsoring someone, consider sponsoring them, or Rainers (VisualD), or the maintainers or LDC or GDC, also single individuals for the most part.

LDC Maintainer: https://github.com/sponsors/kinke

GDC Maintainer: https://github.com/sponsors/ibuclaw


The language server doesn't do it because it's only a parser whereas making UFCS work properly would presumably require a full semantic analyser. By no means impossible to do, just no one has taken the plunge yet.


Can you explain why? I have never used D, but I think UFCS is really convenient.


I don't know for GP, but UFCS functions just litter the auto-completion tab for me. It's also not always readable.


do you have open vacancies? :-)


Symmetry Investments has vacancies with D: https://news.ycombinator.com/item?id=27034032


Just - impressive.

And since this is about dlang a bit... My favorite part of D compared to cpp, was metaprogramming syntax. (i.e. NOT '<' and '>') I was so sad when I got to know that the only thing that rust took from cpp, was '<' and '>'.


It's really beyond me why would Rust designers adopted the '<' and '>' symbols. If I'm not mistaken Walter had specifically mentioned that he's avoided these symbols based on his experience on implementing C++ compiler in the early days of C++. Due to the ambiguity of the symbols with other operations' symbol, their inclusion will require extra symbol look up table and this will significantly increased parsing and hence overall compilation time. Based on the complaints on Rust compilation time that you see in HN, probably he's right after all.

One of the design principles of D is to create compiler friendly programming language and this is evident with the higher speed compilation of the D programs in comparison to similar program in C++ and Rust. Comparatively speaking, Go also has a very fast compilation time but Go currently does not support generic yet, and there's that.

In addition, another design principle of D is to be as intuitive as possible and programmer friendly compiled programming language. If you think this should be easy please check this video regarding of this Professor to try to completely compile R to no avail in 10 years during a keynote speech in a recent major R conference [1]. For examples, this is the reason that you have UFCS in D and there's also no macro in D. You can see that some of later programming languages agreeing with D approaches and copying this UFCS feature. On the overall language idioms, D want to be easily program similar to Python but compiled, i.e. fast in compilation and running time. FYI, there is even a book specifically written for Python programmers if they want try and perhaps migrate to D [2].

[1] How I Learned to Love Failing at Compiling R

https://www.youtube.com/watch?v=VdD0nHbcyk4

[2]D, the Best Programming Language, for Former Python Developers : Learn D Programming for Python Developers

https://www.amazon.com/Programming-Language-Former-Python-De...


Thank you!

I agree, the syntax is much clearer than C++. The very first prototype was in C++, but I found myself frequently frustrated with the language. I find D's features make me more productive.


> From the factory, it came with a rubbish four-speed automatic gearbox. During 18 months of ownership, I destroyed four gearboxes.

[I'm from Europe.] I absolutely don't get this. Just... what? Four gearboxes? I don't know anyone who destroyed a single one - even after an entire lifetime of daily driving, but I don't mean Mercedeses - more like Škodas. What's up with American cars? Is this common?

Edit: my bad, the car is Australian.


They're really not good gearboxes.

Keep in mind, with the 4 speeds I drove casually. With this 6 speed, I can push it hard and it's still going strong almost a year later.

They're quite an old (American) design bolted to a modern engine. It simply doesn't mix well. 4 speeds (4L60e) are the bread and butter of automatic transmission rebuilders in Australia.

My father killed one in his daily driver, and all it did was go 20km each way to and from work. My Aunt's Commodore was recently in the shop getting a new 4L60e. They're simply not suited to the car.


What do you mean with "push it hard"? Maybe try a manual next time. Half of the fun of driving for me is switching gears.


Flogging it, pretty much.

I have a manual license, but I'm not interested in them. Thanks for the suggestion anyway.


> great for racing

that could explain a bit


Holdens are Australian, not American.


They're owned by GM now. Modern ones will be GM parts-bin cars. Going through that many GM transmissions is possible. This is why GM cars have horrible resale value and anything over 150k miles is on borrowed time.


Holden has been owned by GM since the 1930s and has been building its own vehicles since 1948. Holden ceased building cars in 2017 and was disbanded in 2020 (RIP).

But yeah, the 4L60es are lemons in my eyes.


These use GM's 4L60E 4-speed automatic. I don't remember the 4L60E being that much of a lemon that you blow through four of them with normal use.


I like D and could pick it up easily. It feels a lot like C without memory management overhead, Ada-inspired safety and lots of productivity feats. However, where D really shines is the amount of time between learning the language and starting doing something useful in it.


Definitely. If you come from a C-family background it feels quite familiar.


are there any schematics available?


As of current, no. I'm not sure where I want to go with this project.


I hate to be that guy, but is this legal?


Good question!

It is. I contacted a VicRoads approved engineer in regards to this project, and I received the all clear. I've been pulled over by cops, and they were cool with it.

My insurance is ok with it, too.

It does have a software watchdog, and failing that, the gearbox's hydraulics have a safety mechanism that allows for some limited driving.


Almost certainly. Basically all "under the hood" mods like this are— street legality for a vehicle you build or modify yourself is a surprisingly narrow band of requirements that are mostly around safety equipment like lights, horn, etc:

https://en.wikipedia.org/wiki/Street-legal_vehicle

The much higher bars to clear are when it comes to a device that you offer for sale to others for them to operate on the road.


Is there any true reason to use D over C++? At least with Rust you get some guarantees that you don't get with C++.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: