D Programming Language
Tweets by @D_Programming
Report a bug If you spot a problem with this page, click here to create a Bugzilla issue. Improve this page Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

# The D Programming Language
Modern convenience. Modeling power. Native efficiency.

DMD 2.069.2 Released
Download · Changelog Videos and Slides from DConf 2015
[your code here] Got a brief example illustrating D? Submit your code to the digitalmars.D forum specifying "[your code here]" in the title. Upon approval it will be showcased on a random schedule on D's homepage.

    #!/usr/bin/env rdmd
    // Computes average line length for standard input.
    import std.stdio;

    void main()
    {
        ulong lines = 0;
        double sumLength = 0;
        foreach (line; stdin.byLine())
        {
            ++lines;
            sumLength += line.length;
        }
        writeln("Average line length: ",
            lines ? sumLength / lines : 0);
    }

    // Round floating point numbers
    import std.algorithm,
        std.conv,
        std.functional,
        std.math,
        std.regex,
        std.stdio;

    // Transforms input into a real number,
    // rounds it, then to a string
    alias round = pipe!(to!real, lround, to!string);

    // Matches numbers that look like they need rounding
    static reFloatingPoint = ctRegex!`[0-9]+\.[0-9]+`;

    void main(string[] args)
    {
        // If arguments, process those and exit,
        // otherwise wait around for input on stdin
        if (args.length > 1)
            args[1..$].map!round.joiner(" ").writeln;
        else
            // Replace anything that looks like a real
            // number with the rounded equivalent.
            stdin.byLine(KeepTerminator.yes)
                 .map!(l => l.replaceAll!(c => c.hit.round)
                                         (reFloatingPoint))
                 .copy(stdout.lockingTextWriter());
    }

    // Sort lines
    import std.stdio;
    import std.array;
    import std.algorithm;

    void main()
    {
        stdin
            .byLine(KeepTerminator.yes)
            .map!(a => a.idup)
            .array
            .sort
            .copy(
                stdout.lockingTextWriter());
    }

    // Get your local weather report
    pragma(lib, "curl");
    import std.functional, std.json, std.net.curl,
        std.stdio, std.string;

    alias getJSON = pipe!(get, parseJSON);
    auto K2C = (float f) => f - 273.15;
    auto K2F = (float f) => f / 5 * 9 - 459.67;

    void main()
    {
        auto loc = getJSON("ipinfo.io/")["loc"]
            .str.split(",");
        auto resp = getJSON(
            "api.openweathermap.org/data/2.5/weather" ~
            "?lat=" ~ loc[0] ~ "&lon=" ~ loc[1]);

        auto city = resp["name"].str;
        auto country = resp["sys"]["country"].str;
        auto desc = resp["weather"][0]["description"].str;
        auto temp = resp["main"]["temp"].floating;

        writefln(`
            +-----------------------------------------+
            |%s|
            +-----------------------------------------+
            |  weather      |  %-23s|
            +-----------------------------------------+
            |  temperature  |  %.2f°C (%.2f°F)      |
            +-----------------------------------------+
            `.outdent,
            centerJustifier(city ~ ", " ~ country, 41),
            desc, temp.K2C, temp.K2F);
    }

    // D is like...
    pragma(lib, "curl");
    import std.functional, std.json, std.net.curl,
        std.stdio;

    alias getJSON = pipe!(get, parseJSON);

    void main()
    {
        auto json = getJSON(
            "itsthisforthat.com/api.php?json");
        writefln("So, basically D is like a %s for %s",
            json["this"].str, json["that"].str);
    }

    // RPN calculator
    import std.algorithm, std.container.array,
        std.conv, std.stdio, std.meta;

    void main()
    {
        Array!int stack;

        void binop(string op)()
        {
            stack[$ - 2] = mixin("stack[$ - 2] " ~
                                 op ~ " stack[$ - 1]");
            stack.removeBack();
            writeln(stack[$ - 1]);
        }

        void process(in char[] token)
        {
            alias Ops = AliasSeq!("+", "-", "*", "/", "%");
        Lswitch:
            switch (token)
            {
                foreach (op; Ops)
                {
            case op:
                    binop!op();
                    break Lswitch;
                }

            case "=":
                writeln(stack[$ - 1]);
                stack.removeBack();
                break;

            default:
                stack.insertBack(token.to!int);
                break;
            }
        }

        stdin.byLine.map!splitter.joiner.each!process;
    }

D is a language with C-like syntax and static typing. It pragmatically combines efficiency, control, and modeling power, with safety and programmer productivity.

### Convenience

