== Quote from Walter Bright ([EMAIL PROTECTED])'s article
> I wish it were possible to have a language with just a small set of
> features that can do everything. C++'s problem is it can approximately
> do everything but with a boatload of gotcha's, like a const system that
> almost works but doesn't deliver. Java threw out too much.

Agreed.  The problem with C++ isn't so much that it's just complex.  Its problem
is that its complexity comes in the form of lots of cruft inherited from C, from
technological limitations that existed during its development but are no longer
relevant and from just plain bad design decisions that can't be undone without
massively breaking backwards compatibility.

Java went so far in the quest for simplicity that, since the irreducible
complexity of a program has to go somewhere, it ends up being expressed in lots 
of
"design patterns" that should be replaced by language features.  Worse yet, 
Java's
solution to C++'s complexity is to force one level of abstraction, namely the
class, to fit every problem, no matter how awkward that is.  For example, let's
say I wanted to write a simple function to sort an array by an arbitrary
comparison function in Java:

void sort(ArrayList<T> stuff, Comp comp) {...}

I have to define an interface called Comp and a class that inherits from it, 
which
under the hood is using arrays of function pointers, because Java doesn't trust 
me
with function pointers.  This is called abstraction inversion.

Most programs have some subproblems that are pretty run-of-the-mill and should
just be solved in the most expedient way possible, and others that require more
thought, either to make them generic enough or fast enough.  Mixing languages in
one project is generally a pain, especially if you want to do so on a 
fine-grained
level.  Therefore, the thing D gets right that few if any other languages do is
that it has a "keep it simple, stupid" layer for the run-of-the-mill subproblems
and a ridiculously complex but powerful boot-with-a-gun-built-in layer for the
more challenging ones, *in one language*.  The simple layer includes builtin
arrays, builtin associative arrays, garbage collection, the ~= operator, good
string handling, and a reasonably powerful standard lib, at least if you're 
using
either Tango or the D2 version of Phobos.  The complex layer includes templates,
manual memory management, unions, casting, operator overloading, and inline 
assembler.

The way I usually write my D code is to use the complex layer for relatively
generic, performance-critical code near the bottom of my abstraction hierarchy,
and then use the simple layer in the higher levels of my programs to call this
code.  That way, I get C++-like performance when I need it, and Python-like 
safety
and ease of coding when I don't.  Frankly, this works amazingly well.  Being 
able
to do this in one language, so seamlessly, is a perfect example of useful 
complexity.

Reply via email to