Interesting points, but the up sides of dlang are over shadowed by the fact that rust won the hearts of many low level developers and has gotten traction. I know of a few companies that are having difficult finding skilled developers because of this.
BetterC got a lot of resistance at first, along the lines of who needs it. (BetterC is a subset of D that only relies on the C standard library.) But over time it has accumulated a lot of users, as being C without the troubles.
We've gone a step further with ImportC, and now C code can be imported directly into the D compiler, which makes it easy to interface D code to your existing C base.
You seem to have some familiarity with the language. Nonetheless, you're understating a bit the degree of integration with C. You can also: create a shared library in D and call it trivially from C or any language with a FFI, call C shared libraries with little effort from D, compile a C file and add the .o file to your D program compilation command directly, use dstep to write C bindings for you, and directly #include a C header file with dpp. C is more or less a subset of D at this point. C programmers can stick with what they know but use D for incremental elimination of pain points.
Edit: I added that first sentence because it's awkward to tell the creator of the language that his answer was incomplete.
Actually, the truth is that Walter is a pretty poor D programmer who isn't that familiar with the language and knows next to nothing about the ecosystem outside dmd.
It wouldn't surprise me if he genuinely didn't know about how dstep and dpp are used.
> You can also: create a shared library in D and call it trivially from C
this is definitely a killer feature; i can think of very few languages that can do this. i think rust and zig are the only other two that have gotten any sort of popularity, though i would love to hear of any language i've missed.
Unfortunately no. A lot does compile, though, if you can avoid compiler extensions. I downloaded the sqlite amalgamation today (several hundred thousand LOC) and ImportC only had two problems, one which was easy to fix, and one I don't know how to fix (__builtin_va_arg).
Partial aside, BetterC sounds a lot like Zig and Andrew Kelley moved to Oregon a year or two ago. Have you talked with Andrew? Funny that two of the language creators in the space are so close to each other on Earth.
I'd love to listen to you two discuss D, BetterC and Zig and C.
I've never had a chance to look at it much, but I think the magic is in the metaprogramming capabilities. It's more principled than C++ templates, more ergonomic than Scala macros, and more practical than Template Haskell. Somehow. (At least this was my impression from discussing it)
The library looks impressive, but I dunno about that sales pitch: isn't "more principled than C++ templates"… a pretty low bar? And isn't "more practical than Template Haskell"… also a pretty low bar? I would have asked the same rhetorical question of Scala macros a couple years back, but the Scala 3 macro redesign is indeed pretty nice.
While the design D picked for templates looks (and is) straightforward, it wasn't obvious. It's only obvious in retrospect (which is something a good design aspires to, like putting an eraser on the other end of the pencil).
I agree. That one can e.g. lift every binary operator at once with just a few lines of code makes even python overloading feel heavy—but readers can still understand it easily.
My point isn't that "D doesn't meet that bar", but that the GP picked strange points of comparison: the steelman argument for C++ templates would focus on power (e.g. Eigen) instead of principles, and those for Template Haskell on safety instead of practicality. And of course, no macro comparison would be complete without gesturing vaguely in the direction of Lisp while muttering something about parentheses.
It's like the "Always Be Closing" speech in Glengarry Glen Ross: Dlang macros as John Travolta truly do kick ass in that scene—but why not have Al Pacino there to represent as top dog of the local branch?
D makes a compelling promise, but it's still ongoing metamorphosis. Changes too rapidly for libraries to take root. Every time I look at it there's a "new, better way" of doing everything so all the tools and libraries are out of date, at all times. And the whole thing doesn't sound so clean and elegant anymore.
All languages (even C to some extent) that are in wide use evolve towards new and better ways, and obsolete old ways. I don't even recognize C++ anymore, and I wrote a frakkin compiler for it.
Speaking of people who have written C++ compilers, what do you think of Circle? Have you given any thought to targeting GPU shaders from D? I think "C-like low level control but with strong compile time metaprogramming" might be something of a sweet spot, though there is a lot of complexity to the space (mostly the oddball storage spaces).
Is it RESF, or is it Rust's unique feature of memory safety (and data race safety) without GC? D is a nice language to be sure, but it's going to have trouble matching these features. Of course, this is not meant as a criticism of D - other languages like Jai are practically in the same boat. The C++ folks are at least aware of the challenge, as is clear from the C++ Core Guidelines effort.
D already has most of the memory safe features of Rust. Of course, the most valuable memory safety feature is array overflow protection, which D has had since its inception.
By most valuable, it tops the list of security vulnerabilities in compiled code, year after year.
Rust definitely has a lot of merits. I was definitely following it, and excited by its release.
But you cannot deny the RESF was obnoxious. And pervasive. But ultimately successful - the people who voiced their dislike would get down-voted to oblivion.
The anti-Rust stuff was/is pretty tiresome too. FWIW, I think disagreements about the choices Rust made make plenty of sense, or even the disagreements re: its style. But that wasn't what most of the anti-Rust stuff was/is -- it was/is just resentment regarding the hype of a thing, which is just the worst sort of criticism.
This is why I write in Ada--it's C++98 with cleaner syntax and a bunch of nice/new features (array bounds, pre/post conditions, etc). It's package-based, so types do not "contain functions", so free functions, member function, who cares, it's all written and callable the same ways. There's even a real module system built in for decades with packages. You have to get over `begin` and `end` though.
It's probably not removable after almost 40 years.
It has expression functions which you can wrap a return result in () and avoid it.
The important part is that it's surprisingly consistent in that 3 of the 4 structural elements are nearly all self-similar in their declare/begin/end format (protected type being the 4th and the difference).
Someone else made a really good point about hype today: 'One of the dumbest lessons I’ve learned in my career is that you should never disregard something that has hype behind it, even if you don’t think the tech makes sense. [0] Most “tech adoption” problems are really human coordination problems. Hype solves those. It doesn’t matter if you have a better solution, or that you think the proposed solution is stupid. [1]'
> you should never disregard something that has hype behind it
Do you have an opinion on how this sentiment applies to blockchain tech? I’m not trolling, I think the sentiment is interesting and blockchain tech seems obviously relevant to that sentiment.
If you released super popular whatever (game engine, embedded platform, 3d design software) that uses D as its customization language suddenly a lot more people would have a good reason to learn D.
The largest-scale usage of D that I have personally seen is a AAA game studio who had an in-house 3D-engine in C++, and chose to write plugins and game logic in D because of easy integration and hot-swappability. AFAIK worked out well for them.
I first learned C++ 20+ years ago. While I've appreciated it, I also knew its shortcomings and had been looking for a replacement.
D had some missteps along the way that lost some initial traction. I also wouldn't be surprised if timing was a factor with more C++ warts being added while the programming community has learned more lessons along the way that could be applied to the next languages (Go, Rust).
As I followed D, the problems I remember there being were:
- Compiler availability (DMD vs GCC)
- Split stdlib
- It was aiming for C/C++ post-Java but covered more Java use case (GC) than the remaining C/C++ ones (no-GC). It took a while before BetterC. No idea how well that ecosystem has matured.
- It felt like they were shoehorning every feature into the language rather than having a cohesive design strategy
These have slowly been resolving but Rust is now here, targets most of BetterC's use cases by default, and the borrow checker has let me squeeze out performance out of my code that would have been irresponsible without the compiler making it maintainable.
D was still fairly young when I was looking at the feature list [0]. The impression I walked away from it with is "Hey, this thing in boost is cool, let's bake it into the language".
Oh, yes, even as a complete outsider who merely reads D related threads from time to time, I remember these coming up repeatedly years ago. Both on HN and the programming side of reddit, among the top comments on D related threads. The tone was one of these being showstopper issues too.
To be clear, I have no experience with D myself - the point is just about the PR side of things and how things seemed to an outsider.
They come up now still, in part because people read old hackernews threads and don't actually read our docs or other information i.e. the standard library issue (Tango vs. Phobos) has been resolved for 10 years.
My point isn't that this is still a problem but that this was one of the blockers when I was originally looking at D and it was never clear from an outsider when it was resolved (I've assumed it was resolved at this point, more speaking 5-10 years ago).
Ironically as someone who wishes D distanced itself from C++ more, my feeling is that D is catering too much to the C++ programmers and not catering to the "Java programmers" enough. There is a lot of effort going into not only binding to C/C++ libraries, but also C/C++ interop, which appeals to a small group of users who potentially want to migrate a C++ project into D incrementally.
I wanted to like D because I respect Walter a lot, and D's community probably has by far the highest SNR of any community I've visited... seriously smart people.
But the language just wasn't for me. Right off the bat, the default import style which thrusts everything exported into the default namespace like C seems odd at this point. Apparently one can use what are called static imports, but as a code reader I can't enforce it.
It feels a lot like a language for C(++) folks, who IMO tend to be more conservative and entrenched.
Given the initial paragraph, maybe I'm just not smart enough to grok it :).
I'm sorry you don't like it, but that's a feature! But if there are identical names from two different imports, the compiler will demand that you qualify them.
With all respect for all the work you've done in C++ and D but imo that is a mistake. This is one of the reasons I have a distaste for languages like C# and Ruby and prefer languages like Python and Rust. I've had a hard time following what is happening in other people's Ruby code because of this behavior. Whether items are imported from a module should be left up to the developer and not done on their behalf.
The SNR point is well taken. It's probably why I find less popular languages to be more enjoyable. Practically anything Python or Javascript related is flooded with too much entry-level commentary and Medium articles (yick). Languages such as D, AWK, Prolog, etc etc attract those who have broken that threshold, generally many years ago.
D programmers have also been in high demand in the industry, because D programmers tend to not need social proof, and tend to be self-educated and self-starters.
Oh I dont deny that at all. D is on my list of languages to try precisely because it is more powerful / flexible than Go (and thank you for making it).
Just surprises me how quickly people write it off. Horses for courses!
I’ll be honest. It kept me away from Go for far too long. Now, I really appreciate Go, and hope the new generics implementation doesn’t ruin the culture. I do wish Go had sum types, and that it didn’t have null. Those are my main gripes.
if you want to use vibe.d as a fairly complete solution to most tasks. You will not have the fastest web service, but you will be really productive. I think with vibe.d you can easily beat node.js in comfort for writing web services, especially because most errors can be found and fixed at compile time already.
vibe.d is pretty similar to express.js
There are also other non-vibe web service libraries like arsd cgi (can't tell you much about that one) or hunt-framework (which is probably the highest performance library for the D ecosystem if you can believe the benchmarks, but doesn't have much documentation)
"...was originally released under a custom license, qualifying as source available but not conforming to the open source definition. In 2014..."
Which has been a different path other more popular languages took to increase popularity. The standard D2, which is now D, introduced breaking changes and stabilization only came around 2010.
Parallel to this, other programming languages became more popular and evolved, particularly C++. This certainly affected D's "novelty value".
I wonder how much these facts negatively influenced D adoption.
I originally underestimated the value of Open Source, which was definitely a mistake. Now I do everything in Open Source. The latest was releasing my disassembler, originally written in 1982, under a Boost License. (It may be old, but it disassembles the latest Intel instruction sets.)
It's now part of the dmd D compiler. Just throw the -vasm switch, and it'll display the generated code on the console.
I see many uses for a freely available disassembler. For example, you can add it to your favorite text editor! Admit it, you've always wanted to disassemble your text.
I'm impressed with -vasm, but fo the record this isn't strictly true. It supports most everything you'll see day to day but AVX2 (for example) is emphatically not the latest and greatest.
AVX512 adds quite a lot of stuff for example. Entirely new set of mask registers for example.
Even with the VEX prefix Intel did new instructions just recently (VNNI).
As long as it doesn't blow up I think it's fine to not support these, just want to make it clear that if you use (say) TSX via inserting raw bytes in an AsmStatement (which I have done) then the disassembler will not pick it up.
They're wrong: the D parts of the compiler were released under the GPL in 2002. What is now called gdc got started shortly thereafter, bolting it on to the gcc backend, creating a fully-GPL D compiler.
This is easy to verify by looking at the archived releases.
Test suites are my bread and butter! Happy to help contribute if you can point me in the right direction - it’s be a nice way to play with D a little more.
> For example you cannot have multiple inheritance of classes (only of interfaces) so you cannot fall into the diamond problem like in C++ or Java.
This is a weird thing to call out java for: you cannot inherit from multiple classes there. You can only get a diamond if you inherit two interfaces with default implementations of a method on a shared parent interface. Over a decade of writing java, I hit this zero times. In any case, Java treats it as a compile error and forces explicit resolution instead of silently doing something confusing.
I don't know D and just learning this syntax myself, and I'm genuinely interested in where you feel the smell is because I really like this syntax! For example:
I know Ruby, so here is what I'm used to:
half.map { |i| i + 1 }
I also know Elixir:
Enum.map(half, fn i -> i + 1 end)
...and JS, I guess because we have to:
half.map(i => i + 1) // It looks just like the Ruby one
...vs whatever the Python version is... I don't know Python very well, but I imagine it involves list comprehensions...
Compare all those to the aforementioned D version :
Sorry I should have been more clear. Incrementing every element in an array is much less useful than ".map()" which can execute a function on every element.
It just seems like a weirdly specific syntactic sugar... which is a "language smell"... to me
You can use arrays as if they were individual operands, and it will expand out the loop and apply the expression to all the values (and can use optimization/vector tricks if posssible).
e.g.:
arr1[] += arr2[] / 10.0 + 5;
TBH, I don't use this feature much, because I work with ranges more than arrays, which do not have this ability. This feature predates ranges (and the std.algorithm.map function, which can do what you say as well).
Well you can also just call .map if you want. The nice thing about the [] operation is the compiler can optimize it more heavily since it is restricted to simpler instructions.
All of those create a copy of the array and do not modify the original, which may be important on cases like audio manipulation, where there are for instance 44,000 array entries per second. Furthermore, I wonder if D could automatically vectorize this operation when SSE/MMX style instructions are available?
It's not D that auto-vectorize such expression, it's the backend. Those "array ops" makes it easier for the compiler to convey that to the backend, though. Using LDC + arrays ops is often the best thing you can do speed-wise.
Yes it is useful, because "array ops" auto-vectorize well and you can write complex function that are vectorized. It's a bit like expression templates but with compiler support.
Typically if something can be written as an array op expression it isn't worth rewriting with intrinsics or assembly.
For me it's a killer feature :)
You can also mix and match scalar and slices, so for audio code it's quite cool:
In this case the syntax lowers to a template which handles the iteration for you. It is not special, it gets treated the same by the compiler backend, but it will almost definitely be inlined & vectorized if the compiler is allowed to.
GCC and LLVM are actually clever enough to call memset for you if they deem it profitable.
i really want to use D for something, but it's just in that awkward spot where for any given project i can use ocaml instead. ocaml is in roughly the same part of the speed/expressiveness/pleasantness box as D is, plus i already know it.
i had two abortive attempts to use the language for specific projects - one was to wrap a C++ library and use it from D, but it turned out the swig bindings didn't work.
the second was to find an active gtkd-based app and contribute to it, to get a feel for desktop gui development (which seems on the surface like a very compelling use case for the language), but after asking on reddit no one could suggest anything other than tilix, on which development has stalled :( i would still love to do this, if anyone has something to suggest.
if anyone is involved in a fun desktop-based D project (CLI, TUI or GUI are all fine) please recommend it!
I started learning D in 2012 and will echo that Andrei's book is great, and imo one of the most entertaining and informational technical books I've read. The D forum was a great example of dogfooding and the people seemed nice when I would post things.
But, I think one of the things that people seemed very happy about feature-wise that started to turn me off the language was UFCS. I don't deny that it makes the written code look more elegant but I think to me it existed as a net negative for other people who are unfamiliar with the code they are reading. There was an example someone gave years ago on reddit that was supposed to convey how clean the code to solve the problem was but it included an UFCS expression of the form 'a.b!c.d' which was sans-UFCS 'd(b!c(a))'. Trying to determine which reordering the compile would going to eventually choose seemed like more work than should be necessary for simple expression like that.
Having said all that it still might be a good choice for certain development environments and I should see whether there's a second edition of TDPL.
UFCS is one of the most popular features. It's utility is in extending the functionality of a struct without adding member functions that would get private access, but don't need private access.
It helps keep structs small and simple, rather than becoming kitchen sinks.
I don't disagree that it can be useful (eg. from one of the other projects mentioned in the thread: https://github.com/Netflix/vectorflow/blob/master/src/vector...), and I definitely saw plenty of people that liked it. I think it existed in the same realm as a feature like lisp macros which are incredibly useful but when overused can turn the code into an inscrutable mess. The question for me was always how much the community would use or overuse them. When talking with other people it seemed like their own use of UFCS was obvious, but then again they wrote the code so of course they were going to understand it.
Without knowing any of the associated types and members how many interpretations could the prior expression 'a.b!c.d' have with UFCS and parens-less calling conventions (and any other feature that might contribute to different semantics)?
b!(c.d)(a)
b!(d(c))(a)
d(b!c(a))
d(a.b!c)
Might be more? Don't get me wrong I see the benefit. The vectorflow example I think is a good use case thought because it allows a more natural conceptualization of object -> member access -> conversion rather than having to call to!ulong(W.length) which forces the reader to start with the (pending) conversion. You get this same dataflow/conceptualization benefit in threading macros in clojure (->, ->>, etc).
The template parameter after a ! without parentheses is always 1 token, so it's never one of the first two interpretations.
Furthermore, the point is that often when writing generic code, you're not supposed to care what the `.d` means specifically. For example, an `InputRange` is defined to have `.front`, `.empty` and `.popFront` properties. Is `.empty` a member variable, function, or constant? Doesn't matter, as long as it results in a boolean.
This does require some getting used to. A common question from newcomers is how to explicitly spell out the type in a situation like this:
import std.algorithm;
void main()
{
auto x = [10, 20, 30].map!(x => x*2);
}
The answer is: you cannot! You know it's an `InputRange`, so you can access `.front`, `.empty`, `.popFront`, and pass it to range functions, but it's not a simple type like `int[]`.
While it's flexible, generic code is also complex. Many D standard library functions don't take a simple `string`, but a 'generic input range of a code unit'. (UTF-8, UTF-16, UTF-32). The resulting template machinery that this spawns is not pleasant to work with, so I understand your concern.
In my own D code, I often use regular arrays, foreach loops and if-statements instead of ranges, map and filter etc.
The trick is, most newcomers aren't just bothered by auto and would like the explicit type here. What they want to do is actually pass that output into another method. And in that method they need to know the type. I mean, you could accept input range in the method, but then you are losing some typing information.
133 comments
[ 5.0 ms ] story [ 180 ms ] threadThen wait until you see how Rust usage compares with C and C++ usage. Sorry, but I fail to see the point of your comment.
We've gone a step further with ImportC, and now C code can be imported directly into the D compiler, which makes it easy to interface D code to your existing C base.
Edit: I added that first sentence because it's awkward to tell the creator of the language that his answer was incomplete.
Just to note: Walter Bright, whom you replied to, is the creator of D.
Well he should, he's the guy who created D.
(https://en.m.wikipedia.org/wiki/Primer_(film))
It wouldn't surprise me if he genuinely didn't know about how dstep and dpp are used.
Remarkable understatement right there :-P
this is definitely a killer feature; i can think of very few languages that can do this. i think rust and zig are the only other two that have gotten any sort of popularity, though i would love to hear of any language i've missed.
But - it's not production ready yet, is it?
I'd love to listen to you two discuss D, BetterC and Zig and C.
I've never had a chance to look at it much, but I think the magic is in the metaprogramming capabilities. It's more principled than C++ templates, more ergonomic than Scala macros, and more practical than Template Haskell. Somehow. (At least this was my impression from discussing it)
My point isn't that "D doesn't meet that bar", but that the GP picked strange points of comparison: the steelman argument for C++ templates would focus on power (e.g. Eigen) instead of principles, and those for Template Haskell on safety instead of practicality. And of course, no macro comparison would be complete without gesturing vaguely in the direction of Lisp while muttering something about parentheses.
It's like the "Always Be Closing" speech in Glengarry Glen Ross: Dlang macros as John Travolta truly do kick ass in that scene—but why not have Al Pacino there to represent as top dog of the local branch?
it's pretty awesome
I have code that has worked unmodified for many years. The language doesn't change that often.
By most valuable, it tops the list of security vulnerabilities in compiled code, year after year.
D also has a prototype borrow checker.
But you cannot deny the RESF was obnoxious. And pervasive. But ultimately successful - the people who voiced their dislike would get down-voted to oblivion.
This is why I write in Ada--it's C++98 with cleaner syntax and a bunch of nice/new features (array bounds, pre/post conditions, etc). It's package-based, so types do not "contain functions", so free functions, member function, who cares, it's all written and callable the same ways. There's even a real module system built in for decades with packages. You have to get over `begin` and `end` though.
Ada would be smart to get rid of that.
It has expression functions which you can wrap a return result in () and avoid it.
The important part is that it's surprisingly consistent in that 3 of the 4 structural elements are nearly all self-similar in their declare/begin/end format (protected type being the 4th and the difference).
[0]: https://twitter.com/matthew_d_green/status/14809742688758743... [1]: https://twitter.com/matthew_d_green/status/14809747831814348...
I see we've got an n-gate.com reader here. :)
If you released super popular whatever (game engine, embedded platform, 3d design software) that uses D as its customization language suddenly a lot more people would have a good reason to learn D.
D had some missteps along the way that lost some initial traction. I also wouldn't be surprised if timing was a factor with more C++ warts being added while the programming community has learned more lessons along the way that could be applied to the next languages (Go, Rust).
As I followed D, the problems I remember there being were:
- Compiler availability (DMD vs GCC)
- Split stdlib
- It was aiming for C/C++ post-Java but covered more Java use case (GC) than the remaining C/C++ ones (no-GC). It took a while before BetterC. No idea how well that ecosystem has matured.
- It felt like they were shoehorning every feature into the language rather than having a cohesive design strategy
These have slowly been resolving but Rust is now here, targets most of BetterC's use cases by default, and the borrow checker has let me squeeze out performance out of my code that would have been irresponsible without the compiler making it maintainable.
That happens to all languages over time. The more interesting thing is how well do those features fit in with the language's style.
[0] https://web.archive.org/web/20110320130326/http://www.digita...
> - Split stdlib
Oh, yes, even as a complete outsider who merely reads D related threads from time to time, I remember these coming up repeatedly years ago. Both on HN and the programming side of reddit, among the top comments on D related threads. The tone was one of these being showstopper issues too.
To be clear, I have no experience with D myself - the point is just about the PR side of things and how things seemed to an outsider.
I wish that criticism would go away.
But the language just wasn't for me. Right off the bat, the default import style which thrusts everything exported into the default namespace like C seems odd at this point. Apparently one can use what are called static imports, but as a code reader I can't enforce it.
It feels a lot like a language for C(++) folks, who IMO tend to be more conservative and entrenched.
Given the initial paragraph, maybe I'm just not smart enough to grok it :).
Yes, two different D modules can declare the same name as public, and they will not conflict with each other.
It wasn't about name clashing, but readability. It's not clear at first glance what functions belong to which imports.
As an example: https://tour.dlang.org/
Three imports and what appear to be four unqualified functions from them.
Or just use static import.
Well, the developer wrote `import thing;` instead of either `static import thing;` or `import thing : specific, list;` so it was their decision.
The old phrase "nobody ever got fired for buying IBM" is another one (though nobody has said that since 1990).
I wonder how many people are missing out on Go for a feature they wouldnt miss 80-90% of the time?
Just surprises me how quickly people write it off. Horses for courses!
You can take D metaprogramming from my cold dead hands.
No argument on going from D to something else but to not know either and not even try Go is what surprises me.
D has me fooled and I can't imagine Go choosing to go further in D's direction over C#. I feel sorry for them.
vibe.d is pretty similar to express.js
There are also other non-vibe web service libraries like arsd cgi (can't tell you much about that one) or hunt-framework (which is probably the highest performance library for the D ecosystem if you can believe the benchmarks, but doesn't have much documentation)
Parallel to this, other programming languages became more popular and evolved, particularly C++. This certainly affected D's "novelty value".
I wonder how much these facts negatively influenced D adoption.
It's now part of the dmd D compiler. Just throw the -vasm switch, and it'll display the generated code on the console.
I see many uses for a freely available disassembler. For example, you can add it to your favorite text editor! Admit it, you've always wanted to disassemble your text.
https://github.com/dlang/dmd/blob/master/src/dmd/backend/dis...
Humble comment. It is very good to hear this. Will guard this for future examples.
I'm impressed with -vasm, but fo the record this isn't strictly true. It supports most everything you'll see day to day but AVX2 (for example) is emphatically not the latest and greatest.
AVX512 adds quite a lot of stuff for example. Entirely new set of mask registers for example.
Even with the VEX prefix Intel did new instructions just recently (VNNI).
As long as it doesn't blow up I think it's fine to not support these, just want to make it clear that if you use (say) TSX via inserting raw bytes in an AsmStatement (which I have done) then the disassembler will not pick it up.
This is easy to verify by looking at the archived releases.
On a more serious note it's cool to see the languages creator quite frequently on HN - it is the reason I took a look at it a while ago :)
I work on D too, feel free to email.
This is a weird thing to call out java for: you cannot inherit from multiple classes there. You can only get a diamond if you inherit two interfaces with default implementations of a method on a shared parent interface. Over a decade of writing java, I hit this zero times. In any case, Java treats it as a compile error and forces explicit resolution instead of silently doing something confusing.
Looking at the notes, it may have separate syntax to make compiler vectorization and parallelization easier. Plus it's pretty terse.
I know Ruby, so here is what I'm used to:
I also know Elixir: ...and JS, I guess because we have to: ...vs whatever the Python version is... I don't know Python very well, but I imagine it involves list comprehensions...Compare all those to the aforementioned D version :
I'm really feeling the D version!EDITED to fix little mistakes.
It just seems like a weirdly specific syntactic sugar... which is a "language smell"... to me
e.g.:
arr1[] += arr2[] / 10.0 + 5;
TBH, I don't use this feature much, because I work with ranges more than arrays, which do not have this ability. This feature predates ranges (and the std.algorithm.map function, which can do what you say as well).
You can also mix and match scalar and slices, so for audio code it's quite cool:
In this case the syntax lowers to a template which handles the iteration for you. It is not special, it gets treated the same by the compiler backend, but it will almost definitely be inlined & vectorized if the compiler is allowed to.
GCC and LLVM are actually clever enough to call memset for you if they deem it profitable.
i had two abortive attempts to use the language for specific projects - one was to wrap a C++ library and use it from D, but it turned out the swig bindings didn't work.
the second was to find an active gtkd-based app and contribute to it, to get a feel for desktop gui development (which seems on the surface like a very compelling use case for the language), but after asking on reddit no one could suggest anything other than tilix, on which development has stalled :( i would still love to do this, if anyone has something to suggest.
if anyone is involved in a fun desktop-based D project (CLI, TUI or GUI are all fine) please recommend it!
https://github.com/dlang-community/D-Scanner
https://github.com/dlang-community/dfmt
But, I think one of the things that people seemed very happy about feature-wise that started to turn me off the language was UFCS. I don't deny that it makes the written code look more elegant but I think to me it existed as a net negative for other people who are unfamiliar with the code they are reading. There was an example someone gave years ago on reddit that was supposed to convey how clean the code to solve the problem was but it included an UFCS expression of the form 'a.b!c.d' which was sans-UFCS 'd(b!c(a))'. Trying to determine which reordering the compile would going to eventually choose seemed like more work than should be necessary for simple expression like that.
Having said all that it still might be a good choice for certain development environments and I should see whether there's a second edition of TDPL.
It helps keep structs small and simple, rather than becoming kitchen sinks.
Without knowing any of the associated types and members how many interpretations could the prior expression 'a.b!c.d' have with UFCS and parens-less calling conventions (and any other feature that might contribute to different semantics)?
Might be more? Don't get me wrong I see the benefit. The vectorflow example I think is a good use case thought because it allows a more natural conceptualization of object -> member access -> conversion rather than having to call to!ulong(W.length) which forces the reader to start with the (pending) conversion. You get this same dataflow/conceptualization benefit in threading macros in clojure (->, ->>, etc).Anyway, thank you for all the work you've done.
The template parameter after a ! without parentheses is always 1 token, so it's never one of the first two interpretations.
Furthermore, the point is that often when writing generic code, you're not supposed to care what the `.d` means specifically. For example, an `InputRange` is defined to have `.front`, `.empty` and `.popFront` properties. Is `.empty` a member variable, function, or constant? Doesn't matter, as long as it results in a boolean.
This does require some getting used to. A common question from newcomers is how to explicitly spell out the type in a situation like this:
The answer is: you cannot! You know it's an `InputRange`, so you can access `.front`, `.empty`, `.popFront`, and pass it to range functions, but it's not a simple type like `int[]`.While it's flexible, generic code is also complex. Many D standard library functions don't take a simple `string`, but a 'generic input range of a code unit'. (UTF-8, UTF-16, UTF-32). The resulting template machinery that this spawns is not pleasant to work with, so I understand your concern.
In my own D code, I often use regular arrays, foreach loops and if-statements instead of ranges, map and filter etc.