Specification for the D Programming Language
dlang.org
dlang.org
http://code.dlang.org/packages/pyd
That and ranges (D/Andrei's preferred model for iteration) are excellent - in my view at least.
The original impetus for this was so I could incrementally convert the D compiler backend itself from "C with Classes" to D.
- tsv-utils repo: https://github.com/eBay/tsv-utils
- Performance studies: https://github.com/eBay/tsv-utils/blob/master/docs/Performan...
- Talk slides: https://github.com/eBay/tsv-utils/blob/master/docs/dconf2018...
Because you kee thinking in technological terms. Languages have come and gone, those who stayed are either old enough to have a midlife crisis or are supported by at least one big company. For all the merits D has there is no big name willing to push it forward, even though its creator is now working for Facebook and is doing some internal work: Facebook didn't express any interest in showing this off.
It really is a shame, because D has a lot of things that might interest programmers, all it takes is a little more presence.
https://forum.dlang.org/thread/xsqrdgwnzehdmfmvcznn@forum.dl...
While you can use D without the garbage collector, you will lose access to a lot of the standard library, which limits the practicality of running without garbage collection.
golang's GC isn't advanced either.
Although most of the benchmarks I've seen are at lease 2 years old. It would be nice to see some updated benchmarks that also compare against the Shenandoah and ZGC garbage collectors for the JVM.
That's how you get from zero to heavy usage in companies like Uber, Twitter, Cloudflare, BBC, Basecamp, Canonical etc... in less than a decade.
Not to mention technology change always generate friction. You just can't please everyone.
Hype driven development is a thing.
Unless technology X is irrelevantant.
But real-world applications performance needs fine tuned libraries that scales and this is where Java destroy both go and c#.
I ran several benchmarks locally on a CPU that's a few years old where the benchmarks site shows golang being faster than Java, without changing the code, and I got the opposite result (Java was faster). Especially the longer the program ran. For example, the site shows that golang is faster in the spectral norm benchmark. Running it locally with a larger input parameter:
golang:
time ./test 30000
1.274224153
18.81 real 70.19 user 0.38 sys
Java: time java spectralnorm1 30000
1.274224153
16.18 real 105.95 user 0.45 sys
Or with the nbody benchmark:golang:
time ./nbody 60000000
-0.169075164
-0.169012474
6.09 real 6.04 user 0.02 sys
Java: time java nbody 60000000
-0.169075164
-0.169012474
6.04 real 5.94 user 0.06 sysThings should get more interesting once Java gets green threads, which would make it easier to implement high performance concurrent servers without needing to drop down to event driven code unless for specific needs. That, and with value types, should push the performance bar forward.
- https://blog.plan99.net/modern-garbage-collection-911ef4f8bd...
- https://blog.plan99.net/modern-garbage-collection-part-2-1c8...
The main takeaway is that saying that Go is the leading GC is just a (somewhat dishonest) PR move, and Go's team made a pretty good GC given there project constraints, even of it is not at the state of the art at the moment.
You know when you end your article with "Overall, it looks to me like the Java guys are winning the low latency game." when none of those GC are actually production ready ... Go GC low latency has been stable and used for some time now.
Out of the box Go GC is very good and doesn't need all the memory or the tunning from G1. ( I spend years tunning GC for Java application it's a nightmare )
And isn't Shenandoah included by default in OpenJDK 12+?
Oracle chooses to build with only ZGC enabled.
I would not be surprised if the difference in amount of "garbage"—as measured in either bytes or object count/mark time—were a lot smaller than people think.
So does Go. Otherwise it wouldn't be anywhere as popular specially with regards to server-side usage by giants of the industry.
Java GC don't need allocation tricks of several GBs, like Twich was forced to do.
It is not heap size that matters, but how often old objects are mutated. Basically, if you have 1TB of immutable objects, you are lucky, but if you constantly modify all the heap, then you will have a lot of headache.
GC authors continuously mislead on this issue for many years (they promised the same with multi gigabyte heaps but with G1 several years ago).
> you will lose access to a lot of the standard library
This is incorrect. Not much of it needs the GC anymore.
P.S. click the link to see the spec...
Class destructors can be declared deterministic with the "scope" keyword: https://dlang.org/spec/attribute.html#scope
Scope guards are useful if you cannot change the data type itself.
Your remark, additionally being taught programming on languages that indeed use the GC heap allocations for everything, and on those that allow fine grained control over resources it is usually left for "exercise to the reader", so many don't care and so aren't aware of what they are losing.
An advanced GC requires having "write gates" inserted into the generated code. These take away from performance, but in a language like Java that makes very heavy use of the GC, the gain in GC performance outweighs the slower code.
D is not a GC heavy language, even if all you use is the GC, hence it is a poor tradeoff. (For example, in D you can use the stack for a great deal of the routine allocations, whereas in Java these are often done with the GC. Java has optimizations to try and detect when allocations can be done on the stack, but this isn't as effective as proactively putting them on the stack.)
This isn’t strictly true. In particular it is possible to design a GC such that write barriers are implemented in hardware (these days using the mmu not dedicated hardware). It’s also possible to write a (non-incremental non-concurrent non-parallel) gc that uses no write barriers: just stop the world, collect and move.
The mmu-for-write-barrier technique I’ve seen is to keep pointer colour in high bits and map the same physical memory onto n copies of itself in virtual memory (so you don’t need to mask the colour bits away before dereferencing). When the mutator tries to write to a black pointer (or maybe pointers are coloured by whether their targets might have moved?), the gc gets a memory exception and can ensure that the invariants are maintained. The general assumption is that this doesn’t happen very often in most programs. I can’t remember the name of the system I’m thinking of but it’s one of the new GCs being developed for java.
An alternative method to avoid a write barrier is avoiding mutation in your programming language. This makes GC simpler. There are other advantages and disadvantages
If you have real-time needs, then GC is probably out. That includes handling audio and video playback.
Tight memory constraints are another killer argument against GC but that only applies to small embedded devices. Smartphones, desktops, and servers have enough RAM.
The great thing about D is that you can start the easy way with a GC. When real-time or memory become constraints at some point you can selectively adapt parts of your program.
You could say, D wants to provide Python and Rust and everything in between so that you can shift seamlessly to wherever your specific sweet spot is. Different parts of your program can even use different spots. In a game engine, you could have the audio and rendering parts as non-GC real-time code, while the game logic is easy high-level script-like.
We are very used to a scripting language plus compiled language combo these days but is the separation a good one?
http://michaelrbernste.in/2013/06/03/real-time-garbage-colle...
The trick is not loading the GC too much, neither in terms of allocations/second nor bytes/second (for multimedia it means recycling buffers as opposed to creating/destroying), also having enough RAM so you don’t need to use 80% of installed memory.
Anti-GC hate seems to always come from religious objection or having had back luck not understanding how to actually use the tools at their disposal.
One thing that having been an Oberon user teached me, was that having a GC wasn't a show stopper for systems programming.
Ironically C++ has has GC support for more than 20 years now.
Managed C++ and C++/CLI on .NET, C++/CX on UWP, Unreal C++, and the GC API introduced in C++11.
So it seems to be one of those things that you only learn to enjoy after experiencing it personally.
You'd be surprised. At first our D audio products had GC enabled, and that created very little problems. When we got rid of the D GC for other reasons (macOS + druntime portability in shared library), we found that we only gain in memory usage. The GC was already "tamed" to happen outside real time threads. This is described in: https://www.auburnsounds.com/blog/2016-11-10_Running-D-witho...
The conclusion:
> Long story short, we brute-forced our way into having fully @nogc programs, with the runtime left uninitialized.
> As expected this fixed macOS Sierra compatibility. As a bonus Panagement and Graillon are now using 2x less memory, which is nice, but hardly life-changing.
> We found no magical speed enhancement. Speed-wise nothing changed. Not registering threads in callbacks did not bring any meaningful gain. GC pauses were already never happening so disabling the GC did not help.
> In conclusion, it is still our opinion that outside niche requirements, there isn't enough reasons to depart from the D runtime and its GC.
And indeed now we dearly miss the GC...
For sure you wouldn't allocate in tight loops. But the portion of a program that can accomodate a GC is very much larger than is commonly told on the internet.
As for video, it is way less sensitive to scheduler pauses than audio. Video systems are full of allocations (often of commited virtual memory) because throughput is often more important than latency there.
If i exclude the financial backing i think languages that tried to tackle one specific thing did rather well. Rust came to be to address the issue with security and there is not really an alternative. Yes people use it for cli tools or backend services but that’s just because they are riding the hype train.
The same with Go.
On the other hand we have things like Dart which did not really try to solve an issue people felt they have. The same with Crystal. Nobody really needed faster Ruby that much and if they did they already needed a production ready solution which was just too hard to deliver.
A language like Nim reminds me of D. Its author is also a brilliant Phd CS person but I feel like he does not really have a problem to solve. It’s all just an intellectual challenge. Companies like Status.im ( backer of Nim ) have a problem that they are trying to solve by using Nim. Making the right and the perfect solutions is hard but this evolutionary approach is really harming the expansion of the ecosystem. Nim has just too many features and too many approaches to memory management (recent gc:arc release). But it is all too half baked and does not support the features Nim advertises that it has.
This is basically the same issue i have with D. I have no idea what I would use D for. And could i rely on D in the domain i pick it for ? Eg the same field where Go excels.
I like Rust for CLI tools because it takes some nice ML features and it handles strings sensibly.
That will change in the coming months.
> I have no idea what I would use D for. And could i rely on D in the domain i pick it for ?
D is a general programming language. You can use it for scripts, number crunching, UI, and everything in between. It's been around a long time, and is part of the gcc collection.
However, most of my experience is with Python, Perl, Bash...etc. So I don't have a lot of Java, C#, C++ experience. With D, this sometimes bites me as all the doc seems to assume I'm familiar with that world. There is that one beginners book which is cool, but it only covers the absolute basics and I still get confused traversing stdlib.
Still, Thank you for all the work you've put in over the years!
There is excellent mir library but its documentation is subpar, no tutorials or any examples too. There is Netflix Vectorflow small deep learning library but only for CPU and only feed-forward networks, so it works for some specific narrow case. There is fastest on earth csv parsing library TSV-utilities from one of the ebay engineers but I have only learnt about it when I started looking through D website resources, also no tutorials. There are tools but using them needs more time investment than alternatives.
I have everything available in R at my disposal, because it's easy to embed an R interpreter inside a D program. Note that this does not always give poor performance, because the R code calls into compiled code or you can just call the compiled code directly using the R interface.
For numerical optimization, I call the R optimization routines directly (i.e., the C library functions).
For basic model estimation, I call the Gretl library.
For statistical functions (evaluating distributions and such) I can call into the R API or Gretl.
For random number generation, I can call into Gretl, R or GSL. I have parallel random number generation code that I ported from Java.
For machine learning (I do a limited amount like lasso) I call R functions. The overhead with that is so low that there's no point in not just calling the R functions directly.
So things are there. It's just a matter of finding the time to turn it into something others can use. Right now I'm focused on doing that with my linear algebra library.
How do you do numerical optimization in D? Do you somehow wrap Coin-OR's CBC C++ library or lp_solve? What does it mean to call the R functions directly? Do you have an example? I'm going to guess that won't be able to handle the massive and time critical models I use, but am still curious.
How do you do linear algebra? Are you binding to BLAS, LAPACK, Armadillo? Or did you write some routines from scratch?
[1] http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...
For optimization, I was referring to calling into the R API, which exposes the optimization routines in base R (Nelder-Mead, BFGS, Conjugate Gradient, and simple bounds constrainted BFGS). In terms of what it can handle, I guess that's entirely up to what R can handle. Here's the project page, but it looks like I haven't committed to that repo in three years: https://bitbucket.org/bachmeil/dmdoptim/src/master/
If you do try it and have problems with anything, please create an issue so I can fix it or add proper documentation.
I've also used this binding of the nlopt library: http://code.dlang.org/packages/libnlopt
For linear algebra, I built a wrapper on top of the Gretl library http://gretl.sourceforge.net/
There were two reasons for that. First, it offered a really simple LAPACK interface when I was starting out with D, and second, it offers a lot more than just linear algebra.
Is this something I'd recommend to others? I don't know. I built my infrastructure over a period of several years while waiting for my son at his many practices and activities. I also optimize for programmer convenience rather than performance at all costs. The time it takes to write correct, performant code is far more valuable than having code that runs 15% faster.
This has a lot of potential, but ultimately I'm paid to do other things, meaning those things become the priority...
I like R but generally use it for basic stat tasks and plotting instead of Python. It would awesome if you could share your experience on how to set it up with D in blog post or whatever form you find useful.
D lacks this kind of tutorial material so much.
About scid[0], I looked at it when I started, but it seemed to be largely inactive by that time, it didn't do what I needed, and the documentation wasn't really good enough. I was also turned off by the excessively generic nature of everything - there were just too many templates. At least that's what I recall.
Ada has been an alternative since 1983.
Oberon was an alternative in 1992.
Modula-3 was an alternative in 1988.
And while they don't fix use after free, Object Pascal dialects, Modula-2 have been better options to C in safety terms since ages.
What Rust has coming for it, is being on the forefront bringing affine types into mainstream languages and being more appealing to younger generations than a language like Ada.
This doesn't mean Rust is here to take it all.
In fact, I don't have any specific use case where Rust would excel, AOT compiled languages with value types and automatic memory management fulfill much better my use cases.
For example I do signal processing, and D is surprinsingly pleasant for it since it has builtin complex numbers.
Being well-balanced, generic, readable, productive, and performant seemingly doesn't convince more than "this solves problem Y". Probably why marketers use segmentation.
But at the end of the day, more power is more power and every specialized language tend to become general-purpose.
What does Rust have to do with security? It's not even compliant with any modern security standards (at least not that I'm aware of).
> I have no idea what I would use D for.
This makes no sense. D is a general-purpose language, just like Rust, Nim and Go (and it does concurrency better than Go, IMO). It just happens to be the best general-purpose language that I've ever used. The language gets out of your way and lets you focus on solving problems in the domain you're working in.
In the specific case of Rust, no security is not its primary strength. In fact, it has no standard and a few soundness issues, and I'm not sure what certifications it has, so this makes little sense.
What Rust does have is very impressive. It has a type system that can express a very large subset of data race-free and memory safe programs. It's one of the few languages to get strings right. It has a fantastic package manager. It has destructors, so no more "defer f.Close()". It has sum types, so your state machines actually look like state machines, and "if err != nil { return err; }" is just "?".
Most of these features aren't unique to Rust at all, but their combination definitely is, so I hope this unintentional advertisement explains why "cli tools or backend services" developers like Rust.
Yes, Walter is working on more compile time stuff too, but the existing runtime checks really do excellent work and shouldn't be overlooked.
The truth is it was good enough for most uses already but people waited out for someone to step up and make things better before they felt it would be worth trying D
D really shines if you do greenfield projects where you have the luxury to reinvent some wheels. Its surprisingly pleasant to see a lot of boilerplate one might expect to accumulate to just not be there because it’s either generated or is just not necessary because the language is flexible enough
I can't control how someone else feels, but I can tell you your feeling is very wrong. Just a few of the things people are being paid to work on right now:
Android support
Webassembly
Symmetry Autumn of Code projects
There will also be paid work on iOS once they find someone that can do the job (if they haven't already). And yet another annual DConf will be taking place in London in June.
These are just a few of the examples where folks are putting real money into the D ecosystem. The language continues to evolve (for example, moving to safe by default). This is by far the most active D has been in the seven years I've been using it.
AFAIK adam is going to work on it, once he finishes up with the android stuff.
In order to get something like that to compile for aarch64, you have to build a recent GCC with the very old dmd frontend enabled, and then you can compile LDC2. This all to use one app!
That being said standard formatting function can automatically print most types including user types. This eliminates necessity for automatic formatting implementation in majority of situations
D's compilation isn't "stateful" like that in the sense that (user-defined) attributes both cannot influence the thing they are attached to or do anything without being read by something else.
Eh?
I wish people gave some context of why they post links without context and why I should be interested in the link.
https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1...
1. eliminate double frees 2. eliminate use-after-free 3. eliminate memory leaks 4. using undefined pointers
when using explicit memory management like malloc/free. Any D application, including DasBetterC, that uses explicit memory management can benefit from it.
It's like C# to Java, which has traction only through relentless flogging by Microsoft. There's nobody to flog D.
Ok, "in relation to C++" it is clean. :)
Edit: There is a proposal to fix it: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1028.md
From my experience with Rust, there’s basically _never_ any cost in sticking to safe code. The standard library and crates pretty much always give you enough tools.
Unsafe is really only ever needed if you’re implementing the core of an abstraction, which is probably not something that’s going to deter “casual” users imo.
The borrow checker and and type system definitely can be thorny at times, though. Other times they’re very easy to work with! But having a more ergonomic way to fall back to Java-like behavior, if only for debug builds, would make languages like Rust _much_ more accessible.