Log in / create account
DocForge
An Open Wiki For Software Developers

Digital Mars D

From DocForge

The Digital Mars D Programming Language,[1] usually simply referred to as D, is a relatively new object-oriented, imperative, multiparadigm system programming language written by Walter Bright of Digital Mars. D is first and foremost a re-engineering of C++, although it has been influenced by the features found in other programming languages such as Java, C#, and Eiffel. The first stable version of D, version 1.0, was released on 2 January 2007. An experimental version was released on 17 June of the same year. [2]

Contents

[edit] Availability

There are currently two main compilers capable of building D code, the Digital Mars D Compiler (DMD) itself, and the GNU D Compiler (GDC) frontend to the GNU Compiler Collection. Several other compilers exist, though they are not quite as popular. DMD has support for 32-bit Windows platforms and i686 Linux, and GDC has (tested) support for 32-bit Windows, i686 and x86_64 Linux, as well as x86_64 Apple OS X. Both compilers are freely downloadable.

D also has two system libraries, Phobos and Tango.[3] Phobos is the default library and is maintained by the language creator, Walter Bright. Phobos is similar to the C Standard Library when compared to its alternative, Tango. Tango is maintained by a community effort spearheaded by Lars Ivar Igesund, Kris Bell, and Sean Kelly. Tango is more simlar to the Java API by comparison to Phobos. Both libraries work on Windows, Linux, and OS X.

[edit] Compatibility with Other Languages

A great strength of D is its ability to link against libraries generated by other compilers, even from different languages. D can link against virtually any C library and most C++ libraries as well. This makes using D with other software, specifically proprietary libraries, much easier. Even despite this, there are still many useful and popular "ports" of other libraries and tools to D in order to make them native to D, which increases their usability.

[edit] D Language Features

Most features found in D were created from practical experience with C++, as opposed to other languages which focus more on academic goals. [4]

  • Built-in garbage collection.
  • Dynamic arrays.
  • Easy array concatenation and "slicing."
  • Associative arrays.
  • Contract programming.
  • Unit testing.
  • Compile-time function execution.
  • Templates.
  • Inline assembler.
  • Built-in variadic function arguments.
  • Extensive benchmarking tests have proven D to be approximately as fast as C++![5]

[edit] A Simple Example

The "Hello, World - Reloaded" example found on the Digital Mars D web site:

This example also demonstrates another D technology, the D Scripting language. D code can be interpreted like a shell script—though obviously at a performance penalty.

#!/usr/bin/dmd -run
/* sh style script syntax is supported */
 
/* Hello World in D
   To compile:
     dmd hello.d
   or to optimize:
     dmd -O -inline -release hello.d
*/
 
import std.stdio;
 
void main(string[] args)
{
    writefln("Hello World, Reloaded");
 
    // auto type inference and built-in foreach
    foreach (argc, argv; args)
    {
        // Object Oriented Programming
        auto cl = new CmdLin(argc, argv);
        // Improved typesafe printf
        writefln(cl.argnum, cl.suffix, " arg: %s", cl.argv);
        // Automatic or explicit memory management
        delete cl;
    }
 
    // Nested structs and classes
    struct specs
    {
        // all members automatically initialized
        int count, allocated;
    }
 
    // Nested functions can refer to outer
    // variables like args
    specs argspecs()
    {
        specs* s = new specs;
        // no need for '->'
        s.count = args.length;             // get length of array with .length
        s.allocated = typeof(args).sizeof; // built-in native type properties
        foreach (argv; args)
            s.allocated += argv.length * typeof(argv[0]).sizeof;
        return *s;
    }
 
    // built-in string and common string operations
    writefln("argc = %d, " ~ "allocated = %d",
        argspecs().count, argspecs().allocated);
}
 
class CmdLin
{
    private int _argc;
    private string _argv;
 
public:
    this(int argc, string argv) // constructor
    {
        _argc = argc;
        _argv = argv;
    }
 
    int argnum()
    {
        return _argc + 1;
    }
 
    string argv()
    {
        return _argv;
    }
 
    string suffix()
    {
        string suffix = "th";
        switch (_argc)
        {
          case 0:
            suffix = "st";
            break;
          case 1:
            suffix = "nd";
            break;
          case 2:
            suffix = "rd";
            break;
          default:
            break;
        }
        return suffix;
    }
}

Here is another example, this one demonstrating the classic "Word Count" program as it can be implemented in D.

import std.stdio;
import std.stream;
 
int main (char[][] args)
{
    int w_total;
    int l_total;
    ulong c_total;
    int[char[]] dictionary;
 
    writefln("   lines   words   bytes file");
    foreach (arg; args[1 .. args.length])
    {
        int w_cnt, l_cnt;
        bool inword;
 
        auto c_cnt = std.file.getSize(arg);
        if (c_cnt < 10_000_000)
        {
            size_t wstart;
            auto input = cast(char[])std.file.read(arg);
 
            foreach (j, c; input)
            {
                if (c == '\n')
                    ++l_cnt;
                if (c >= '0' && c <= '9')
                {
                }
                else if (c >= 'a' && c <= 'z' ||
                         c >= 'A' && c <= 'Z')
                {
                    if (!inword)
                    {
                        wstart = j;
                        inword = true;
                        ++w_cnt;
                    }
                }
                else if (inword)
                {   auto word = input[wstart .. j];
 
                    dictionary[word]++;
                    inword = false;
                }
            }
            if (inword)
            {   auto w = input[wstart .. input.length];
                dictionary[w]++;
            }
        }
        else
        {
            auto f = new BufferedFile(arg);
            char[] buf;
 
            while (!f.eof())
            {   char c;
 
                f.read(c);
                if (c == '\n')
                    ++l_cnt;
                if (c >= '0' && c <= '9')
                {
                    if (inword)
                        buf ~= c;
                }
                else if (c >= 'a' && c <= 'z' ||
                         c >= 'A' && c <= 'Z')
                {
                    if (!inword)
                    {
                        buf.length = 1;
                        buf[0] = c;
                        inword = 1;
                        ++w_cnt;
                    }
                    else
                        buf ~= c;
                }
                else if (inword)
                {
                    if (++dictionary[buf] == 1)
                        buf = null;
                    inword = 0;
                }
            }
            if (inword)
            {
                dictionary[buf]++;
            }
        }
        writefln("%8s%8s%8s %s\n", l_cnt, w_cnt, c_cnt, arg);
        l_total += l_cnt;
        w_total += w_cnt;
        c_total += c_cnt;
    }
 
    if (args.length > 2)
    {
        writefln("--------------------------------------\n%8s%8s%8s total",
            l_total, w_total, c_total);
    }
 
    writefln("--------------------------------------");
 
    foreach (word1; dictionary.keys.sort)
    {
        writefln("%3s %s", dictionary[word1], word1);
    }
    return 0;
}

This example demonstrates the Tango library's nifty console output.

/*******************************************************************************
 
        Illustrates the basic console formatting. This is different than
        the use of tango.io.Console, in that Stdout supports a variety of
        printf-style formatting, and has unicode-conversion support
 
*******************************************************************************/
 
import tango.io.Stdout;
 
void main()
{
        // no formatting
        Stdout ("hello, sweetheart \u263a").newline;
 
        // text replacement
        Stdout.formatln ("{}, {} \u263a", "hello", "sweetheart");
 
        // indexed text replacement
        Stdout.formatln ("{1}, {0} \u263a", "sweetheart", "hello");
}