How does D improve on C++17?
p0nce.github.io
p0nce.github.io
However not a beat a dead horse, but if you want to process more than a trickle of data in it you run into problems with the GC really quickly. I really feel the language would be better off without the GC.
These are not the same issues address by the JSON compiler post or w/e that surfaces a couple months ago.
From what I can tell, theres a global lock around everything in the GC, including allocations. In a multi-core world, this just simply doesn't work and it one of the major pain point of the language. I write data-intensive processing on high core count machines (32), and have had to resort to 0-allocation strategies, or in map-reduce contexts actually sharding at the process level, writing the results to disk, and then running a reducer process over the results.
You can write performant D code, but you give up large amounts of code safety. It's essentially just whatever you'd write in C++ without the ownership semantics it gives you.
You can't have a core part of your language being an essentially unavoidable massive point of contention.
I've literally seen 20x or more speedups in multithreaded cases just by making sure I reuse every buffer rather than create new ones.
I feel this is really holding back an otherwise great language to work in.
This is discussed in the reddit thread in more detail.
D with an Hotspot comparable GC quality would be quite good.
I thought using SIMD to accelerate it more on the integrator and acceleration calculation, inside of the parallel for.
Reuse rather than free and reallocate is a core practice whenever you feel the need for speed, regardless of the memory allocate strategy used.
For some very fast D code:
https://github.com/facebook/warp
Minimizing the amount of heap memory allocated is a core strategy.
Not that buffer reuse/avoiding heap allocations was unknown to me, it was just surprising to see this in an application that spent most of it's time waiting on the network.
I will say as a positive point that the equivalent D code to a C++ implementation was much cleaner due to build in array slicing among other things.
There are other areas where heap allocations are not so avoidable however (some hashmaps, some std's). My main point is that like at all languages, heap allocations are slow, but here they bear an unnecessarily large contention factor.
I really like D so I hope this is helpful feedback.
The problem with this conventional wisdom is that it defeats other optimisations. If you free, use, and deallocate a block of memory within a compilation unit, a compiler can transparently allocate it on the stack, or even keep it in registers
If you use a free-list the objects are always escaped, and the same optimisations can't be applied to them.
This is particularly true for small temporary objects, like an intermediate vector (as in coordinates) object.
I just discovered that the language authors are converting the std library (phobos) to be "no GC".
Algorithms, by and large, do not need to dynamically allocate memory. By converting more of Phobos to being algorithms, they become agnostic to whatever allocation method is used. Allocation strategy becomes a high level decision, rather than a low level one.
How does this work, specifically conditional compilation? I have lots of code like this:
#if __APPLE__
/* do things the OS X way */
#else
/* do things the Linux way */
#endif
Where the OS X way calls functions that do not exist on Linux, and vice-versa. How does D handle this?The salient point is that conditional compilation in D is not text based, it is AST based. Furthermore, for 'static if', the conditional expression has access to the full symbol table and power of the D language - it is not a separate preprocessor language with its own rules and separate symbol table.
The constructs are simply built into the language.
This has considerable benefits: you can use e.g. `static if` to enable/disable code based on conditions which refer to constants declared in the program (there is no longer a separate namespace for preprocessor defines and program constants), and with CTFE, you can use any expression that can be evaluated during compilation.
version (Posix) {
version(OSX) {
// Weird stuff on OSX
}
// Sane stuff for Linux or FreeBSD
}
version (Windows) {
// Weird stuff for Windows
}
But think that this is processed by the compiler, not by a text pre-processor. Also, you can use your own version stuff, for example here : https://github.com/Zardoz89/nBodySim/blob/master/source/app.... there is a "PFor" version to allow to compile a version of the program that uses a parallel foreach (an N Body simulator)Ironically, the dmd compiler is written in C++.
Is that going to make it trickier for GDC/LDC to stay in sync with DMD? (Either way, it's exciting news!)
http://tech.adroll.com/blog/data/2014/11/17/d-is-for-data-sc...
Here's a bit of code from a personal shopping comparison program I wrote a few days ago, which combines some standard library constructs with my own libraries:
string findProduct(string name)
{
return
("http://www.tp-link.com/en/search/?q=" ~ encodeComponent(name))
.download
.readText
.toXML
.xmlParse
.I!(doc => zip(
doc
.findAll("#productResult > li > dl > dt > a")
.map!(e => e.attributes["href"])
,
doc
.findAll("#productResult > li > dl > dt > a")
.map!(e => e.children[$-1].text.strip)
))
.filter!(t => !icmp(t[1], name))
.I!(r => r.empty ? null : "http://www.tp-link.com" ~ r.front[0])
;
}Thanks for all your hard work, there's people out there who really found RABCDAsm really helpful, and it inspired a lot of fun software in the process.
D fits lots of purposes (more than C++), but I'm only going to talk about scripting.
The minimalistic approach for the C++ standard library makes C++ inappropriate to replace, for example, Bash scripts. In C++, you can't do any operation on the file system (erase a directory, get file size, list files, create pipes, ..) in a portable way. You can't create processes in a portable way.
The D standard library (aka Phobos) doesn't suffer these limitations. Which means you can write very high-level code using only a few (readable) lines. By adding a shebang "#!/usr/bin/env rdmd" at the beginning of your D programs, you can execute them without prior explicit compilation, like: ./myProgram.d
I've been porting all my Bash scripts to D. The code runs incredibly faster, and now I can have structs again!
I really enjoy a lot more writing on D, but I keep finding the issue that I need to interface with C++ libs for something (for example Qt 5 for an emulator GUI) or weird errors like these problem with std.net.curl on Ubuntu 14.04 . If not was for that, I would wrote the Trillek virtual computer on D.
http://wiki.dlang.org/GUI_Libraries
Just thought I'd share, maybe you overlooked it and this might be helpful for future projects? Good luck!
Also, I played a few with Qt 5 on C++... I would like to have updated binding of Qt for D. qtd and dqt looks that are abandoned. :S
DQuick looks interesting, perhaps I would rewrite my fontmap editor with it.
PD: If I look that I hate a bit Gtk, I would only say that with buggy graphics drivers (ie ATI/AMD cards on Linux), Gtk usually have horrible graphical glitches, when Qt simply works fine.
This comes up all the time in reference to C++. C++ doesn't need a package manager because it has excellent support from distro package managers. Most libraries are in the system package manager. And yes, sometimes you need a newer version of a package or one not quite widely-used enough to be in the system package manager, in which case you need to do compile it yourself or install it manually. But that is a problem common to all package managers and there is nothing about D which will make it any easier.
Anyone here unhappy with pip?
Yeah, e.g. Chromium. But that was also the reason why Fedora refused to provide packages for Chromium. Distros don't like projects that include their own versions of libraries because it goes against how things are supposed to work (maintenance and, by implication, a security nightmare). I know that there are many C++ projects in the various distro package repos, and no way do 'most of them' include their own copies of dependencies.
> Anyone here unhappy with pip?
Pip has (had) a number of issues (mostly related to pypi/availability) -- but pip+virtualenvs is something I use all the time, and am very happy with.
The ease with which one can simply:
virtualenv some_experiment # --no-site-packages
# is now standard! yay!
./some_experiment/bin/pip install -U pip distribute
# sadly needed -- but gets us pip list --outated, which
# is very helpful
./some_experiment/bin/pip install <thing-to-test>
And then just work with that, without even having to mess around with sourcing the "activate" script etc for most packages is great. No clutter under /usr/local, no broken system tools due to some dependency being pulled in etc.Package managers for development allow things such as installing multiple versions of a library, creating "sandboxes" with specific versions of libraries, and sometimes they are also the de-facto build system for a language.
The OS package manager isn't doing the same job and has very different requirements. Not all libraries (especially ones that are usually built statically or header-only) end up in an OS package manager. Typically OS package managers don't bundle any libraries that are not required by one or more of applications in the package repository.
So no, an OS package manager doesn't cut it for C or C++ development. They don't ship all the libraries and they can't do all the things you need for serious development.
As a C and C++ developer, this pisses me off constantly. Even though most libraries are easy enough to fetch these days with Git, there's no standard way of configuring, building and installing them. And no OS package manager has ever been able to provide all the libraries I need.
The operating system package manager is supposed to
provide packages for libraries that are required to
run the rest of the operating system. Not libraries
you need for development.
Distro repos do provide many of the packages you need for development because you need to be able to compile all of the C++ applications and libraries in the distro repo, of which there are many. Package managers for development allow things such as
installing multiple versions of a library, creating
"sandboxes" with specific version
Distro repos often include multiple versions of libraries because not all of the crucial applications and libraries in the repo are upgraded at the same speed. The OS package manager isn't doing the same job and has very
different requirements. Not all libraries (especially ones that
are usually built statically or header-only) end up in an OS
package manager. Typically OS package managers don't bundle
any libraries that are not required by one or more of
applications in the package repository.
Fair enough, and for this reason a language-specific PM will most likely have more libraries available, so I concede that point. However, I seriously doubt that a single group of people could be better at providing packages for all the major combinations of kernel, distro, and CPU architecture than the collection of distro groups. Just imagine how difficult that would be!C++ is different because it is very intertwined with the system. For D it makes sense at this point because it doesn't have the existing distro PM support that C++ does. Once crucial parts of the system starts depending on D the situation might change.
I think it's more along the lines of the distro's package manager's responsibilities should be different from the language's PM. Although I do find myself in agreement with you that the distro's PM is sufficient for C/C++
To name a C++-specific pain in the ass: Boost. The Boost libraries make minor, incompatible changes every now and then (which is good), requiring applications that use Boost to either specify a certain version that they can work with or bundle the Boost libraries with the application source (which is bad).
And "development" package manager should be able to deal with the situation above, but distro package managers don't really work here. There are several libboost-foo-1.xy.z packages available but it may be that none of those will work with a certain application you're trying to build (either too old or too new).
This situation is handled by development package managers by pinpointing the exact version (or range of versions) of a library an application depends on. This also allows specifying compiler/interpreter version(s) an application works with. Some of my projects depend on features that are only available in recent GCC versions (__builtin_shuffle), but that requirement can only be informally specified in the README, nothing enforces it (leading to unnecessary bug reports).
This is also what git submodules does but without a standard build system, it only solves half of the problem (and may create new problems).
I think you and I can both agree that this situation is less than ideal. Using just one package manager application should be enough, there's a lot of overlap between what a distro package manager and a development package manager do. And it's a huge waste of engineering resources to maintain language-specific package managers such as pip/gem/cabal/cpan.
"Next generation" package managers such as Nix and GNU Guix should be able to address these issues, but they are yet to be widely adopted. Unfortunately those applications are based on less-than-mainstream languages (Haskell and Guile Scheme, respectively) which might scare away potential adopters.
In what areas would D excel? What are its downsides? What did you like and dislike the most? I'd be really interested in hearing about people's experiences.
Lets you specify contracts which are asserted on construction and destruction, it's great.
The meta programming is also wonderful for things like serialization of data, simply iterating over a type's members at compile-time to generate serialization code, cutting out much bloated code. It's worth noting that it's metaprogramming for humans, _compared_ to c++, but sometimes leaves a bit to be desired documentation-wise, all the building blocks are there, but sometimes you'd like to not need to reinvent the wheel every time you attempt some metaprogramming-related task.
Things I don't enjoy include the core language's reliance on the GC, including things like exceptions relying on GC allocations.
Thankfully they've made it a bit easier to track down things which may allocate gc memory lately with accompanying flags to the compiler, which prints a trace of where it may happen.
Can you still turn off the GC? Lets say I don't like exceptions, and that I don't mind implementing library code on my own, would turning GC off impact anything else?
How is the story for deploying executables to mac/win/lin? Is it as easy as C/C++?
Also, do you know if anybody's shipped high quality games with it before? It's been a while now, I'd hope so, but I haven't heard of any. Pretty sure no AAA games have used it but maybe some indie?
You can turn off the GC in the sense that memory allocation will always request more memory from the OS instead of occasionally starting a collect cycle. However, you can alternatively use manual memory management (malloc/free, allocators/RAII on top of that, etc.), which will never trigger the GC.
> How is the story for deploying executables to mac/win/lin? Is it as easy as C/C++?
Yes. I think for Posix systems, you can optionally link dynamically to the runtime/standard library.
> Also, do you know if anybody's shipped high quality games with it before?
IIRC, Remedy Games used D for engine scripting on XBox 360. Manu Evans talked about this at DConf 2013.
Here's a commercial indie game written in D: http://www.inventivedingo.com/mayhemig
There are a few gotchas sometimes, like array literals of certain kinds sometimes allocating when you don't expect them to, but these can usually be sorted. Something which also might bite you, but can be caught with the gc-tracking compiler flag, is the fact that delegate _closures_ use the GC, regular delegates however will not need the GC, one thing to keep in mind.
There's quite a bit of info about how the GC impacts things, and how to get by without it around, so I think you'll survive without it's presence.
Lately as well, efforts to annotate portions of the standard library which don't use the GC at all with a special annotation @nogc has been underway, which makes it explicit if something can allocate or not (this is transitive, so a @nogc annotated function can only call @nogc annotated functions which can't do any gc allocation in turn).
I'm not a huge fan of closures in many cases (if they outlive the scope of their defining function I think it leads to unclear code), so the fact that they might allocate is not a huge deal to me. Array literals silently allocating GCed memory concerns me greatly however...
I remember hearing about efforts to remove a lot of the reliance on the GC, and I guess I was hoping that that was further along than it sounds like it is.
Still, I'll try not to pass judgement until I try it out on something small. There are a lot of other potential issues unrelated to the GC that would probably be dealbreakers for me.
Good luck with trying it out, you make tradeoffs as with any other language :)
Making games? :) I'm half joking here, Kenta Cho has made tons of shoot'em up games, mostly written in D (and released as Open Source) for years:
> Even when C++ compilers implement modules and you can finally use them, headers will still survive alongside modules for backward compatibility.
Uh, that one is just weird. So, a reason to use D is because C++ can support older projects?
The one issue that sticks for me was the dual standard libraries. Just seems so messy.
Honestly, I'm pretty excited for Rust. Having a strong proof of lifetime enforced by compiler is very compelling idea.