This is a list of issues I encounter when working with the D programming language, and which I find annoying or which limit what I can do with D.
The selection of these issues is completely subjective, I keep it here for personal reference and possibly for others who might want to fix one of these problems or just want to know about the problems I see with D.
Despite all of the issues, I think D is a useful language, otherwise I wouldn't use it and put effort in fixing (or working around) flaws, or even creating this list.
If you spot an error in the list or want to correct something, please ping me about it!
I also categorized the problems into:
- Problems which prevent proper inclusion of D into Linux distributions (Debian specifically) - (marked with 📦)
- Problems which prevent me from achieving some goal in D, or making doing certain things a lot harder (marked with 🔴)
- Problems which are very annoying, but don't actually prevent achieving a goal (e.g. style issues) (marked with 🌀)
If you are just interested in the "how to integrate D into distributions" issue and want a priorized list with those issues, you might want to take a look at the more condensed dlang-packaging-issues.md list.
-
Function decorator bloat: I recently tagged a function
@property @nogc pure @safe override
which seems a bit much. (This is just a minor annoyance though, usually this is within limits, especially since you can set some of those as global per-unit - having@safe
as default would still be awesome though!) [ 🌀 ] -
The
assert
statement is "dumb" in a way that it doesn't show me what data it actually compared, making using pure-assert in unittests a very cumbersome task. Pretty much every slightly bigger project I have see wrapsassert
in some other function to display useful information about the specific check. I would consider a useful-by-defaultassert
statement to be very valuable, especially because it could show much more and nicer information and we could all drop our workarounds. [ 🌀 ]
- D has no stable ABI. This kind of enforces recompiling all D shared libraries and binaries in a Linux distribution with every new compiler version. It also means that you can not use the libraries which were compiled with LDC in an application that is compiled with GDC and vice versa. This is a real PITA for distros and users who might have binaries compiled with the "wrong" compiler. [ 📦 ]
-
DMD has a non-free backend (open source, but no free software) and is the reference-compiler of D. DMD being non-free means that I will never ever be able to use it, since I want my software to be available in Linux distributions, and I also don't like extra legal obstacles which make using the compiler harder. DMD being non-free also makes it incredibly hard to sell D in the FLOSS community. Because of that, I can not actually test my code with dmd and use a free compiler instead, which means that I don't benefit from improvements done in druntime, Phobos and other parts of D as quickly as others. (IMHO a free compiler (LDC?) should be the reference compiler) [ 📦,🌀 ]
-
No Make/Ninja compatible depfile generation - this is especially important when not using dub (see the dub issues) and some other build system (Automake/CMake/Meson/..) is used instead. See https://issues.dlang.org/show_bug.cgi?id=16746 [ 🌀 ]
-
LDC doesn't support a lot of architectures / architecture support breaks from time to time. This makes it slightly harder to package the compiler in Debian. (see ldc-developers/ldc#1636 for a bug report, build logs are here: https://buildd.debian.org/status/package.php?p=ldc) [ 📦 ]
-
LDC doesn't support gcc command-line options. This would be very helpful to make LDC integrate better with Debian (e.g. it could pick up new default hardening flags quickly). It would also make me open the LDC manpage less to see how a certain flag was named.... ;-) [ 🌀 ]
-
No working Make/Ninja compatible depfile generation - this is especially important when not using dub (see the dub issues) and some other build system (Automake/CMake/Meson/..) is used instead. See ldc-developers/ldc#1802 [ 🌀 ]
-
GDC only supports an ancient version of the D standard library, which has many nice classes and also bugfixes missing. Because of that, it is almost impossible to compile modern D applications with GDC, and when developing an own application, I always need to add support for GDC explicitly, which means I sometimes can't use certain features. Thisn is an issue LDC doesn't have, and which is fragmenting the D ecosystem. [ 🔴,📦 ]
-
GDC is not part of official GCC. This makes it difficult to ship it with some Linux distributions, e.g. Fedora. On Debian, we inject GDC into the GCC build, which is also a bit weird. Having GDC in GCC proper would also give D more visibility (being in GCC still means something). [ 📦 ]
-
GDC does not support creating shared libraries at time, which is a big deal for distros which need it to reduce duplicate code and make security fixes easier. [ 📦 ]
-
There is no
dub install
command (dlang/dub#839) [ 📦,🌀 ] -
dub test
overrides binary created bydub build
(dlang/dub#840) [ 📦,🌀 ] -
Dub doesn't use packages installed to system locations (dlang/dub#838) [ 🔴,📦,🌀 ]
-
Can not version dependencies on other libraries (dlang/dub#906) [ 🔴,🌀 ]
-
Dub always recompiles the whole project, insread of just the parts that changed, like a normal Makefile does. When using dmd this is not an issue, since dmd is very fast, but with LDC and GDC it is and makes for a slower development process. [ 🌀 ]
-
Doesn't allow us to custom build parameters externally via an env var or the dub command-line (there is no "plain" build-type) [ 📦 ] -
Dub is unfit for complex projects: If I want to build a shared library and multiple binaries depending on it, edit files as part of the build process, un arbitrary commands to create a certain target and install the result into a directory, dub is not up to the task at all. I don't know if we need a dub-compatible more complex build system (Reggae? Meson?) or if dub can be enhanced to work for these cases. [ 🔴,🌀 ]
-
std.json: Why is there no
boolean
data type? Needing to check whether the type is TYPE_TRUE makes uglier code and is also very inconsistent given that an uinteger, integer and string type exists. [ 🌀 ] -
std.net.curl: The download() function doesn't throw errors, while the get() function does, which makes the former really useless (you never know if the download actually succeeded, or whether you downloaded a 404 page or nothing at all). Also, it is impossible to set timeouts via AutoProtocol, you basically need to work with HTTP/FTP primitives to get functionality which is even only slightly more advanced. [ 🌀 ]
-
std.xml: Deprecated, but there is no replacement available yet - so what should I use to be future-proof? [ 🌀 ]
-
There is no standard I/O streams interface anymore. std.stream says it's deprecated, without offering me any alternative that should be used instead (I heard some rumour about std.io being in progress, but that doesn't seem to be ready yet) [ 🌀 ]
-
There is no "Set" type in the standard lib. Faking one using an associative array is a bit ugly. [ 🌀 ]
-
The Phobos online docs and the reality are sometimes worlds apart, especially in the case of GDC, which makes using the docs a lot harder and less reliable. The online docs are only true for the latest DMD release, but you might actually be using an older LDC or GDC. This is very annoying when learning D. [ 🌀 ]
-
Named unittests blocks would be awesome, to see which test is running right now. [ 🌀 ]
-
https://wiki.dlang.org/Unittest points out cases where the
unittests
block isn't the best fit, but it offers no alternative on how unittests should be done in the D world in that case (ideally with dub integration). Having a basic test framework in Phobos would be very useful. [ 🌀 ]
"Set" can be replicated via
RedBlackTree
withallowDuplicates = false