3 ms·
EDIT: Short summary (half-subjective) = "More ergonomic + flexible higher-level-syntax C++ that performs just as well." -------- I'm a programming language en
by gavinray 5y ago
EDIT: Short summary (half-subjective) = "More ergonomic + flexible higher-level-syntax C++ that performs just as well."
--------
I'm a programming language enthusiast and enjoy learning + experimenting with them in my free time.
I've written code in most things, especially newer or niche languages. (Always interesting to try them out and get new perspectives)
Anyways, I've quickly grown attached to D, even in comparison to say Rust or Nim, and I could maybe speak to some of those points:
- C/C++ interop: One of only a handful of languages that can do direct C++ interop without a wrapper (others being Ada, Nim, and experimentally Swift).
But it has the most ERGONOMIC interop with C/C++ of any language because of how syntactically similar it is.
- Syntax: If someone were to tell me there was a language that felt like you were writing some kind of very high level Javascript/Typescript/Kotlin/C/C++ mixture, but you still had as much low-level power and access as C++, I would have assumed the language was a joke. That's kind of what D is like -- it's not a joke though!
- Language constructs: D really hit the nail on the head in my mind here.
It has scope guards ("scope(exit)", etc, for methods)
void main() {
writeln("<html>");
scope(exit) writeln("</html>");
// ...
}
Compile-time function execution, and a metaprogramming/reflection system that blows away most high-level languages I've worked with.
Here's a compile-time generic template that can be added to a struct/class to mix in function pointer definitions from another module or struct/class with reflection:
mixin template InjectFunctionPointers(T)
{
static foreach (fptr; __traits(allMembers, T))
{
static if (isFunctionPointer!(__traits(getMember, T, fptr)))
{
mixin(typeof(__traits(getMember, T, fptr)).stringof, " ", fptr, ";");
}
}
}
struct MyStruct {
// Compile-time embedded into the struct with reflection
InjectFunctionPointers!(module.with.function.pointers);
}
And I'm not sure what the exact term for this is, but it's the equivalent of Rust's "where: T" constraints for methods and C++'s concepts (sort of).
This shows generics/templates, variadic template arguments, and the concept I just mentioned:
auto cartesianProduct(R1, R2, RR...) (
R1 range1,
R2 range2,
RR otherRanges
)
if (!allSatisfy!(isForwardRange, R1, R2, RR) || anySatisfy!(isInfinite, R1, R2, RR));
And it has Design-by-Contract
long square_root(long x)
in {
assert(x >= 0);
} out (result) {
assert((result * result) <= x
&& (result+1) * (result+1) > x);
} do {
return cast(long)std.math.sqrt(cast(real)x);
}
D has "no-GC" modes and manually memory management if you want. You can just add "@nogc" above a function (or an entire module/program) and it'll disable the garbage collector.
There's also "-betterC" for a stripped down, non-memory managed, C-like version of D without the stdlib.
// Disable the garbage collector for the method
// Or, put @nogc: at the top of a module/program to disable it for the entire thing
@nogc
void main() {
// stuff
}
There's also a somewhat newer Rust-like ownership + borrow-checker system in D, with @live.
https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/ https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in...
https://news.ycombinator.com/item?id=20441519 https://news.ycombinator.com/item?id=20441519
Last but not least, the community is small but active and close-knit + welcoming.
-------------------
That being said:
- D has a much smaller ecosystem of tooling and libs than Rust/C++
- Similarly the development experience isn't quite on par. It's not bad though, quite usable, particularly on VS Code (the Visual Studio extension is also solid).
- danielEM 5y agoBeen playing with D for a day or two, it is cool, like it, but missing setters and getters - very much :-) But anyway, if there were jobs in D, I would take it blind :-) Love the idea of C being intermediate language.
- gavinray 5y agoD has getters + setters, but they are called "property functions" which is probably why you didn't find them on a cursory google search, ha =) https://dlang.org/spec/function.html#property-functions https://dlang.org/spec/function.html#property-functions
- danielEM 5y agoOk, been to short into D to understand doc nuances, but what it means: "WARNING: The definition and usefulness of property functions is being reviewed" Does it meant that it is just language update proposal? Or it's already tested in D implementations? anyway, saw it before, ha =)
- PoignardAzur 5y ago> There's also a somewhat newer Rust-like ownership + borrow-checker system in D, with @live. > > https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in... > > https://news.ycombinator.com/item?id=20441519 https://news.ycombinator.com/item?id=20441519 I'm really annoyed when people repeat the part about D having a Rust-like borrow checking system. This is absolutely something that the project has communicated about, but that communication shouldn't be repeated uncritically. If you actually look at what @live semantics are like... well, they're quite incomplete, under-specified, and they lack a roadmap for getting to a state where they could offer GC-less memory safety in D. I have yet to hear of any project successfully using the @live feature in a production environment, and I fully expect the same thing to be true 5 years from now. D's @live is a mirage.