D Language accepted for inclusion in GCC
gcc.gnu.org
gcc.gnu.org
Most Rust contributors are not Mozilla employees. Losing people to work on Rust full-time would be a setback, but we're not really reliant on it; we'd evolve more slowly.
https://dlang.org/blog/2017/05/31/project-highlight-excel-d/
Perhaps that's the reason why both Rust and Go managed to gain so much traction and goodwill, because they actually offer entirely different takes on programming. D, on the other hand, tried to fix problems that existed only due to the lack of work developing C++ beyond the 98 standard. Once the C++11 standardization process took off, D was pushed away into irrelevance.
We generally try to market Rust as a good language on its own merits rather than a "better X." That said, there are undoubtably comparisons to make, but the latest iteration of our marketing is "confident, productive systems programming."
After working with C++11 (or C++14 or C++17), D is such a breath of fresh air. Everything is so... easy. I can do what I want, and I don't have to worry about doing just the wrong kind of thing to get a segfault or UB. I might get stack traces at runtime if I make a mistake, or even better, compiler errors because my types didn't check correctly or my compile-time evaluations had errors, but the language is much simpler and cleaner because it's been able to throw out the baggage of C++. In fact, it's thrown it out twice, once for D1 and again for D2, what is now simply called "D".
And being able to actually throw out cruft without concerns for backwards compatibility is why D isn't irrelevant.
No doubt about it, many existing C++ users feel this way. I've read the same comment many times. Most programmers, however, are not C++ programmers, and they are not looking for a better C++. They are looking for the best programming language for their needs (which means in most cases they won't go anywhere near C++). Your comment about D being irrelevant doesn't make much sense.
And that's precisely why D fails. D was marketed as nothing more than C++'s successor, right down to the naming choice. No one is looking for a better C++, therefore no one bothers with D.
Meanwhile, those who have to work with C++ keep their eyes in the C++ standardization process. Since D's inception, the C++ standardization committee already produced three standards which oddly enough do include stuff that is sought after by the C++ community.
It's great that C++ is catching up. It's almost got static if, except not because it introduces a new scope. Maybe next time...
The C++ programmers I know are attached to native code, but not exactly content with C++. Ethan Watson of Remedy Games (Quantum Break) said "we are an industry looking for salvation".
The evolution of both Go's and Rust's strategies as "replacement" languages is actually pretty interesting.
While Go's official marketing no longer calls it a systems language, the use of that phrase when Go was originally released does indicate that that they envisioned Go to be a "better C" in a sense (perhaps specifically in the sense of being used for userspace "system" utilities in the same vein as the Rob Pike's C-like Alef on Plan 9). At the same time, much of the public rationale given for Go was obviously to avoid the pitfalls of using C++ at Google-like scales (e.g. an aversion to junior-dev footguns and a fanatical focus on fast compilation), which implies that they saw some potential for replacing C++, though they later acknowledged that very little of Go's growth appeared to be coming from C++ programmers (see https://commandcenter.blogspot.com/2012/06/less-is-exponenti... : "Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++.").
Meanwhile, given that Mozilla intended to write a browser engine in Rust, old versions of Rust absolutely intended to replace C++. Like D and Go, ancient pre-0.1 Rust was willing to impose a runtime by default in order to guarantee memory safety (originally intending for both green threads and a garbage collector to be baked into the language), until years of experimentation proved that its static checks were capable of providing memory safety without a runtime, which is the pivotal moment in Rust history (actually a series of pivotal moments, but let me be romantic). Nowadays, rather than market itself as a C++ replacement exclusively, Rust tends to position itself outside of the traditional spectrum of languages as simply a zero-overhead memory-safe systems language. While it's still true Rust competes with C++, is inspired by C++, and can be used to replace C++ (e.g. its usage at Dropbox and in Firefox), Rust also intends to compete directly with C, e.g. for system utilities (e.g. ripgrep), reusable low-level libraries (e.g. librsvg), and extending high-level languages (e.g. Helix).
In any case, I will +1 you on coming from python and ruby, and add another major bucket go developers come from is node js.
Rob Pike uses the phrase within the first 5 minutes or so of the very first presentation video announcing Go, and explicitly mentions that they mean "systems" in the sense of webservers and the like. Since then, Go being a systems language has endlessly (and often maliciously) been misrepresented, so under these circumstances, it's only understandable why this phrase was dropped, even though it was absolutely appropriate since its first use gave plenty of context.
(I'm aware of Caddy, but my understanding is that it's aiming for ease of use over performance.)
is that true? Old versions of Rust looked like Go, IMO.
One interesting thing about D is that we don't have to answer to anybody, so nobody can kill D other than us. We just keep steadily pushing forward regardless.
Some people refer to all of these as "better C++", but it's meant in very different and incomparable ways. For example, Rust is ostensibly a "better C++" in a sense that it retains the low-level, zero-overhead (no GC) etc nature and powerful metaprogramming facilities. Go is a ostensibly a "better C++" because it promotes higher-level, safer abstractions that are still "fast enough" (but not zero-overhead). Ditto Swift.
D is arguably in the same bucket as Swift, and partly as Go. I don't think it's very useful to compare and contrast it against Rust. And I think that of all of these, Rust is the only one that can truly claim to be a "better C++" in a meaningful way. Others are "something better than C++ for most apps you'd write in C++ today".
As big C++ fan and language geek, I am pretty confident that if Java and .NET had taken the route of all other alternatives in the 90's (Oberon, Eiffel, Modula-3, Delphi,...), C and C++ would be less relevant today than they turned out to be.
This because many people make use of them, just because they are the only languages they know about compilers that produce AOT executables, with the option of static linking them.
Maybe even Longhorn would have been a success, instead of having to wait for UWP with .NET Native.
You probably won't be writing kernels with it.
So what, so do Oberon, Modula-3 and many others including D.
Yet quite a few production OSes were even written with them, e.g. Native Oberon for the Ceres Workstation at ETHZ.
Pauses weren't an issue for users' productivity.
http://www.ocp.inf.ethz.ch/wiki/Documentation/Front
Video editor playing a video on the lower right corner.
http://www.ocp.inf.ethz.ch/wiki/Documentation/WindowManager?...
Rust is the best bet we have at a better C (and a better low-level C++).
High level C++ competes with D and Go. Rust is a little too specifically targetted at the low level "systems" programming.
It is, to a degree a matter of taste, of course, but Go APIs tend to be rather simple, whereas Java libraries seem to often have FileOpenDialogStyleTemplateProcessorFactoryFactory-type interfaces.
The major problem I have with Go currently is lack of function overloading, which means you either have to convert your data around a lot or have many similar functions for different data types that do the same thing (basically), but have different names.
I think the comparison with Python is quite fitting, because both languages encourage a certain way to think about and implementing things. For Python it's called pythonic, in Go it's called idiomatic.
It is easy to claim how things "arguably" are, but without providing any justification that is not a very meaningful statement to make.
D very much matches your definition of "low-level, zero-overhead (no GC) etc nature and powerful metaprogramming facilities" – the GC can be avoided easily enough. It can certainly claim to be a "better C++" in this sense. For instance, Weka.IO (a storage startup founded on D) heavily relies on D to offer exactly that, in order to implement a distributed file system with sub-100µs latency.
The fact that you can also write Python-esque code during prototyping (playing fast and loose with the GC, etc.) doesn't detract from the core identity of the language as a tool for systems programming with zero-cost abstractions.
Pointers Gone Wild: Memory Safety and D http://dconf.org/2017/talks/bright.html
If not, then I would posit that it's not correct to say that it matches my definition.
The masses have had a long time to adopt D and I wouldn't get my hopes up simply because it's not dead yet.
http://www.mail-archive.com/digitalmars-d-learn@puremagic.co...
Not only is it not quite dead yet, it's growing rapidly : http://erdani.com/d/downloads.daily.png
DMD downloads direct from home page only.
If something is growing very quickly then saying it hasn't yet dethroned C, so it won't ever be significant seems to me to be a bit brittle thinking. Compound growth and the passage of time - thats what has been underway for some time now.
From what I have seen of D, it provides a C++ without some of the cruft, but without trying to solve other issues with C++-like languages (for eg: usefulness of Algebraic Data Types). Why should someone choose D today over Go or Rust for any project? I have yet to see a convincing answer.
Over Rust: No need to learn new concepts like borrowing
D over Go: D has much better language mechanisms for abstraction and programming in the large.
Go over D: Go has an incremental, mature GC.
Rust and D do not quite target the same application domains (though there's overlap), so it's difficult to compare them. Insofar as they do (D with @nogc and @safe), the tradeoffs become rather complicated.
It is usually only way some programmers are forced to adopt new programming languages, in spite they religious beliefs regarding how programming should be.
Notorious example, game developers moving from Assembly to C/Pascal and later from C to C++.
Or systems programmers being force to move into C++ instead staying with C (e.g. IO KIt and UMDF).
Well, so at least now I am no longer mistaken. ;-)
I have tried to learn D repeatedly over the last couple of years, but I was usually scared off by how complex this language is. Even so, the syntax is far cleaner than C++[1].
Also, the last time I gave it a try, something finally clicked. I am not all there yet, but I am beginning to like it. The community is very friendly and helpful. Being able to ask stupid questions without being shouted at makes learning a language a lot easier.
[1] To be fair, C++ has carried the baggage of backwards compatibility around since its birth, while D did not and could learn from what C++ got right and wrong.
Never having written a compiler, I can only imagine how tedious supporting those must have been; and I would be willing to bet that trigraphs weren't even used much, because, among other reasons, hardly anyone knew of them, so it must have been really frustrating for people to support them. An Exercise in futility.
I really liked D after that, I felt I'm working with python but much faster.
one advice, never use printf function in D, use write() and writeln()
What is ABI compatiblity? in a nutshell it let's you use libraries from another programming language. In D, all you need is a D file that describes the C/C++ library as a wrapper so the D compiler knows what you are using.
This means D will build upon everything that already exists for C/C++. You can intermix C/C++ and D in the same project if you so choose to. Which is really a big deal because you don't necessarily have to stop and rewrite years of code you might already have to start using D.
Syntax wise D is a kin to C#/Java, so if you know C# or Java, jumping over to using D is just a matter of learning the language specific Gotchas and core libraries. So the learning curve is quite low if you know C/C++,C#, or Java.
to see what D libraries are out there I suggest looking at http://code.dlang.org/
Said compiler must somehow work together with the D compiler here, which should lead to god-awful memory use, compilation time, and error messages.
How does it work in practice ? C++ name mangling is not standardized and so every compiler can implement its own scheme. So does it mean there is a list of D compatible c++ compiler somewhere ? I have the feeling that if you are using some exotic proprietary c++ compiler it won't work well.
That's right, and the D compiler deals with that by customizing the C++ mangling for every platform.
So you have a C++ file that uses vector<int>, vector<struct c_struct>, vector<CppClass>, vector<DClass>, etc. once and then you can link to them from D code.
The only case where that doesn't work is when you have lots of one-off instantiations, where requiring an instantiation in C++ code for each use in D would get annoying quickly.
Do you have to write some kind of D header file for foreign C++ functions? Otherwise, how would D even know about the existence of e.g. vector<int>::push?
You will need to recreate the C++ function definitions in D and mark them extern(C++), but that's about it.
Let's be clear a compiler builds a object files that have to be linked to create a executable binary. IE compiler makes .o files. Linker takes output object files from the compiler an puts them (.o,.so/.dll,.a) together, to make .exe files.
This all works because you are linking to the C/C++ library binaries (the .o, .so, .a, .dll) files generated by a C/C++ compiling/linking. In most cases this is shared object library/dll provided by the operating system or pre-built library you install on the system. There is no need to compile it because it is pre-built. if you do compile the library yourself, it is a one time thing.
In D you create a .d file that describes what is in a C++ library .o/.so/.a/.dll file. So that upon linking, you take your D code's .o files + the C/C++ .o files to put together a full executable binary.
Templates are delivered as C++ include files (i.e. source code). When you use them, the compiler fills in the types you want and compiles the result.
For example, there's the std::vector<> template. You can fill in any type that meets the specific requirements of the template and use it like std::vector<int> or std::vector<YourC++ClassType>.
However, you probably won't be able to do std::vector<YourDClassType>. ABI compatibility is not enough to do this as you would be effectively mixing C++ and D source code here.
I think this should be working. You don't have to 'mix source code', you can implement YourDClassType in D and use it in C++. You simply have to write a C++ header describing the class. Then write a D file describing the external C++ sdt::vector<YourDClassType> file and link everything together.
Not sure if anybody actively tested this though ;-)
Also if your "library" is all templates, it's not a library, it's a framework that uses other libraries. There still has to be at some point tangible code that is compiled to an object file to be linked. You will have to find all of the dependancies and make sure that they are also described in a .d file.
This might mean you have a bunch of work that you need to do in order use the c++ code you want to bring in into D. But then again, if it's a public/open source library, and you go down that rabbit hole and make it work, you just made D even better.
please see https://dlang.org/spec/cpp_interface.html#cpp-templates for more details.
TIL STL is not a library.
The next option is to use reference counting by wrapping your data in Rc/Arc (depending on whether you need atomicity or not).
But that can still leak memory if you have cyclic data structures and can't break the cycle with Weak pointers.
At this point, what you need is a garbage collector.
So it is up to the community if they want to accept such change.
I should note that they still need some help cleaning the standard library and compiler corner cases in regard to @safe.
As always in such cases, to validate binary libraries, they need some kind of metadata to indicate they are safe libraries (aka they only use of @safe or @thrusted code).
.NET does this with MSIL metadata, Modula-3 does it directly on the module definition section, for example.
GC + range checks provide memory safety to most programs without the kind of extra work you need in Rust. This is a big reason why they are so common in industry.
@safe:
at the top of your code, it'll be memory safe (excluding issues which we plug 'em when we find 'em). I wouldn't say that makes it fundamentally different from Rust. What is fundamentally different from Rust is the approach D uses to implement memory safety.And yes, templates are so much better in D than in C++ or in C# :)
How does @nogc work in D? Is it easy to keep track of what needs freeing and what does not or is it easy to mix up and get hard bugs? Also, what do these bugs look like? Is use-after-free possible or how is the failure mode i that case? Is it possible to call free on an object after it's been garbage collected?
The answer to all of your questions is basically the same as they are in C and C++. D does have @safe though which prevents unsafe memory operations and Walter is in the process of ratcheting up the memory safety with DIP1000[2].
1. https://dlang.org/phobos/std_experimental_allocator.html 2. https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md
Want function programming and purity? Check.
Want C style/low abstraction code? Check.
Want extreme C++ metaprogramming? Check.
Want C#'s LINQ? Check.
Want an improved version of C++'s STL? Check.
Want low cognitive load memory management through a GC? Check.
Want highly tailored memory management? Check.
Want high level object oriented abstractions? Check.
Want memory safety? Check.
Want systems programming? Check.
Want rapid prototyping? Check.
D, fundamentally, assumes the programmer knows what approach they should take and lets them do it. There are no "we know better" design decisions in the language. I think this might be because D is so community driven. With no real company backing D was left in the hands of enthusiasts coming from all sorts of different backgrounds to implement ideas they liked.
That's a major problem, and not a feature.
One of C++'s main drawbacks is its size and arcane features, to the point that the language is known for being impossible to master. If all D brings to the table is an agenda to pick off C++'s complexity and drive it up even further then I fail to see what problems that will solve while it creates many others.
auto names = [ "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David"];
names.filter!(a => a.length == 5)
.array // convert from lazy range to array so we can sort
.sort!()
.map!(a => a.asUpperCase)
.joiner("\n")
.writeln;
Ranges enable lazy processing with efficient static dispatch against arbitrary types of ranges. Those individual algorithm functions are basically all template functions that return types tailored to match the input which allows the lazy evaluation to work. When writeln asks for the first element to print it asks joiner which asks map which asks asUpperCase and so on. The results are calculated upon request, not in advance, which helps you forgo a lot of memory allocations for storing temporary results.UFCS lets you call a function as if it were a member of the first parameter (i.e. fun(x, y) -> x.fun(y)). This lets you write it as if it were chain rather than a series of inside out function calls (i.e. `writeln(joiner(map!(a => asUpperCase(a)(sort!()(array(filter!(a => a.length == 5)(names)))), "\n"))`).
There is exactly two memory allocations in all of that. Once for the initial array and again prior to sorting because it's not reasonable to sort a lazy range. We could have reused the initial array by eagerly removing the items being filtered from it if we wanted.
And built in at the compiler level, so it happens when you compile your program as you normally would, the tests show up while compiling, and the output does not contain the code. Always impressed me.
I could really see D take off now that it's getting gcc support.
https://github.com/dlang/dmd/blob/master/LICENSE.txt
I don't mean this to start a fight over licenses I'm just curious how it works when gcc lets other projects in.
GDC (and LDC, the LLVM D compiler) use the frontend (lexer, parser,semantic) provided by the DMD reference compiler. GDC and LDC then map the AST produced by the frontend to something GCC and LLVM understand.
The DMD frontend has always been boost licensed. So the licensing question is valid here as we'll include boost frontend code into GCC. But I don't really have an answer to the question ;-)
I don't know the details of the D compiler frontend that has now become part of GCC, but I'd imagine its something like that. E.g. the GCC Go frontend is, AFAIK, BSD licensed.
The frontend has been Free Software since the beginning. The reference backend was only Open Source (not freely redistributable).
So, alternative backends were plugged to the frontend, LLVM and GCC. They all share the same frontend still, although LLVM and GCC slightly lag behind the reference in version (LLVM is nearly in sync).
This announcement is official recognition after Iain and helpers did the grunt work consistently for years now.
Free redistributibility is part of the Open Source Definition. It is literally the first item: https://opensource.org/osd-annotated
The one major thing you can't do is redistribute the base source code. That's a big thing, and disqualifies it from being open source, but let's not pretend there is no value in the source code access.
Collins still has the old definition "free to use or modify". Merriam-Webster and Oxford has since included "redistribution" in the definition.
The term "shared source" is not in any dictionary though.
The notion that the phrase "open source" started out with broader definition but was later revised by OSI is itself revisionism.
OSI's definition is important because the phrase "open source" originates with the folks behind OSI—the term did not exist before 1998 when they created it. The phrase resulted from a public awareness effort leading up to the release of the Mozilla code on March 31, because the only alternative that had legs at the time was the FSF's term "free software", which had marketability problems. A few months later, a bunch of those involved in the brainstorming session where "open source" was coined went on to start the OSI as an advocacy group primarily concerned with:
a) marketing the term "open source" to get the public to adopt it en masse
b) advocating for the adoption of open source ideals themselves
To sum up, there has never been a time when "open source" meant something besides how the OSI defined it, except for sloppy usage in instances of someone co-opting the OSI's term but not their definition for it.
(Disagree with whether it's a good definition or not, but telling history and facts wrong is something to be avoided.)
http://jordi.inversethought.com/blog/5-things-we-have-forgot...
https://en.wikipedia.org/wiki/Shared_Source_Common_Language_...
That said, it's a surprisingly good term, because it's so accurate - the source is shared with you, but there isn't much you can do with it other than look at it.
Pedantically, you are correct. But making the whole thing Free Software has cleared up a lot of confusion about this issue, and has undoubtedly helped. Perception matters.
For example, an acquaintance plays (at least used to) a large role in the AVR (8 bit) back-end. He went to a gcc summit to lobby for avr-gcc being upgraded to a support tier where functional (not performance) regressions would be release show-stoppers. His argument: Over a million downloads per month. It took that much to get the gcc steering committee to even consider it. gcc is a big project, they can't afford to make commitments lightly.
<sarcasm (or something)> Because they need an alternative to the mess that is C++ and Rust is already married to LLVM.</sarcasm>
Great work, Iain!!!
If it's a small amount of work, and the only thing really preventing it is wider adoption, this news may be the kick that it needs.
If it's a large amount of work, then this news likely won't change much.
We require some per-target integration to provide correct version(ARM), version(linux) statements in D code and we need to know the size of a mutex on the target system. Iain is currently rewriting this code here: https://github.com/D-Programming-GDC/GDC/pull/500
However, we already provide and the new, rewritten code will continue to provide this integration for many targets. For example, all debian targets should be working: https://packages.debian.org/experimental/gdc
The main problem with architecture support is porting the runtime library and phobos. Here ARM is supported, MIPS and PPC has seen some work from LDC devs but making this work fully on GDC might require some small changes, MinGW is broken (and was never fully supported).
One caveat thought is that all D compilers mainly target 32 or 64 bit systems. So things won't just work without changes for 8bit targets, although we've seen proof of concept D code on 8bit and 16bit CPUs as well.
Back then we had a shell script hack that was called by the GCC configure script and parsed the target triplet to set these versions.
Fortunately that's long gone and we now simply add some D specific code to the platform configuration files in gcc/config/ . The shell script hack would have never passed the GCC review ;-)
Actually they are. Take a look at this example:
void main() {
int delegate(int) @safe nothrow @nogc pure f;
//This looks like something bad is happening, but the delegate literal
//actually has the proper attributes inferred so it Just Works
f = delegate(int) { return 0; };
int delegate(int) g;
f = g; //Fails, as it should
}Refactoring, no.
Edit: There is also a D-specific IDE called coedit, which is pretty good AFAIK
I assume it's forked from an existing open-source editor, but there's nothing in the source headers to say which one.
i think so, because i believe ocaml and d do compete, and it is clear facebook stopped using d and now used ocaml in several project, they even created reason
any idea why facebook dropped d
Rust guides you more toward certain approaches. That makes rust easier to learn, but it makes it harder to integrate with existing projects. On paper, rust could work great in a lot of environments, but I'm finding that it takes a bit more work to integrate with a real codebase. It can be done, and I feel like that's well supported, but it takes some real work to port the concepts of a C API into a good and safe rust API.
D might make that easier because it's an "everything" language, so there is likely a corresponding D equivalent of almost any existing API. Of course, you won't get the same level of safety or other benefits, but it could be a smoother path.
The built-in `scope` syntax is deprecated (though making a comeback recently as more stuff gets implemented around it), but you can also do a library type fairly easily, just slightly heavier in syntax (you need to prepare the memory and construct the object in two separate lines) or prep work (write a struct which does both).
- GC by default, manual memory management where and when you need it with no loss of efficiency
- Better metaprogramming
- Does not compromise on things a C++ coder would care about (speed, efficiency, deterministic behavior, etc.)
The language is led by Andrei Alecsandrescu and Walter Bright, two C++ core language veterans
Fewer languages help everyone communicate easier/better.
Programming languages seem to go the opposite direction.
Any speculation on why?
Programming started out with one very limited language (machine code), the spread out to cover the world, and new languages flourished. As technology progresses and the world becomes smaller, having fewer languages (or at least, a few common languages) will make more sense. With the advent of the singularity, the world will have become so small a single language might be the best option.=