Really wanted to like Dlang but I just did not have a good time with it.
One of my projects has a really simple server written in nodejs that's basically (in terms of complexity) just an auth'd chatroom, and I wanted to switch it from using raw tcp sockets to websockets. And since the server is so simple, why not refactor it to another language and see if there's no some performance gains from that? I ended up doing something pretty similar to that "Comparing 10 programming languages. I built the same app in all of them." video from Tom Delalande (https://www.youtube.com/watch?v=-MbTj8DGOP0). I had several working versions of the server in:
- Bun, using Bun APIs (https://bun.sh/docs/api/websockets)
- Dart, using Dart APIs (https://api.dart.dev/stable/latest/dart-io/WebSocket-class.h...)
- Java, using Java-WebSocket (https://github.com/TooTallNate/Java-WebSocket)
- Kotlin, using Ktor (https://start.ktor.io/p/ktor-websockets)
- Rust, using tokio-tungstenite (https://docs.rs/tokio-tungstenite/latest/tokio_tungstenite/i...)
- Zig, using websocket.zig (https://zigistry.dev/packages/karlseguin/websocket.zig/)
- D, using serverino (https://code.dlang.org/packages/serverino)
And Dlang was, by far, the worst experience out of the lot. Firstly is the lack of adequate, comprehensive, and centralised tooling. I almost gave up when dmd could not even compile a freshly init'd project. The impression I got is that you're not really meant to use dmd directly, you're meant to use dub, like how you compile Java projects with Maven/Gradle, not javac. Except that there's also apparently three competing compilers (https://wiki.dlang.org/Compilers)? And good luck remembering the names of the tooling because they're all some random three-letter combination.
Serverino makes heavy use of mixins and attributes (think Java annotations), which is not ideal. But what really killed the deal was (despite using the recommended intellij plugin (https://wiki.dlang.org/IDEs) with the recommended tools installed and setup) not being able to inspect[1] serverino's mixin or its attributes. So I look at serverino's source code, except its source also has mixins... which I can't inspect. I'm not going to use something when I cannot easily ascertain its control flow. And while, yes, I probably should have gone with vibe-d (https://code.dlang.org/packages/vibe-d%3Ahttp) in the first place, mixins and attributes are nonetheless part of the language and the tooling should be able to tell me about them.
- [1] When I say "inspect" I mean requesting the IDE to show me the source/definition so I can see what it is, what it does, and where it's known to be used.
> And Dlang was, by far, the worst experience out of the lot. Firstly is the lack of adequate, comprehensive, and centralised tooling. I almost gave up when dmd could not even compile a freshly init'd project.
Yep this also happened to me when I tried D. I love the idea of the language and the syntax is great, but I really don't want to fight my tools when I'm working on a project.
Tangential, but which of the 7 ended up being the best experience?
It's a tossup between Dart and Bun: Dart has better language features but Bun has better APIs. Since Bun is first and foremost a Javascript runtime, it inherits its annoyances and issues, like the complete lack of pattern matching, or switch expressions at all, or decent enums, etc. That said, Bun includes SQLite support and encryption out of the box, whereas Dart is heavily compartmentalised (https://pub.dev/publishers/dart.dev/packages). Imagine if, in Bun, importing "node:crypto" meant needing a "node:crypto" npm dependency. Dart ekes out the win though, I think.