The D Language Progresses
xsniper writes "D made its debut here on Slashdot in August 2001. Since then, many new features have been implemented, to include: operator overloading and slew of additional functionalities. It was featured as a cover story for the February 2002 issue of Dr. Dobb's Journal, and has been ported to the UNIX environment. I encourage programmers to revisit the specs to see how Walter Bright has addressed their concerns. A copy of the compiler is also available for testing. I'm sure some would be surprised by the achievements made thus far."
What is D?
D is a general purpose systems and applications programming language. It is a higher level language than C++, but retains the ability to write high performance code and interface directly with the operating system API's and with hardware. D is well suited to writing medium to large scale million line programs with teams of developers. D is easy to learn, provides many capabilities to aid the programmer, and is well suited to aggressive compiler optimization technology.
D is not a scripting language, nor an interpreted language. It doesn't come with a VM, a religion, or an overriding philosophy. It's a practical language for practical programmers who need to get the job done quickly, reliably, and leave behind maintainable, easy to understand code.
D is the culmination of decades of experience implementing compilers for many diverse languages, and attempting to construct large projects using those languages. D draws inspiration from those other languages (most especially C++) and tempers it with experience and real world practicality.
Why D?
Why, indeed. Who needs another programming language?
The software industry has come a long way since the C language was invented. Many new concepts were added to the language with C++, but backwards compatibility with C was maintained, including compatibility with nearly all the weaknesses of the original design. There have been many attempts to fix those weaknesses, but the compatibility issue frustrates it. Meanwhile, both C and C++ undergo a constant accretion of new features. These new features must be carefully fitted into the existing structure without requiring rewriting old code. The end result is very complicated - the C standard is nearly 500 pages, and the C++ standard is about 750 pages! The reality of the C++ compiler business is that few compilers effectively implement the entire standard.
C++ programmers tend to program in particular islands of the language, i.e. getting very proficient using certain features while avoiding other feature sets. While the code is portable from compiler to compiler, it can be hard to port it from programmer to programmer. A great strength of C++ is that it can support many radically different styles of programming - but in long term use, the overlapping and contradictory styles are a hindrance.
It's frustrating that such a powerful language does not do basic things like resizing arrays and concatenating strings. Yes, C++ does provide the meta programming ability to implement resizable arrays and strings like the vector type in the STL. Such fundamental features, however, ought to be part of the language. Can the power and capability of C++ be extracted, redesigned, and recast into a language that is simple, orthogonal, and practical? Can it all be put into a package that is easy for compiler writers to correctly implement, and which enables compilers to efficiently generate aggressively optimized code?
Modern compiler technology has progressed to the point where language features for the purpose of compensating for primitive compiler technology can be omitted. (An example of this would be the 'register' keyword in C, a more subtle example is the macro preprocessor in C.) We can rely on modern compiler optimization technology to not need language features necessary to get acceptable code quality out of primitive compilers.
D aims to reduce software development costs by at least 10% by adding in proven productivity enhancing features and by adjusting language features so that common, time-consuming bugs are eliminated from the start.
P and L got used up by APL though. This is BCD..Binary Coded Decimal.
Jason
ProfQuotes
And of course, generics.
Now all it needs is some community support and ECMA goodness. I think it has a good chance of being widely used.
Why should I use D instead of Java? D is distinct from Java in purpose, philosophy and reality. Here are some of the ways, in no particular order:
D has Design by Contract.
D has unit testing.
D has lightweight arrays.
D has lightweight objects.
D has enumerated types.
D has typedefs.
D has function delegates.
D has inline assembler.
D has direct access to hardware I/O ports.
D has a considerably smaller executable size (no VM needed).
D has out and inout function parameters, i.e. functions can return multiple values.
D has code execution speed that is as fast or faster than C.
D has direct support of all C types.
D has support for complex and imaginary floating point types, ASCII, unsigned types, etc.
D has arrays of bits.
D has associative arrays.
D supports direct interfacing to C and operating system APIs.
D has version control as part of the language.
Debug D programs with common, existing C debuggers.
D has a minimal learning curve for C programmers.
D has turn-offable array bounds checking.
D has support for assert()s and debug statements, and other tunable runtime error checking.
D has no need for external C functions.
D's full library source means complete control over generated app.
D's floating point is the best available on the target machine.
D has strings implemented as arrays, not objects.
D does not do dynamic class loading.
D works with your other existing dev tools (make, linkers, debuggers, etc.)
Java is designed to be write once, run everywhere. D is designed for writing efficient native system apps. Although D and Java share the notion that garbage collection is good and multiple inheritance is bad , their different design goals mean the languages have very different feels.
Non-virtual methods in Java also involve no indirection. A non-virtual method is one that is private, final, or static. The only difference is:
in C++, a method is non-virtual unless declared virtual
in Java, a method is virtual unless declared non-virtual
void main ()
/* Called at the start of the program before main */
/* Called after main or an unhandled exception. */
/* The constructor - C++ would have "HelloWorld ()" here */
/* The destructor - C++ would have "~HelloWorld ()" here */
{
printf ("Hello, World!\n");
}
Not exactly informative, although note that "void main ()" is explicitly a well-formed main, and could be:
void main ();
void main (char [] [] args);
int main ();
int main (char [] [] args);
The OOP version:
class HelloWorld
{
char [] string = "Hello, Class!\n";
static this ()
{
printf ("Hello, Program!\n");
}
static ~this ()
{
printf ("Bubye, Program!\n");
}
this ()
{
string = "Hello, World!\n";
}
~this ()
{
printf ("Goodbye, World!\n");
}
void print ()
{
printf ("%.*s", string);
}
}
void main ()
{
(new HelloWorld).print ();
}
Value classes by definition are always copied and never passed by reference. Values classes have no identity, only values, so the use of pointers or references with value classes is forbidden. If your classes have references, then they are not value classes but some bastard hybrid between value and interface classes.
C++ allows code to be executed before main() is called, they're called static constructors. The problem is, as you pointed out, there is no specified order in which libraries (modules in D) get their static constructors run. In D, however, the order in which they (the module initializers) is called is determined by how the modules import each other.
Nothing. D is not a safe language; making it safe would change the language (no pointers, union restrictions), what it can do (no direct interaction with other languages), and what it can be applied to drastically.
...
The calling order of static constructors is not defined. Anyone trying to use static constructors as their only tool is going to get burned, same as with destructors. So:
class Foo
{
private bit initialised;
static void init ()
{
if (initialised)
return;
initialised = true;
}
static this ()
{
init ();
}
}
Is still a necessary construct.
Yes, on a piano it is. As on most guitars. But on a recorder flute or for example a violin, Csharp and Dflat are not the same!
I was looking at the list of features.
While it looks fine, and useful, I can't help noticing that last time we heard about D it didn't have most of these features (templates, overloading etc.) and they were claiming that the lack of these features was it's strength.
I called them ignorant swine for that at the time.
The new D looks a lot like Modula 3, a great language aiming at the same sort of niche which disappeared without a trace.
Rocky J. Squirrel
Lisp.
Now, I'm walking a semantic line here, because you can presumably do all that by writing header files, includes, classes, etc. that contain new logic within the structure of the language. But what I mean is a language that by its nature is abstracted and modular, even to the point where the syntax of, say, control structures could be modified in a module?
Lisp.
I guess the root question I'm asking is: Are there any truly novel languages out there,
Lisp.
or are they all just variations on a common theme, with shared shortcomings and much duplication of effort?
Everything else.
See what I've been reading.
This is no more of a problem for D than it is for C. With ld.so, each DLL's _init() function is called first. Under Windows, something similar is done for DllEntryPoint() or whatever.
Of course there is code called before main(). On Linux and BSD, the _start symbol is jumped to, and that sets up argc and argv, then calls main().
Wrong. You are confusing local-scoped (stack) value types with explicit memory management (malloc/free new/delete). The thing that makes life so difficult in C++ is explicit memory management -- the programmer has control over when memory is freed, and therefore, usually gets it wrong.
Look at the value type system in C# /
I love garbage collectors. However, putting undue pressure on them will reduce their performance. And memory management performance is one of the hot issues between traditional unmanaged execution (C/C++ malloc/new/etc.) and managed memory (GCs).
Value types do not complicate GC design. They are completely orthogonal to GC design -- by definition, they simply don't involve GC at all.
Again, look at value types in C# /