D Day Two: Conclusion of “Future of D”

Walt and Andrei closed the second day and last formal of the conference (Saturday was more open discussion). This post is a continuation of the first day’s notes. Also note that the slides for all talks have been uploaded by Brad, and videos will appear in the future. Again, disclaimer — any errors are mine, not the speaker’s.

Jumping right into Walt and Andrei’s talk…

Object Model Improvements

  • struct ctor/dtor/opCopy/opAssign – Enable the creation of ref counting template wrappers for objects. When copying value objects: 1. member-wise copy 2. call the opCopy method (if supplied)
  • opImplicitCastTo – enable implicit casting of one user defined type to another
    struct S {
      int opImplicitCastTo() {}
      float opImplicitCastTo() {}

    A very useful feature for library designers to take a burden off library users.
    As Walt presented it, Andrei expressed some distaste for this opImplicitCastTo feature (perhaps distaste is too weak a word?). Or maybe it was one of the many other topics where Walt and Andrei sparred. Throughout the presentation, there was good-natured banter between Andrei and Walter that was fun to watch.

  • opImplicitCastFrom – enable implicit casting of objects which you don’t own the definition
    struct S {
      static S opImplicitCastFrom(F f)
  • Polysemous Values – lazy, late determination of type when intent is not clear.
    Quiz: What is the type of X?

    int i; uint u; auto x = i + u;

    Answer: there is no good answer until you see how the value is used.

  • Arrays and Slices
    Arrays will be separated into resizable Arrays and non-resizable. Resizables can be converted into a slice, but a slice can only be converted into a non-resizable. There was some concern about backwards compatibility here.
  • struct “inheritance”
    Based on C++ concepts
    How can we be sure a struct had a list of functions? Answer: if a struct inherits from an interface, the compiler will require that the struct implements all the features of the interface.
  • Immutability – still don’t like the solutions out there. There’s no consistency among languages in how to treat consting a chain of pointers/references. With D, going to take another look at giving programmers the ability to state their intent clearly.
    final – means “const” of the head
    const – means “const” of the tail
    final can be combined with const or invariant
    In Q&A, the room suggested keywords that matched Walt’s verbal word usage “head const” and “tail const” (with head/tail being context-sensitive keywords only — too common to be reserved).

Simplifying Code

  • Static Function Parameters – lets us specialize functions on static arguments
  • Order of function argument evaluation – new rule: always evaluated left to right
  • Unambiguous enum names will resolve without having to qualify the scope

Generic Programming

Unfortunately, they ran out of time and had to skip some slides in order to get to the important proposed macro functionality. They skipped to this section. See presentation for some smaller items that were missed.

  • AST Macros -
    macro foo(e) { e = 3; }

    invoking with(*q);
    will replace foo(*q) with *q = 3; (THEN it does the semantic analysis)
    C preprocessor macros are widely considered to be evil — so why introduce similar macros in D? Because they’re only similar in goal — the very different implementation solves many of the C issues. In D, the semantic analysis is done after the macro is expanded (Walt noted that a similar implementation would be possible in C, but not be possible in full C++, because C++ parsing has semantic dependencies). And then the substitution is not at the character/text level — rather it’s at the abstract syntax tree level. So rather than being a preprocessing trick, invisible to the compiler, it is better integrated — so the compiler can provide more help and information at compile time.

  • Pattern matching in macros – Macro arguments an be pattern matches analogously to template type parameters
    macro foo(e) {}  // (1)
    macro foo(e: e+1) {} // (2)
    foo(3); // matches (1)
    foo(3+1); // matches (2), e aliased to 3
    foo(x+y+1); // matches (2) -- e gets aliased to (x+y)
    foo(1+x); // matches (1) because matching predates semantic analysis
    foo(x+(3-2)); // matches (1) because matching predates constant folding

    This is one of the new pieces of functionality that potentially could help clean up the creation of domain specific languages in D.

  • Hygiene
    Symbols defined inside the macro are invisible outside. Symbols resolved inside are in the context of the expansion of the macro (not the invocation)
    Proposal is to define an unclean extension — $symbol — in the macro expands

  • string literals – 3 new syntaxes proposed
    q"(foo(xxx))" // "foo(xxx)"
    q{foo}		// "foo" has to be a sequence of D tokens 
    // (e.g. q { 67QQ} error, not a valid D token)

    And Heredoc strings

    		This is a multi-line
    		heredoc string

    Coming from the Ruby/Perl, I appreciated these block string literals. Walt noted that this was one of the few features already with an implementation in the private D branch.

  • return Storage class

Standard Library

They had no time to speak in length, but mentioned to a top feature was adding STL-style containers. No comment on Tango.

So there it is. Every one of the talks was very interactive. Perhaps because it focused on the future of the language, this one particularly so. Lots of questions interrupting each slide. So keep an eye out for the videos to be posted in upcoming weeks on Brad’s conference page. And check out Planet D for other commentary on the conference. As a D outsider, it’s great to see the unfolding of this attempt to tackle the language design challenges that have kept much of the world from moving past the known warts of C.

Post a Comment
(Never published)