The Future of D is Functional
The D Programming Language has an impressive list of cool features. That is not always a good thing. A feature should contribute to the philosophy and foundation on which the language was built. If it doesn’t, harmony breaks down and the result is a language that is harder to learn and to use.
Some people think D suffers from such a feature creep. To some degree I can agree. D has features that are unlikely to become widespread, but most of them are aligned towards a common goal. That goal is bringing productivity to the world of low-level programming.
Lately, a new goal has emerged from the D community, and it has triggered some real intense activity. The future of D seems to lie in the field of functional programming, making the imperative and the functional paradigms truly come together.
Why is this important? Let me quote Walter Bright from a discussion at the D forums:
The future of programming will be multicore, multithreaded. Languages that
make it easy to program them will supplant languages that don’t.
[…]
The surge in
use of Haskell and Erlang is evidence of this coming trend (the killer
feature of those languages is they make it easy to do multiprogramming).
As we all know, multithread programming in an imperative language is a real pain. It’s complicated and easy to get wrong, but that is not the case in a functional language. A pure functional program is thread-safe by design, since it’s free from mutable state and side-effects.
You never have to worry about deadlocks and race conditions because you don’t need to use locks! No piece of data in a functional program is modified twice by the same thread, let alone by two different threads. That means you can easily add threads without ever giving conventional problems that plague concurrency applications a second thought!
Quote from Slava Akhmechet’s excellent article Functional Programming For the Rest of Us.
What the people behind D want to do is to create a true functional subset of the D Programming Language, and create a safe interfacing to parts of the program that are imperative. The functional subset would enforce pure functional programming, like disallowing access to mutable global state and calls to non-pure functions. In effect that would enable you to write parts of your program that need to be thread-safe in a functional style, while using the style of programming that most of us are used to for the rest.
But, it might not stop there. Andrei Alexandrescu, who’s one of the driving forces behind the functional subset, has suggested that the enforcements inside a pure function can be relaxed to allow mutability of what he calls “automatic state,” thus allowing imperative techniques to be used as long as the mutability doesn’t leak across the function barrier. Here’s an example from Andrei’s slides on the subject:
int fun(invariant(Node) n) pure { int i = 42; if (n.value) ++i; int accum = 0; for (i = 0; i != n.value; ++i) ++accum; return n.value + i; }
This code doesn’t look a bit functional, but the result of fun() is solely dependent on its arguments, so seen from the outside it’s pure.
Mixing pure functional and main stream imperative programming is certainly bleeding-edge. As far as I know it has never been done in any other language. But even though I’m excited, I can’t help wondering whether this is the right way to go. There’s a risk that D spreads itself too thin, and that the pure functional subset of D will be too noisy; I anticipate a heavy use of the invariant keyword for instance.
Would it be a better option to create a completely new language, say Functional D, and make D and Functional D interoperable on a binary level? At least that would battle the noise by reducing the need for explicitly expressing things like immutability, which can be taken for granted in a functional language. I also suspect that the compilers would be less difficult to implement than a compiler that has to support both styles.
But then again, I don’t know much about making compilers. I just happen to be more of a minimalist when it comes to computer languages. (As opposed to my preferences for APIs and Framworks.)
Expect more posts on this subject as I plan to delve into details next.
Cheers!
One word is very low syntactic baggage considering the verbosity most people are willing to accept from java.
True, but I have a couple of small objections:
1. The invariant keyword is long, and must probably be used all over the place.
2. As suggested, all pure functions needs to be marked with the “pure” keyword. That makes it two new keywords.
3. Just because it’s less verbose than some other language doesn’t make it better.
But I see what you mean, and I’m not negative about the functional subset. I’m merely venting concerns.
“Mixing pure functional and main stream imperative programming is certainly bleeding-edge. As far as I know it has never been done in any other language.”
smalltalk, python, javascript, ruby all mixed in varying degrees of functional with OO/imperative.
ocaml, F#, scala are highly academic approaches at mixing functional with OO/imperative.
clojure an interesting mix of lisp (which includes many imperative constructs), pure-functional, concurrency, and jvm.
Thank you for your input. I don’t know much about the functional languages you mention, but for the imperative ones (javascript and ruby) they don’t have mechanisms to enforce “purely” functional constructs, and thus cannot take functional advantages like parallelism on a compiler level.
But, maybe I should change my claim to: “Mixing pure functional into a main stream imperative language is bleeding-edge.”
The other way around might have already been done, as you indicated, in languages like OCaml and F#. But I wouldn’t know anything about it.
It’s great to see functional programming finally finding a place in D. In 2001/2002 when I was active in the D community I tried to convince Walter of the importance of functional programming, but I wasn’t too convincing (and the time wasn’t right). Recently I saw your posts on D and went to take a look on it. Now it seems to be huge, lots of features and not much language design. From your post it seems that FP will be added upon D, which isn’t the best solution but maybe results in something better than Java, C++ or C#.
I like the attempt to unite these two paradigms, but I, like you I guess, am not sure it’s the best solution.
anonymous, none of those mix functional with imperative in the sense that is meant in this article, as none of them offer any guarantees that the functional part really is functional.
Haskell supports this with the ST Monad.
I’m a systems programmer who hates C++ and really really wanted to embrace D, but my biggest problem with the language has bee nit’s complete lack of identity. Much like C++0x, it seems like nothing more than a hodge-podge of cutting-edge language-geek coolness mashed together and given a name. There’s just no coherency.
I see the interest in functional semantics to be just more of the same… a language with no identity frantically embracing every interesting thing that comes along without any consideration for the final form of the beast.
D is a capable language with some great marketing bullets, but it’s being managed like a toy language, and will suffer a similar fate unless some focus is provided.
What a load of sensationalist nonsense. It seems to have a pretty clear identity to me, it’s a systems language that aims to provide some high-level language features in the interests of productivity, but also lets you do low-level systems programming.
Which feature is at odds with this identity? functional programming is being embraced because they believe it will make systems programming on multi-core and multi-processor systems easier.
“but also lets you do low-level systems programming”
Not low enough. D can’t interpret Linux kernel header files so Linux kernel modules can’t be written in D and use the Linux kernel module build facility.
If he really cares about concurrent programming how about fixing the stop-the-world mark-and-sweep GC that D currently employs?
The D community needs to focus on fixing bugs in their runtime. You can’t adopt D for real-world usage. Every feature added makes the language less stable. The last chunk of features were all around meta-programming which contains so many bugs that it’s pretty much unusable.
… and people say that C++ is a complicated language, come on, don’t enter in that world of complexity, if I want a complexity language I got C++
Love it, can’t wait to use it.
I’ve investigated D several times, but it’s never managed to sway me over from c and c++.
I have an interest in functional languages, and these new features in D would tempt me into trying a few projects the language.
I’ve seen “academic” languages with function annotations like “commutative” but I think “pure” would make a lot more sense. One of the goals of functional annotation is compiler optimization. Compilers are pretty good at optimization small sequences of code but whole program optimization remains elusive. I’m thinking things like automatic parallelization too!
This reminds me a great deal about that talk Tim Sweeney had at some conference a few years back, http://www.scribd.com/doc/5687/The-Next-Mainstream-Programming-Language-A-Game-Developers-Perspective-by-Tim-Sweeney.
Hopefully I’ll get the chance to use D in a real project some time in the near future.
D is merely trying to catch up to what OCaml and F# has already achieved.
That’s probably true, unfortunately I wouldn’t know anything about it (I haven’t had time to dig into those languages yet, probably will – F# seems promising) The difference (I’m guessing here) is that those are functional languages with an imperative subset, while D will be an imperative language with a functional subset.
Scala ( http://www.scala-lang.org ) is my poster child for hybrid FP/OOP. It’s been around as a research effort for a few years, but has gained considerable maturity and visibility in the past year or two. Although its syntax contains elements resembling dynamic languages (e.g. Python, Ruby, etc.) it uses compile-time type inference to achieve strong, static typing.
It is implemented on the Java Virtual Machine, compiles to Java class files, and interoperates with Java code. Those facts explain the interest shown in Scala at “mainstream” conferences such as JavaPolis and JavaOne, as well as smaller-scale conferences such as the JavaPosse Roundup (both 2007 and 2008) and CodeMash. One of the best introductions to the language is the presentation by Martin Odersky (the father of Scala and a major player in the history of Java generics) at JavaPolis late in 2007 ( http://parleys.com/display/PARLEYS/Scala ) .
In addition to the above, Microsoft supports full .Net “citizenship” for F# (their functional language based on OCaml). These facts persuade me that hybrid FP/OOP, which has been around for several years, is a serious alternative for real production development in the coming years.
Perl allows one to mix imperative and functional techniques.