Bas Geertsema Software Musings

18Jul/122

Trying out the D programming language

I have been experimenting with the D programming language over the past couple of weeks. D is a native language and was conceived by Walter Bright. Although the language itself has been in development for many years already, it seems that it has been getting more traction over the last couple of years. The name D hints already at it's reason d'etre: to be a better C++. Because of endless backwards compatibility and decades of evolution the C++ language has grown.. well a bit complex. C++ is a language that is powerful in the hands of an experienced programmer, but is daunting for the inexperienced programmers. And even those with years of experience get bitten by the many pittfalls in the language that are the result of this complexity.

So the premise of the D language should provoke excitement by both native and non-native programmers. A modern, powerful and performant systems language that is designed to increase productivity of the programmers in developing safe, robust programs that are still performing great. I surely got excited!

So, does D deliver on this premise? With the current state of affairs, I have mixed feelings about this. The language itself seems powerfull, but when working on it you will notice that there are many issues that are a bit awkward to use or do not work as you expect. For example, D has a powerful type system that does not just include 'const' (as in C++), but also 'immutable' which basically means that this object can never, ever be changed. This in contrast with a 'const' object can be changed by other (non-const) references. This is a powerful concept that enables a lot of optimization in concurrent programs. D also has built-in associative arrays. A declaration like 'string[int]  values' declares an associative array that can be accessed by an integer and returns a string. Also very powerful. But here is the catch, somehow these features do not work together well. For example:

In this example, I try to create an associative array that stores immutable objects of class A. The associative array itself should not be immutable because obviously I want to store objects in it, right? Unfortunately, this code fails. If you want to store immutable object references in an associative array you will get an error from your compiler that states that the associative array is not mutable: 'values[0] isn't mutable'. As D has some peculiar lexing rules I thought I must have had typo's somewhere. I took me a while to figure out that what I was trying to do was simply not possible (afaik), although my common sense still tells me it should be possible! (and more confusing.. it does work with strings, which are in fact also immutable) (.. and even more confusing, storing immutable objects in a regular array does work).

The reason for this particular issue is technical in nature and has to do with immutability being transitive and the difference between head-const and tail-const. A similar issue exists when you want to pass immutable class objects between threads within a concurrent program, which also was very surprising to me. Obviously most issues can usually be solved in the end with work-arounds. But I found myself spending a lot of time in the documentation and the source code of the standard library (phobos) to figure out what to do next.

This can be expected, ofcourse, when the language, the standard library and the whole community is in such a flux. The amount of updates and bug fixes on the compiler and standard library is consistenly high. There is a lot of activity there which is a good thing. I guess things will mature and settle down in the coming years. However, at this point it seems some design concepts are not consistently applied throughout the language and library which do need some ironing out. The forums are a valuable source for reading on design decissions which have been made or yet have to be decided and that can explain why your compiler is showing you that cryptic error. As an indication for the type of change I am talking about, in a recent discussion there is some debate about whether the current modules for reading and writing i/o streams should be deprecated and/or replaced. As any programmer will know, reading and writing to streams is a necessity for many applications. Still, even this important part of the library is not yet stable.

These remarks aside, I believe the future of D can be bright. It's type system, with immutable references, is a powerful construct in this age of multi-core and concurrent programming. D has a powerful templating system and supports Compile Time Function Execution (CTFE) which enables compile-time reflection and computation to generate very performant run-time code.

D is a powerful native language that enables you to program  in bits and bytes while at the same time employ a functional programming style with closures, ranges, and lambda's if possible. This multi-paradigm approach allows for a broad application. Whereas the sweet spot of C++ is systems programming and the sweet spot of (e.g.) ruby is application programming, D might be the language that can be used in both system and application programming.

Imagine a language that a web developer can  use to create a very performant, safe and robust web application while still being able to  program on a high level of abstraction. While at the same time, a colleague of this web developer is a system programmer who is working in the same language on the same project to provide seamless integration with other (legacy) systems. This dual role might become a strength of D.

Efforts have already been made to achieve this. For example, Vibe.D is a web framework for high-performance web applications. Imagine Node.JS, but running on full-speed with optimized native code (yes, even html templates are compiled to native code). These kind of projects have the potential to cross the bridge.

As for now, although D has some productivity issues and requires quite some determination for those willing to try it out, I believe D has the potentional to become an important language in the coming years.

 

  • Adam

    Unless I am misunderstanding what you’re trying to do you’ve just gotten the code wrong, you made the associative array and the class constructor immutable, when all you needed was to make the class immutable. This gives you an array of immutable objects:

    public immutable class A {
    int data = 4;
    }

    int main(string[] argv) {
    A[int] values;
    values[0] = new A();
    values[0].data.writeln;
    //values[0].data = 5; //Will fail because the data is immutable
    return 0;
    }

  • sclyrack

    public this() immutable
    {
    writeln(“test”);
    }

    If you make your constructor immutable you can call it using the following.

    new immutable(A)();