Howdy,
I've been using Go recently, for the following reasons:
-
I want to quickly deploy and run a program across an excessively diverse
range of Linux systems and also Windows, without needing a build farm. -
I'd like the program to be a completely static binary.
-
I'd like the program to make HTTPS connections and maybe query a local sqlite database.
-
I'd like it to not be Rust (because: my previous choice was Rust; this is a program that cares a lot about potentially malicious filenames; Rust's string type zoo was exhausting to deal with and I caught myself wasting tons of time on Rust micro-problems that didn't benefit the program).
That's it. The previous-previous choice was D, because I was aware that cross-compiling to Windows was possible, and because I'd already worked out how to use Docker and Alpine's ldc to build static binaries.
So, what happened with D?
Take static binaries: they're the default in Go, they're what the community expects, so not only does most everything work normally in a static build, but when dynamic linking seems to be required you can find that someone's already put the effort in to avoid it: for example, there's a Go port of sqlite: https://pkg.go.dev/modernc.org/sqlite
And in D?
RUN apk add ldc dub alpine-sdk openssl-dev zlib-dev llvm-libunwind-static curl-static
buildType "static" {
dflags "--static" "-L--eh-frame-hdr"
}
That's part of the Dockerfile and part of the dub.sdl that already represent several problems overcome--I didn't know about that 'eh' frame flag until I was searching the forum for build errors. This gives me a static binary with
??:? <ERROR: Unable to retrieve function name> [0xffbeef]
spam on an uncaught exception, and I still couldn't get std.net.curl to not complain about being unable to dynamically load libraries despite it clearly having code for a static build.
There are a couple of different lessons to be taken from this, but the one I suggest is that D could use something like an application support tier list. D's a general-purpose programming language so you can technically do anything at all in it, so call "you can technically do that" tier 4 and start elaborating on higher tiers where a kind of program in a kind of environment is kind of reasonably done with some specific libraries.
e.g., want to make https requests?
- std.net.curl is in Phobos and only needs system libcurl, libssl, etc.
- vibe.vibe.requestHTTP can work with system libssl or the D port of Botan
- arsd-official:http can work with system libssl, with a caveat about 32-bit windows
The value I would've gotten out of some clear information like this is that I would've started with vibe+botan and maybe not have had any problems at all. As it was, when I realized I hit a wall, I'd already wasted tons of time and didn't want to risk wasting any more time even seeing if vibe would work. The value of such information for users of D is that it alleviates that fear, so that other languages are no longer the safe option.
The value of such information for D devs or D advocates is
- it encourages use of D where D is already a pretty good option
- it encourages users to be more prepared to help advance the language if they're consciously doing something that D has little support for
- (repeating #2) it saves users from trying to do something that D has little support for, getting burned by the lack of support, and going away
- it highlights support gaps as room for improvement that isn't DIPs or fixing bugs
With all that said, I don't think I've seen any language produce such a thing. My actual inspiration was Zig's release tierlist which is only about the compiler and standard library's suitability for different architectures.
Another lesson is obviously "you should have multiple languages in your toolbox and Go is just super good at this one thing and you can use D or other languages for other things", but this perspective doesn't leave much room for D in the end.