D allows writing large code fragments without redundantly specifying types, like dynamic languages do. On the other hand, static inference deduces types and other code properties, giving the best of both the static and the dynamic worlds.

    void main()
    {
        // Define an array of numbers, double[]. Compiler recognizes the common
        // type of all initializers.
        auto arr = [ 1, 2, 3.14, 5.1, 6 ];
        // Dictionary that maps string to int, type is spelled int[string]
        auto dictionary = [ "one" : 1, "two" : 2, "three" : 3 ];
        // Calls the min function defined below
        auto x = min(arr[0], dictionary["two"]);
    }
    // Type deduction works for function results. This is important for generic
    // functions, such as min below, which works correctly for all comparable
    // types.
    auto min(T1, T2)(T1 lhs, T2 rhs)
    {
        return rhs < lhs ? rhs : lhs;
    }

Automatic memory management makes for safe, simple, and robust code. D also supports scoped resource management (aka the RAII idiom) and scope statements for deterministic transactional code that is easy to write and read.

    import std.stdio;

    class Widget { }

    void main()
    {
        // Automatically managed.
        auto w = new Widget;
        // Code is executed in any case upon scope exit.
        scope(exit) { writeln("Exiting main."); }
        // File is closed deterministically at scope's end.
        foreach (line; File("text.txt").byLine())
        {
            writeln(line);
        }
        writeln();
    }

Built-in linear and associative arrays, slices, and ranges make daily programming simple and pleasant for tasks, both small and large.

    #!/usr/bin/env rdmd
    import std.range, std.stdio;

    // Compute average line length for stdin
    void main()
    {
        ulong lines = 0, sumLength = 0;
        foreach (line; stdin.byLine())
        {
            ++lines;
            sumLength += line.length;
        }
        writeln("Average line length: ",
            lines ? cast(double) sumLength / lines : 0.0);
    }

### Power

The best paradigm is to not impose something at the expense of others. D offers classic polymorphism, value semantics, functional style, generics, generative programming, contract programming, and more—all harmoniously integrated.

    // Interfaces and classes
    interface Printable
    {
       void print(uint level)
       in { assert(level > 0); } // contract is part of the interface
    }

    // Interface implementation
    class Widget : Printable
    {
       void print(uint level)
       in{ }
       body{ }
    }

    // Single inheritance of state
    class ExtendedWidget : Widget
    {
       override void print(uint level)
       in { /* weakening precondition is okay */  }
       body
       {
           //... level may be 0 here ...
       }
    }

    // Immutable data shared across threads
    immutable string programName = "demo";
    // Mutable data is thread-local
    int perThread = 42;
    // Explicitly shared data
    shared int perApp = 5;

    // Structs have value semantics
    struct BigNum
    {
        // intercept copying
        this(this) { }
        // intercept destructor
        ~this() { }
    }

    void main()
    {
        // ...
    }

D offers an innovative approach to concurrency, featuring true immutable data, message passing, no sharing by default, and controlled mutable sharing across threads. Read more.

From simple scripts to large projects, D has the breadth to scale with any application's needs: unit testing, information hiding, refined modularity, fast compilation, precise interfaces. Read more.

### Efficiency

D compiles naturally to efficient native code.

D is designed such that most "obvious" code is fast and safe. On occasion a function might need to escape the confines of type safety for ultimate speed and control. For such rare cases D offers native pointers, type casts, access to any C function without any intervening translation, manual memory management, custom allocators and even inline assembly code.

    import core.stdc.stdlib;

    void livingDangerously()
    {
        // Access to C's malloc and free primitives
        auto buf = malloc(1024 * 1024);
        scope(exit) free(buf); // free automatically upon scope exit
        // Interprets memory as an array of floats
        auto floats = cast(float[]) buf[0 .. 1024 * 1024];
        // Even stack allocation is possible
        auto moreBuf = alloca(4096 * 100);
        //...
    }

    // Using inline asm for extra speed on x86
    uint checked_multiply(uint x, uint y)
    {
        uint result;
        version (D_InlineAsm_X86)
        {
            // Inline assembler "sees" D variables.
            asm
            {
                mov     EAX,x        ;
                mul     EAX,y        ;
                mov     result,EAX   ;
                jc      Loverflow    ;
            }
            return result;
        }
        else
        {
            result = x * y;
            if (!y || x <= uint.max / y)
               return result;
       }
    Loverflow:
       throw new Exception("multiply overflow");
    }

    void main()
    {
        // ...
    }

The @safe, @trusted, and @system function attributes allow the programmer to best decide the safety-efficiency tradeoffs of an application, and have the compiler check for consistency. Read more.

Copyright © 1999-2015 by Digital Mars ®, All Rights Reserved | Page generated by Ddoc on Thu Dec 3 01:39:37 2015