Why the programming language D is a very bad thing

The design of the programming language D lacks one important design which makes it completely unusable:

A powerful standard source code preprocessor.

Why this makes this language unusable is maybe not directly obvious to people which look at a language from the academic perspective, but to be usable in praxis a language simply needs a preprocessor.

Why do I use something

Why does anybody use a programming language? This is related to the question why do people not stick to entering there programs in binary code directly:

Programming languages are used because of comfort. To express something in a PL is more easy than to punch in holes into cards to form binary instructions which then make up the program.

This is a general feature. I do not sit on the ground, because it's more comfort to sit in a chair. I do not eat dirt, because good food is more tasty. And I do use modern gadgets, because they make life more easy. If they don't, I do not need them.

Why do I use languages

I use two types of languages:
  • Interpreted languages like Shell, PHP or Perl and Python
  • Compiled languages like C or others
The question is not why I use a language but which one do I choose first to implement things. The answer is easy:

I choose the language from which I think I can get results most comfortably

This is not such an easy choice. On a Supercomputer I presumably stick to Fortran and even will punch in the program on punchcards because this /is/ the most easy choice for a certain class of problems.

So which languages I do use really daily to do my things:

On Shell level this is Shell (with all the implied tools like AWK and even Perl), for the WWW it is PHP (as it is convenient) and as a compiled language this is C.

Please note under Windows it now is Visual Basic (or VBA) if it cannot be expressed with CygWin easily.

Why C?

The answer is extremely easy:

  • C is available on nearly every machine I want it to run on.
  • It has the Preprocessor.
The C preprocessor is very limited, however it has extreme powers. Powers which are missing in D, as D does not contain any preprocessor. Powers, which cannot be built into D again, as it is simply lacking support. Powers, which are so important, that I cannot miss them.

To explain the powers is too deep going. But it has to to to restructure the source code independently of the language, to make the source more easy to understand. So I need the CPP to express things I do not want to express in C (or any other language).

Perhaps it is more clear if you think of a development cycle of a program:

  • At the beginning many features are lacking. These shall not be implemented. The CPP gives me the opportunity to do so. If I do not have a CPP, I must do it in C. This means, to implement it in the language (even if it might only say "not yet implemented"), but that exactly is not the goal: The goal is to leave it away! Such leftouts cannot be expressed in a language, as it's a contradiction to specify leftouts (specifying leftouts is including it, so it's no more a leftout).
  • In a later cycle you often want to revamp the source code. However you don't want to do this in blocks, you want to do this step for step. So doing this in the language always means to completely revise the source code. However this shall not be done. It shall be done step by step. Steps, which only the CPP can provide, as else it is effort which cannot be handled.
No, Aliases are no solution when it comes to a replacement of #define. Most often such intermediate #defines look extremely horrendous with a lot of ## and other constructs inside. However this is mostly to a design lack of the CPP and not due to the horrendous nature of the rework in progress.

What allows CPP which D does not allow?

The CPP is not on language level. People may criticize that CPP is unable to access runtime variables, and the presentation of D tells about how good D is as it can express the commonly needed CPP constructs in a better way with full access to language features.

But this is the wrong way!

The idea is not to have a CPP which is more capable of the language, no, it's the complete opposite: The CPP must be most independent of the language!

It's nice that D can handle nearly each common construct of the CPP now within the language core. But this is no argument to leave a standard preprocessor away!

There are a lot of constructs which you now are no more able to express. For example, my tino_getopt() can simply no more expressed in D, as I need to rewrite the language on syntax level to formulate my own syntax which is easy to understand and use.

I need this rewrite within the source code I write to be able to mange the thing in an easy and very efficient way. No, functions within functions are most often no solution, too!

And if you think, it's hard to maintain these source code, you are wrong: The CPP enables me to write source code which is extremely easy to maintain! The code, which is generated, is a code monster. However this monster is tamed by the compiler, not me. I am simply not interested to be disturbed by language details because some authors thought, it is clever to leave out a standard preprocessor.

D is lacking a DPP, so source code in D is unmaintainable. Period.

Why a DPP must be in the language core

Now, you perhaps want to argue, that, leaving out a DPP out is an opportunity to wrap something around D to get the feature I need.

This claim is wrong. It is all too wrong, as this suggestion contradicts several aspects of this universe.

Think of sex. Why is evolution so successful?

It is because it is (quite too) simple. Each idiot is able to do sex and get children. And why can even idiots do sex?

Because you do not need additional things for it. That is, throw away everything else you carry, and you still can have sex.

That is, why sex is a successful model for evolution. All you need is a partner of opposite sex and you are done.

Exactly the same must hold true for programming languages:

If you have the PL and an OS, you must be able to compile. Nothing else must be required. No special CPP, no make, nothing. Everything shall be contained in the PL.

In the current situation this means, you have following:

  • You have your OS.
  • You have a standard development environment.
  • You have the source code.
This must be enough to completely compile a program. Nothing else must be needed. No special preprocessor, no uncommon features, no bloated anything else. Just the standard.

Therefor a preprocessor which you can use must be part of the language. If it is not, it cannot be used. It cannot be used, as you do not know what the standard development environment looks alike. Here is something to consider:

It perhaps sounds silly, but for a standard development environment there need not be things like files or intermediate pipes! You put in the source at one side and on another side you will get the executable.

Think about a browser implementation of the D language: You "upload" the source and "download" the program. Where do you stick in the Preprocessor in this scenario?

As a browser plugin which runs on the client side? Does your browser (or client) allow this?

At the compiler side? Are you allowed to extend this development system, as this can be a feature which simply isn't needed!

No, "make" is not the solution, "make" is the problem you must get rid of.

So generally speaking, you can only use features, which are in the language core. For C the CPP always is part of the development system, so you will never miss it. For D there is no such thing, all you can do is stick to the language itself, which (as explained above) is incapable to express everything the same way C does.

So D is simply no replacement for C

D is not even a successor of C nor C++. It's just another programming language which was designed by academics (even if those people write this is not the case) as it was not designed for people like me, who want to use a language their way, so they are definitivly not in need of just another language which does not support their programming style.

Freestyle is the key to a successful language

Yes, D has a more clean syntax, less design flaws, a good support for modern language constructs and a very clean way to express things.

However this all is pointless. Everything you can do with D you can do with other languages. There are a lot of them. Many are extremely powerful (look at Smalltalk). They are still not used.

Why?

My theory is very simple

C is taken in favor of other languages as it has a preprocessor. (Besides that you can write efficient programs and has full library support and a broad codebase.)

Think of following: Why are many programming people fond of TeX?

The answer, again, is: There is a powerful preprocessor (or moreover: TeX is just one single gigantic Preprocessor). So people can express things they like to do and not how the language orders them to do.

Freestyle is the word, the freedom to express things you want to. This is the key feature of a successful language.

Look at Perl: Perl is a language with extreme freestyle. That, however, drives some people (like me) away from it. A certain form of freestyle is OK, however Perl has to many ways to express a single thing. So perl again makes it difficult to understand a source code written some years ago from the same author.

That is the wrong form of freestyle. The idea is not to do allow a bigger chaos (like in Perl) but to allow people to do it their way and augment what's there (C). The CPP is far from being perfect. However it does it's job.

Lacking a simple to use but powerful DPP, one is dictating people how to express themselves. People (like me) dislike such type of languages (like Pascal).

It's that simple.

Last words

D does not fit into the C language model. It does, however, fits in the Modula and Pascal style of languages. So perhaps it can be seen as a replacement of Modula, but not C.

-Tino, 2007-05-31