Author Archives: Michael Parker

DMD 2.085.0 and DConf 2019 News

Coinciding with news of a new release of DMD is news about DConf 2019 in London. From new GC options in DRuntime to free beers and free tours at DConf, we may as well kill two birds with one blog post!

Compiler news

The 2.085.0 release of DMD, the D reference compiler, is now ready for download. Among other things, this release sees support for 32-bit OS X removed, more support for interfacing with Objective-C, and big news on the garbage collection front. There’s also been some work on compatibility with the standard C++ library. In total, 2.085.0 represents 58 closed Bugzilla issues and the efforts of 49 contributors. See the changelog for the full details.

Interfacing with Objective-C

DMD has had limited support for binding with Objective-C for some time. This release expands that support to include classes, instance variables, and super calls.

Previously, binding with Objective-C classes required using D interfaces. No longer. Now, Objective-C classes can be declared directly as D classes. Decorate an Objective-C class with extern(Objective-C), make use of the @selector attribute on the methods, and away you go.

To better facilitate interaction between the two languages, such classes have slightly modified behavior. Any static and final methods in an extern(Objective-C) class are virtual. However, final methods still are forbidden from being overridden by subclasses. static methods are overridable.

extern (Objective-C)
class NSObject
{
    static NSObject alloc() @selector("alloc");
    NSObject init() @selector("init");
    void release() @selector("release");
}

extern (Objective-C)
class Foo : NSObject
{
    override static Foo alloc() @selector("alloc");
    override Foo init() @selector("init");

    int bar(int a) @selector("bar:")
    {
        return a;
    }
}

void main()
{
    auto foo = Foo.alloc.init;
    scope (exit) foo.release();

    assert(foo.bar(3) == 3);
}

It’s also now possible to declare instance variables in Objective-C classes and for a method in an Objective-C class to make a super call.

extern (Objective-C)
class NSObject
{
    void release() @selector("release");
}

extern (Objective-C)
class Foo : NSObject
{
    // instance variable
    int bar;

    int foo() @selector("foo")
    {
        return 3;
    }

    int getBar() @selector("getBar")
    {
        return bar;
    }
}

extern (Objective-C)
class Bar : Foo
{
    static Bar alloc() @selector("alloc");
    Bar init() @selector("init");

    override int foo() @selector("foo")
    {
        // super call
        return super.foo() + 1;
    }
}

New GC stuff

Perhaps the biggest of the GC news items is that DRuntime now ships with a precise garbage collector. This can be enabled on any executable compiled and linked against the latest DRuntime by passing the runtime option --DRT-gcopt=gc:precise. To be clear, this is not a DMD compiler option. Read the documentation on the precise GC for more info.

Another new GC configuration option controls the behavior of the GC at program termination. Currently, the GC runs a collection at termination. This is to present the opportunity to finalize any live objects still holding on to resources that might affect the system state. However, this doesn’t guarantee all objects will be finalized as roots may still exist, nor is the need for it very common, so it’s often just a waste of time. As such, a new cleanup option allows the user of a D program to specify three possible approaches to GC clean up at program termination:

  • collect: the default, current, behavior for backward compatibility
  • none: do no cleanup at all
  • finalize: unconditionally finalize all live objects

This can be passed on the command line of a program compiled and linked against DRuntime as, e.g. --DRT-gcopt=cleanup:finalize.

All DRuntime options, including the two new ones, can be set up in code rather than being passed on the command line by declaring and initializing an array of strings called rt_options. It must be both extern(C) and __gshared:

extern(C) __gshared string[] rt_options = ["gcopt=gc:precise cleanup:none"];

See the documentation on configuring the garbage collector for more GC options.

Additional GC-related enhancements include programmatic access to GC profiling statistics and a new GC registry that allows user-supplied GCs to be linked with the runtime (see the documentation for details).

Standard C++

There are two enhancements to D’s C++ interface in this release. The first is found in the new DRuntime module, core.stdcpp.new_. This provides access to the global C++ new and delete operators so that D programs can allocate from the C++ heap. The second is the new core.stdcpp.allocator module, which exposes the std::allocator<T> class of C++ as a foundation for binding to the STL container types that allocate.

DConf 2019 news

There are two interesting perks for conference goers this year.

The nightly gathering spot

We now have an “official” gathering spot. Usually at DConf, we pick an “official” hotel where the D Language Foundation folks and many attendees stay, but where a number of conference goers gather in the evenings after dinner. This year, a number of factors made it difficult to pick a reasonable spot, so we opted for something different.

There’s a cozy little pub around the corner from the venue, the Prince Arthur, that has a nice room on the second floor available for reservation. There’s a limit on how many bodies we can pack in there at once, but folks generally come and go throughout the evening anyway. Any overflow can head downstairs to the public area. We’ve got the room May 8, 9, and 10.

Additionally, we’ll be offering a couple of free rounds each night courtesy of Mercedes-Benz Research & Development North America. Free drinks in a cozy backstreet London pub sounds like a great way to pass the time!

Check out the DConf venue page for details about the Prince Arthur and how to get there.

A free tour by Joolz Guides

Julian McDonnell of Joolz Guides will be taking some DConf registrants on a guided walk May 6 and 7. If you’ve never seen his YouTube channel, we recommend it. His video guides are quirky, informative, and fun.

This is available for free to all registrants, but space is limited! When you register for DConf, you’ll receive information on how to reserve your spot. We’ve arranged to have the tours in the mid-afternoon on both days so that folks arriving in the morning will have a chance to participate. This is a walking tour that will last somewhere between 3 – 4 hours, so be sure to wear comfortable shoes.

The current plan is to start at Temple Station and end at London Bridge. We hope you join us!

Deadlines

The DConf submission deadline of March 10 is just around the corner. Now’s the time to send in your proposal for a talk, demo, panel or research report. See the DConf 2019 homepage for submission guidelines and selection criteria. And remember, speakers are eligible for reimbursement of travel and accommodation expenses.

The early-bird registration deadline of March 17 is fast approaching. Register now to take advantage of the 15% discount!

Project Highlight: Spasm

In 2014, Sebastiaan Koppe was working on a React project. The app’s target market included three-year-old mobile phones. He encountered some performance issues that, after investigating, he discovered weren’t attributable solely to the mobile platform.

It all became clear to me once I saw the flame graph. There were so many function calls! We managed to fix the performance issues by being a little smarter about updates and redraws, but the sight of that flame graph never quite left me. It made me wonder if things couldn’t be done more efficiently.

As time went on, Sebastiaan gained the insight that a UI is like a state machine.

Interacting with the UI moves you from one state to the next, but the total set of states and the rules governing the UI are all static. In fact, we require them to be static. Each time a user clicks a button, we want it to respond the same way. We want the same input validations to run each time a user submits a form.

So, if everything is static and defined up-front, why do all the javascript UI frameworks work so hard during runtime to figure out exactly what you want rendered? Would it not be more efficient to figure that out before you send the code to the browsers?

This led him to the idea of analyzing UI definitions to create an optimal UI renderer, but he was unable to act on it at the time. Then in 2018, native-language DOM frameworks targeting WebAsm, like asm-dom for C++ and Percy for Rust, came to his attention. Around the same time, the announcement of Vladimir Panteleev’s dscripten-tools introduced him to Sebastien Alaiwan’s older dscripten project. The former is an alternative build toolchain for the latter, which is an example of compiling D to asm.js via Emscripten. Here he saw an opportunity to revisit his old idea using D.

D’s static introspection gave me the tools to create render code at compile time, bypassing the need for a virtual DOM. The biggest challenge was to map existing UI declarations and patterns to plain D code in such a way that static introspection can be used to extract all of the information necessary for generating the rendering code.

One thing he really wanted to avoid was the need to embed React’s Javascript extension, JSX, in the D code, as that would require the creation of a compile-time parser. Instead, he decided to leverage the D compiler.

For the UI declarations, I ended up at a design where every HTML node is represented by a D struct and all the node’s attributes and properties are members of that struct. Combined with annotations, it gives enough information to generate optimal render code. With that, I implemented the famous todo-mvc application. The end result was quite satisfying. The actual source code was on par or shorter than most javascript implementations, the compiled code was only 60kB after gzip, and rendering various stages in the todo app took less than 2ms.

He announced his work on the D forums in September of 2018 (the live demo is still active as I write).

Unfortunately, he wasn’t satisfied with the amount of effort involved to get the end result. It required using the LLVM-based D compiler, LDC, to compile D to LLVM IR, then using Emscripten to produce asm.js, and finally using binaryen to compile that into WebAssembly. On top of that…

…you needed a patched version of LLVM to generate the asm.js, which required a patched LDC. Compiling all those dependencies takes a long time. Not anything I expect end users to willfully subject themselves to. They just want a compiler that’s easy to install and that just works.

As it happened, the 1.11.0 release of LDC in August 2018 actually had rudimentary support for WebAssembly baked in. Sebastiaan started rewriting the todo app and his Javascript glue code to use LDC’s new WebAssembly target. In doing so, he lost Emsripten’s bundled musl libc, so he switched his D code to use -betterC mode, which eliminates D’s dependency on DRuntime and, in turn, the C standard library.

With that, he had the easy-to-install-and-use package he wanted and was able to get the todo-mvc binary down to 5kb after gzip. When he announced this news in the D forums, he was led down a new path.

Someone asked about WebGL. That got me motivated to think about creating bindings to the APIs of the browser. That same night I did a search and found underrun, an entry in the 2018 js13k competition. I decided to port it to D and use it to figure out how to write bindings to WebGL and WebAudio.

He created the bindings by hand, but later he discovered WebIDL. After the underrun port was complete, he started work on using WebIDL to generate bindings.

It formed very quickly over the course of 2–3 months. The hardest part was mapping every feature of WebIDL to D, and at the same time figuring out how to move data, objects and callbacks between D and Javascript. All kinds of hard choices came up. Do I support undefined? Or optional types? Or union types? What about the “any” type? The answer is yes, all are supported.

He’s been happy with the result. D bindings to web APIs are included in Spasm and they follow the Javascript API as much as possible. A post-compile step is used to generate Javascript glue code.

It runs fairly quickly and generates only the Javascript glue code you actually need. It does that by collecting imported functions from the generated WebAssembly binary, cross-referencing those to functions to WebIDL definitions and then generating Javascript code for those.

The result of all this is Spasm, a library for developing single-page WebAssembly applications in D. The latest version is always available in the DUB repository.

I can’t wait to start working on hot module replacement with Spasm. Many Javascript frameworks provide it out-of-the box and it is really valuable when developing. Server-side rendering is also something that just wants to get written. While Spasm doesn’t need it so much to reduce page load times, it is necessary when you want to unittest HTML output or do SEO.

At the moment, his efforts are directed toward creating a set of basic material components. He’s had a hard time getting something together that works in plain D, and at one point considered abandoning the effort and working instead on a declarative UI language that compiles to D, but ultimately he persisted and will be announcing the project soon.

After the material project there are still plenty of challenges. The biggest thing I have been postponing is memory management. Right now the allocator in Spasm is a simple bump-the-pointer allocator. The memory for the WebAssembly instance in the browser is hardcoded to 16mb and when it’s full, it’s full. I could grow the memory of course, but I really need a way to reuse memory. Without help from the compiler – like Rust has – that either means manual memory management or a GC.

One way to solve the problem would be to port DRuntime to WebAssembly, something he says he’s considered “a few times” already.

At least the parts that I need. But so far the GC has always been an issue. In WebAssembly, memory is linear and starts at 0. When you combine that with an imprecise GC, suddenly everything looks like a pointer and, as a consequence, it won’t free any memory. Recently someone wrote a precise GC implementation. So that is definitely back on the table.

He’s also excited that he recently ran WebAssembly generated from D on Cloudflare workers.

The environment is different from a browser, but its the same in many ways. This is all very exciting and lots of possibilities will emerge for D. In part because you can generate WebAssembly binaries that are pretty lean and mean.

We’re pretty excited about the work Sebastiaan is doing and can’t wait to see where it goes. Keep an eye on the Dlang Newsfeed (@dlang_ng) on Twitter, or the official D Twitter feed (@D_Programming) to learn about future Spasm announcements.

DConf 2019 Early-Bird Registration Opens (and Other News)

I’ve got a few big news items for you today, the biggest being one I’ve been eagerly awaiting: early-bird registration for DConf 2019 London is now open!

Early-bird Registrations…

are now open!

We’re very fortunate, thanks to the generosity of Symmetry Investments, to be able to keep the normal registration fee to our standard $400 this year. Like last year, the early-bird discount is once again 15%, so register before March 17, 24:00 AOE, and you’ll only pay $340. Unfortunately, unlike past editions of DConf, we’re required to charge a VAT of 20% this year, so the early-bird rate with tax is $408 and the regular registration will be $480 with tax. The GBP value of the VAT is listed alongside the price on the registration page and will be updated when the average monthly exchange rate changes.

Currently, you’ll find two options for payment on the registration page: Flipcause and PayPal. Those of you who have been following the latest goings on will know that we’re using Flipcause to create donation campaigns. They also provide support to configure campaigns for events like DConf, allowing us to keep as much as possible coming into one place. In the long run, this will be more efficient for us than accepting money through other services, so if you aren’t paying with a PayPal balance for your DConf registration, we ask that you please choose the Flipcause option.

You’ll also find the DConf campaign listed in our Campaign Menu, which is accessible from the big Donate Now button in this blog’s sidebar as well as from the D Language Foundation’s donation page. In the past, we have supported Eventbrite as a payment option, but have not yet decided if we will do so this year.

Invited Keynote Speaker

I’m also happy to announce that Laeeth Isharc has accepted our invitation to be a keynote speaker at DConf 2019.

Every year, Walter and Andrei are joined by an invited keynote speaker to open each of the three presentation days of the conference. Sometimes, the speaker is from outside of the D community for a different perspective (Scott Meyers was the invited keynote speaker at DConfs 2014 and 2017, and Martin Odersky was the invited keynote speaker last year). This year, offering the invitation to Laeeth was a no-brainer.

Not only is Laeeth responsible for bringing DConf 2019 to London under the sponsorship of Symmetry Investments, he’s also an enthusiastic supporter of the D programming language. He hires D programmers, sponsors open-source D projects, initiated the Symmetry Autumn of Code (SAoC), and can be found in various forums around the internet answering questions about D. Despite all of that, he’s never spoken at a DConf. We can’t wait to hear what he has to say!

The SAoC Finalist

Three programmers started the Symmetry Autumn of Code. Each participant was to complete three milestones, each of one-month duration, and would receive $1000 upon the successful completion of each. After a final month of clean-up work (whatever was required by each project), one participant was to be selected for a final $1000 payment and a free pass to DConf 2019, including travel and lodging.

One participant was unable to continue after the first milestone. The other two—Francesco Mecca, whose project was porting Leandro Lucarella’s old D1 forking GC to DRuntime, and Francesco Galla, whose project was adding HTTP/2 support to vibe-http—were able to see the event through to the end. Both did some excellent work on their chosen projects, but only one would be selected for the final prize.

I can now announce that congratulations are in order for Francesco Galla! He’ll be receiving the final payment and the trip to DConf 2019. As it turns out, he and the other Francesco happen to be friends. They had an agreement beforehand that the finalist would use the extra $1000 to pay for the other to attend DConf. And we’ve been informed that we’ll be fortunate enough to meet both of them in London!

We’ll also be hearing from Francesco Mecca before then, as he has agreed to write about his project for this blog. Francesco Galla will either write a blog post or, depending on how the conference schedule comes together, give a presentation about his project at DConf (possibly both!). Keep an ear open for the announcements.

The New Fundraiser

The PR Manager Campaign was a tremendous success. Not only did we meet our goal well before the deadline, but Nicholas Wilson has done a great job cleaning up the pull request queues. We will continue that campaign for another quarter, starting next month.

In the meantime, we’re raising $2000 for a new server for the D Forums. There are two reasons we’ve selected this as our next target.

First, Vladimir Panteleev has been paying for the server for the D Forums (and his other D services) out of his pocket for years. It’s time we put a stop to that. The forums are a crucial part of the D programming language community and it shouldn’t be up to one person to pay the bills.

Second, the forums have been experiencing performance issues at an increasing frequency over the past several months. Among the possible solutions that Vladimir has identified to improve this state of things, moving to better hardware is a big one. If ever there was a time for the community to take over the server bills, it’s now.

So we encourage you to donate to the cause! Helping us meet our $2000 goal will cover a new server for the forums and provide a cushion for any incidental expenses. Vladimir has graciously declined to accept any money from the D Language Foundation for the work he does in actually maintaining and improving the forums, so we’d like to draw your attention to his Patreon account, where you can more broadly support the open-source work he does.

We thank Vladimir for all the time and money he’s put into this over the years, and thank you in advance for your donations!

DMD 2.084.0 Has Arrived

The D Language Foundation is pleased to present version 2.084.0 of DMD, the reference D compiler. It’s available for download at dlang.org, where you can also find the full changelog. There are a few changes and new features to be found, as usual, along with 100 closed Bugzilla issues this time around.

Finer Control Over Run-time Checks

The new compiler flag -check is a feature that grew out of DIP 1006 and some internal discussions around its content. The flag allows overriding the default behavior of six specific categories of run-time checks by specifically turning them on or off:

  • assert – assertion checks
  • bounds – bounds checks
  • inin contracts
  • invariant – class and struct invariants
  • outout contracts
  • switch – default switch cases

For example, when compiling without -release, all run-time checks are enabled by default. To disable only assertion checks:

dmd -check=assert=off foo.d

This can be further refined with the new -checkaction flag, which determines how the program will respond when an assertion, bounds, or switch check fails. There are four options: D, C, and halt.

  • D – the default D behavior, which is to throw an Error to indicate an unrecoverable condition.
  • C – behave as a C program by calling the assertion failure function in the C runtime.
  • halt – execute a halt instruction to terminate the program.

Listed in the language documentation is a fourth option: context. This causes failed checks to throw an Error to indicate an unrecoverable condition, and also print the error context. It isn’t present in this release, but is coming in DMD 2.085 (the online documentation is generated from the DMD master branch).

Save Your Mixins

One of D’s most popular and powerful features is the mixin statement, commonly referred to as string mixins to avoid confusion with template mixins. Unfortunately, given that string mixins can be composed from multiple compile-time function calls, they are also notoriously painful to debug as they grow in complexity. The new -mixin compiler option aims to do away with that pain.

Consider the following simple (contrived) example, which attempts to generate a function call with a string mixin:

import std.stdio;

void hello() { writeln("Hello!"); }

void main() {
    mixin(hello.stringof ~ "();");
}

Save as hello.d, compile with dmd hello, and you’ll see an error along these lines:

hello.d-mixin-6(6): Error: function expected before (), not hello() of type void

The error does say exactly what the problem is, but even in this simple case it may require re-reading the message a few times before working out what it’s actually saying. So let’s recompile with the -mixin flag. It requires a file name. I’ve selected mixed.txt:

dmd -mixin=mixed.txt hello.d

Now we see this output:

mixed.txt(110): Error: function expected before (), not hello() of type void

See the difference? The error now refers to a line number in a file with the name we provided, rather than a line in the autogenerated hello.d-mixin-6 to which we couldn’t refer. Open mixed.txt and navigate to line 110 to find the generated code, along with a comment at line 109:

// expansion at foo.d(6)
hello()();

And now the error is quite clear. Invoking .stringof on a function provides you with the function name including the parentheses, so there’s no need to append parentheses to the result. We can now change the example so that it will compile:

void main() {
    mixin(hello.stringof ~ ";");
}

Anyone making significant use of string mixins to generate code will undoubtedly find this feature useful. It will be particularly helpful for the maintainers of D-friendly IDEs and plugins to make the user experience more convenient.

New DUB features

DMD 2.084.0 ships with version 1.13.0 of DUB, the D build tool and package manager. It gets some new goodies with this release.

The new add command is a convenience to add dependencies to a project’s package recipe. No need to worry about the syntax and whether the recipe is written using JSON or SDLang. Simply run dub with the add command, specifying one or more dub packages, and the recipe will be modified accordingly. For example, to add the BindBC bindings for the GLFW and OpenGL C libraries:

dub add bindbc-glfw bindbc-opengl

This will add the latest version of each library. This can be restricted to a specific version by appending = to the package name along with the normal DUB syntax for version specifications. This can also be used to change the version specification of an existing dependency.

For those unfamiliar with DUB, executing dub run, or simply dub, in a directory containing a dub recipe will build a project according to the recipe and, if the project is an executable, run it once the build completes. Now, there are two new recipe directives that can be used to achieve more specialized goals. preRunCommands specifies commands to execute before the DUB target is run, and postRunCommands specifies commands to execute when the run is complete. See the DUB package recipe documentation for the JSON syntax or the SDLang syntax, under “Build Settings” in each, to see what they look like.

That’s Not All

Regarding the 100 closed Bugzilla issues, two points should be made.

First is that among many of the Pull Request merges that closed those issues, you’ll find Nicholas Wilson’s GitHub handle. Nicholas is, of course, the community member the D Language Foundation asked to serve as PR Manager, to be paid through a fundraising campaign. He’s been reviving old PRs and making sure new ones don’t go stale. This release is evidence that the initiative is paying off. And the icing on the cake is that the D community enabled us to meet our fundraising target well before our February 14th deadline. Thanks!

Second, a point relevant to the #dbugfix campaign. While I was disappointed that participation in nominating Bugzilla issues on Twitter and in the Forums dwindled to near zero, the previous nominations were not forgotten. The original goal was to fix at least two nominated issues per cycle, so several nominated bugs were never selected. However, thanks to Eduard Staniloiu and Razvan Nitu, two among that group are now closed and fixed in this release:

I’m still happy to take #dbugfix nominations. If you’ve got a Bugzilla issue that’s bugging you, tweet a link to it with #dbugfix in the text, or start a thread in the General forum with #dbugfix in the title. I’ll make a note of it and, rather than counting votes and selecting two of the top five, see if I can find someone to do something about it.

The D Blog in 2018

Another year has gone and the D Blog keeps trucking along. That means it’s time once again to look in the rearview, dig into some blog stats, and talk about plans for the coming year.

The truck did get a bit low on fuel along the way. I’m the world’s worst manager of time and, thanks to an increased workload, that impacted the blog in different ways. I also suffered a severe bout of writer’s block for several weeks. That affected not just the blog, but also my regular job and my hobby. As someone who writes every day, suddenly being unable to find any words was both unsettling and frustrating. I did eventually get through it, but with a much-reduced output level. Where once I could crank out a near-final draft of a blog post in one sitting, I found myself requiring several sessions over several days and multiple revisions.

Because of that, the total post count was down from 2017 and I didn’t meet the goals I had for 2018. But the tank has been topped off for 2019, my output level has improved, and I’m putting a higher priority on chasing contributors. If you’re writing D code and I have a means of contacting you, beware!

What Was and Could Have Been

Publishing more project highlights was a big goal in 2018, but it didn’t go that way. The year kicked off with two in short order: BSDScheme in January and The D Community Hub in February, and that was it.

This is a bigger priority for 2019. If you have a D project you’d like the world to know about, let me know! It will help me tremendously for volunteers to step forward.

In March, I wrapped up the blog’s focus on the first target of our D in Production series with a set of User Stories from Funkwerk. They agreed at DConf 2017 to participate in the series and we started it shortly thereafter.

At DConf 2018, I asked the folks from Sociomantic to be the next target and they agreed. We started the conversations, but the initial post fell victim to my writer’s block and subsequent output woes. We’ll get that going early this year. I expect to pick up the next target at DConf 2019.

The guest post story wasn’t all bad. In the first three months, most of the posts were from me. The two exceptions were Walter’s Flash-Gordon-inspired title, Vanquish Forever These Bugs That Blasted Your Kingdom, a post from the LDC developers about the release of LDC 1.8.0, and the aforementioned Funkwerk User Stories.

In the middle of the year, we had guest posts from Jared Hanson on std.variant, Kai Nacke on using D with SAP, Nick Sabalausky on alias this vs alias for clearer error messages, Jack Stouffer on continuous improvement in D, Bastiaan Veelo on how his engineering company picked up D, and Walter on how he converted make.c to D. After that, there were no contributions until Joakim’s interview with Liran Zvibel of WekaIO.

As with the project highlights, guest posts are always welcome. If you have something you’d like to contribute, let me know! Most people I contact first tell me they don’t have the time now. Some agree to do it and then ask to postpone or cancel, sometimes after sending me a rough draft. That’s perfectly understandable, and I’m not complaining. I just want to make it clear that when someone volunteers to contribute a guest post without my prompting them, I know the person is already committed to publishing the post—they contacted me! The success rate, in that case, is almost 100%. It’s quite a bit lower when I’m chasing posts.

Several of my posts in 2018 were written to announce new initiatives, like The #dbugfix Campaign, The State of D Survey, The New New DIP Process, The D Language Foundation at Open Collective, Funding code-d, and The New Fundraising Campaign. And let’s not forget the page on the Symmetry Autumn of Code, which is in the process of wrapping up. I’m keeping the focus on the blog itself in this post, but I’ll be following up in a few days with a retrospective on D at large in 2018, including some words on all of these initiatives.

More such announcements will be coming your way in 2019. I’m hoping to publish one before the end of this month. It’s highly dependent on my time-management skills, so please don’t make any high-valued bets on it.

The Stats

My favorite part. Be sure to see The D Blog in 2017 and The D Blog in 2016 for comparison if that’s your thing.

There were 39 new posts published to the D Blog in 2018. We picked up 132,754 page views from 80,708 visitors who left 92 comments.

The top five referrers:

Referrer Page Views
Hacker News 20,049
Google Search 16,484
Reddit 7,645
D Forums 5,162
Twitter 3,330

The top five countries:

Country Page Views
United States 43,496
Germany 9,699
United Kingdom 8,358
Russia 5,601
France 4,758

Note that in 2017, France sent us 3,632 views and did not make the list. Canada dropped off the list, having sent us 4,890 views in 2017 and 4,261 last year.

The top five most-clicked GitHub links:

  1. BSDScheme
  2. DLangUI
  3. Pegged Tutorial
  4. PowerNex
  5. Mecca

The top five posts of 2018:

Post Title Page Views
How an Engineering Company Chose to Migrate to D 17,539
Liran Zvibel of WekaIO on Using D to Create the World’s Fastest File System 15,159
DasBetterC: Converting make.c to D 4,144
std.variant is Everything Cool About D 3,832
Lost in Translation: Encapsulation 3,476

Finally, the top five posts of all time (as of 9:20 a.m. UTC, January 2, 2019):

Post Title Page Views
D as a Better C 20,597
How an Engineering Company Chose to Migrate to D 17,541
Liran Zvibel of WekaIO on Using D to Create the World’s Fastest File System 15,169
Faster Command Line Tools in D 13,347
Don’t Fear the Reaper 8,983

Looking Ahead

One of the goals I had in 2018 was to bring on a semi-regular contributor to help lighten my load a bit. That didn’t pan out, but I still want to get something going in 2019. If you’re interested in contributing a “column” to the D Blog once every two or three months, please get in touch. (Psst: There’s money involved.)

The invitation for guest posts and project highlights still stands. Please note that the majority of the top posts are guest posts! People who are using D in their jobs or solving hard problems with D have things to say that the non-D audience will be interested to learn. Guest posts require a commitment to an editing and revision process, but project highlights do not require any writing from you. All I need is an information dump I can massage into a post. It’s an easy contribution. Please, get in touch! (Psst: There’s money involved.)

The GC series is on temporary hold, awaiting a potential development in the language. That gives me more bandwidth for some new installments in my series on Interfacing D and C. I’m shooting for four!

A new thing I’d like to do this year is to invite people to write about their first impressions of D while they’re still fresh. I have a couple of ideas for how to go about it, but they will take time to pursue. In the meantime, if you are a relatively new D user, I invite you to contact me (aldacron@gmail.com) and talk to me about getting your experience into written form. I hope through such posts we can zero in on some major pain points and source some improvements for them while reinforcing the good parts. Blog posts are slower to fall off the radar than forum posts (Psst: There might be money involved.)

Thanks for reading the D Blog in 2018. I’m on a mission to provide more, and more interesting, content in 2019. I hope you’ll keep on reading.

Happy New Year, D Land!

DConf 2019: Shepherd’s Pie Edition

On behalf of the D Language Foundation and Symmetry Investments, I’m excited to announce that we’re heading to London for DConf 2019!

From May 8 – 11, 2019, we’ll be hosting our traditional three days of talks, capped off with the 3rd annual DConf Hackathon, in an area packed full with tech companies, known as East London Tech City. We’ve secured facilities at 99 City Road, a conference space owned and operated by Inmarsat, a global satellite communications firm. They’ve got a great setup, with equipment geared specifically toward tech conferences. Anyone sitting in the back of the room shouldn’t need to worry about reading code samples on the screen!

Image by Jack Torcellohttps://www.flickr.com/photos/stonechat/6772642995/, CC BY 3.0, Link

The venue is located in a convenient spot, right on the “Silicon Roundabout” outside the Old Street tube station. For those who intend to schedule some time for sightseeing before or after the conference, the area is a nice walk or a short tube ride from some iconic London attractions, like the Museum of London, the Tower of London (in this handy PDF showing walking times between tube stations, it’s roughly a 30 minute walk from Old Street to Tower Hill), and just a handful of stops away from all the famous places in the City of Westminster (the Transport For London tube page has several useful maps and guides).

Several hotels are located within walking distance, some of which offer discounts for conference attendees (details will be provided to registrants). Prices vary, of course, but there are some budget hotels nearby for the price conscious (like me!). We’ll update the conference venue page in the coming days with some suggestions. We have yet to select an “official” hotel for post-conference gathering, but I hope to post that on the venue page soon.

Some details remain to be worked out as we’re still deep in the planning stage. Will the Hackathon be open to the public? Will we kick it off with a talk like last time? It’s still too early to say. It’s also too soon to announce any deadlines or registration fees. I’ve been chomping at the bit just to make the announcement that we’re going to London, but I wanted to wait until we had a venue confirmed. Now that we have, and with Christmas just a few days away, I couldn’t contain myself any longer! We’ll update the conference page and make announcements in the forums as we finalize the details. Keep an eye on @D_Programming and #dconf for real-time news.

A special thanks to Laeeth Isharc and our friends at Symmetry Investments for offering to sponsor and host DConf 2019. They’re doing all the leg work to put it together and we wouldn’t be going to London without them. And to everyone in the D community, please have very safe and Happy Holidays!

Updates in D Land

As we encroach upon the end of 2018, a recent Reddit thread wishing D a happy 17th birthday reminded me how far the language has come since I first stumbled upon it in 2003. Many of the steps along the way were powered by the energy of users who had little incentive to contribute beyond personal interest. And here we are, all these years later, still moving forward.

There are a number of current and upcoming happenings that will play a role in keeping that progress going. In this post, I’d like to remind you, update you, or inform you about some of them.

The Pull Request Manager Campaign

If you haven’t heard, the D Language Foundation has hired a pull request manager, to be paid out of a pool of donations. This is our first major fundraising campaign through Flipcause. I’m happy to report that it’s going well. As I write, we’ve raised $1,864 of our $3,000 target in 66 days thanks to the kindness of 30 supporters. If you’d like to support us in this cause, click on the campaign card.

You can access our full campaign menu at any time via the “Donate Now” button in the sidebar here on the blog. A pull request has also been submitted to integrate the menu into dlang.org’s donation page. Currently, we only have two campaigns (this one and the General Fund) but any future campaigns will be accessible through those menus.

Symmetry Autumn of Code

Earlier this year, Symmetry Investments partnered with the D Language Foundation to sponsor the Symmetry Autumn of Code (SAoC). Three participants were selected to work on D-related projects over the course of four months, with milestones to mark their progress. If you haven’t heard of it or had forgotten, you can read the details on the SAoC page here at the blog.

Unfortunately, one participant was unable to continue after the first milestone. The other two, whom we have come to refer to as the two Francescos, have each successfully completed three milestones and are in the home stretch, aiming for that final payment and free trip to DConf 2019.

Francesco Mecca is working on porting an old D1 GC to modern D, and Francesco Galla’ is busy adding HTTP/2 support the vibe-http library. Both have made significant progress and are on track to a successful SAoC. Read more about their projects in my previous SAoC update.

DIP Updates

I’ve received partial feedback on a decision regarding DIP 1013 (The Deprecation Process) and expect to hear the final verdict soon. As soon as I do, I’ll move Manu’s DIP 1016 (ref T accepts r-values) into the Formal Assessment stage for Walter and Andrei to consider.

I had intended to move Razvan’s Copy Constructor DIP into Community Review by now, as that is a high priority for Walter and Andrei. However, he’s been working out some more details so it’s not quite yet ready. So as not to hold up the process any longer, I’ll be starting Community Review for one of the other DIPs in the PR queue at the end of this week. When the Copy Constructor DIP is ready, I’ll run its review in parallel.

Google Summer of Code (GSoC) 2019

At the end of last month, I announced in the forums that we’re ramping up for GSoC 2019. I seeded our Wiki page with two potential project ideas to get us started. So far, only one additional idea has been added and no one has contacted me about participating as a student or a mentor.

It’s been a while since we were last accepted into GSoC and we’d very much like to get into it this time. To do so, we need more project ideas, students to execute them, and mentors to provide guidance to the students. If you’re looking for another way to contribute to the D community, this is a great way to do so. Adding project ideas costs little beyond the time it takes to add the details to the Wiki and, if you are lacking in ideas already dying to escape the confines of your neurocranium, the time it takes to brainstorm something. Student and mentor participation is a more significant commitment, but it’s also a lot more rewarding. If you’re interested, tell me at aldacron@gmail.com.

DConf 2019

Finally, I’m happy to announce… Just kidding. I can’t announce anything yet about DConf 2019, but I hope to be able to soon. What I can say with certainty is that in 2019, DConf will be where DConf has never gone before. We’re currently working out some details with an eye toward making 2019 a big year for DConf.

I’m really excited about it and eager to let everyone know. I’ll do so as soon as I’m able. Watch this space!

The New Fundraising Campaign

On January 23, 2011, Walter announced that development of the core D projects had moved to GitHub. It’s somewhat entertaining to go through the thread and realize that it’s almost entirely about people coming to terms with using git, a reminder that there was a time when git was still relatively young and had yet to dominate the source control market.

The move to GitHub has since been cited by both Walter and Andrei as a big win, thanks to a subsequent increase in contributions. It was smooth sailing for quite some time, but eventually some grumbling began to be heard below the surface. Pull Requests (PRs) were being ignored. Reviews weren’t happening fast enough. The grumbling grew louder. There were long communication delays. PRs were sometimes closed by frustrated contributors, demotivated and unwilling to contribute further.

The oldest open PR in the DMD queue as I write is dated June 10, 2013. If we dig into it, we see that it was ultimately done in by a break in communication. The contributor was asking for more feedback, then there was silence for nine months. Six months later, when asked to rebase, the contributor no longer had time for it. A year and a half.

There are other reasons why PRs can stall, but in the end many of them have one thing in common: there’s no one pushing all parties involved toward a resolution. There’s no one following up every few days to make sure communication hasn’t broken down, or that any action that must be taken is followed through. Everyone involved in maintaining the PR queue has other roles and responsibilities both inside and outside of D development, but none of them have the bandwidth to devote to regular PR management.

We have had people step up and try to revive old PRs. We have seen some of them closed or merged. But there are some really challenging or time-consuming PRs in the list. The one linked above, for example. The last comment is from Sebastian Wilzbach in March of this year, who points out that it will be difficult to revive because it’s based on the old C++ code base. So who has the motivation to get it done?

I promised in the forums that I would soon be launching targeted funding campaigns. This seems like an excellent place to start.

Fostering an environment that encourages more contributions benefits everyone who uses D. The pool of people in the D community who have the skill and knowledge necessary to manage those contributions is small. If they had the time, we wouldn’t have this problem. A community effort to compensate one of them to make more time for it seems a just cause.

The D Language Foundation is asking the community as a whole to contribute to a fund to pay a part-time PR manager $1,000 per month for a period of three months, from November 15 to February 14. The manager will be paid the full amount after February 14, in one lump sum. At that time, we’ll evaluate our progress and decide whether to proceed with another three-month campaign.

We’ve already roped someone in who’s willing to do the job. Nicholas Wilson has been rummaging around the PR queue lately, trying to get merged those he has an immediate interest in. He’s also shown an interest in improving the D development process as a whole. That, and the fact that he said yes, makes him an ideal candidate for the role.

He’ll have two primary goals: preventing active PRs from becoming stale, and reviving PRs that have gone dormant. He’ll also be looking into open Bugzilla issues when he’s got some time to fill. He’ll have the weight of the Foundation behind his finger when he pokes it in the shoulder of anyone who is being unresponsive (and that includes everyone on the core team). Where he is unable to merge a PR himself, he’ll contact the people he needs to make it happen.

Click on the campaign card below and you’ll be taken to the campaign page. Our target is $3,000 by February, 14. If we exceed that goal, the overage will go toward the next three-month cycle should we continue. If we decide not to continue, overage will go to the General Fund.

Note that there are options for recurring donations that go beyond the campaign period. All donations through any campaign we launch through Flipcause go to the D Language Foundation’s account. In other words, they aren’t tied specifically to a single campaign. If you choose to initiate a recurring donation through any of our campaigns, you’ll be helping us meet our goal for that campaign and, once the campaign ends, your donations will go toward our general fund. If you do set up a monthly or quarterly donation, leave a note if you want to continue putting it toward paying the PR manager and we’ll credit it toward future PR manager campaigns.

When you’re viewing the blog on a desktop system, you’ll be able to see all of our active campaigns by clicking on the Donate Now button that I’ve added to the sidebar. Of course, the other donation options that have always been supported are still available from the donation page, accessible through the menu bar throughout dlang.org.

Thanks to Nicholas for agreeing to take on this job, and thanks in advance to everyone who supports us in getting it done!

Lost in Translation: Encapsulation

I first learned programming in BASIC. Outgrew it, and switched to Fortran. Amusingly, my early Fortran code looked just like BASIC. My early C code looked like Fortran. My early C++ code looked like C. – Walter Bright, the creator of D

Programming in a language is not the same as thinking in that language. A natural side effect of experience with one programming language is that we view other languages through the prism of its features and idioms. Languages in the same family may look and feel similar, but there are guaranteed to be subtle differences that, when not accounted for, can lead to compiler errors, bugs, and missed opportunities. Even when good docs, books, and other materials are available, most misunderstandings are only going to be solved through trial-and-error.

D programmers come from a variety of programming backgrounds, C-family languages perhaps being the most common among them. Understanding the differences and how familiar features are tailored to D can open the door to more possibilities for organizing a code base, and designing and implementing an API. This article is the first of a few that will examine D features that can be overlooked or misunderstood by those experienced in similar languages.

We’re starting with a look at a particular feature that’s common among languages that support Object-Oriented Programming (OOP). There’s one aspect in particular of the D implementation that experienced programmers are sure they already fully understand and are often surprised to later learn they don’t.

Encapsulation

Most readers will already be familiar with the concept of encapsulation, but I want to make sure we’re on the same page. For the purpose of this article, I’m talking about encapsulation in the form of separating interface from implementation. Some people tend to think of it strictly as it relates to object-oriented programming, but it’s a concept that’s more broad than that. Consider this C code:

#include <stdio.h>
static size_t s_count;

void print_message(const char* msg) {
    puts(msg);
    s_count++;
}

size_t num_prints() { return s_count; }

In C, functions and global variables decorated with static become private to the translation unit (i.e. the source file along with any headers brought in via #include) in which they are declared. Non-static declarations are publicly accessible, usually provided in header files that lay out the public API for clients to use. Static functions and variables are used to hide implementation details from the public API.

Encapsulation in C is a minimal approach. C++ supports the same feature, but it also has anonymous namespaces that can encapsulate type definitions in addition to declarations. Like Java, C#, and other languages that support OOP, C++ also has access modifiers (alternatively known as access specifiers, protection attributes, visibility attributes) which can be applied to class and struct member declarations.

C++ supports the following three access modifiers, common among OOP languages:

  • public – accessible to the world
  • private – accessible only within the class
  • protected – accessible only within the class and its derived classes

An experienced Java programmer might raise a hand to say, “Um, excuse me. That’s not a complete definition of protected.” That’s because in Java, it looks like this:

  • protected – accessible within the class, its derived classes, and classes in the same package.

Every class in Java belongs to a package, so it makes sense to factor packages into the equation. Then there’s this:

  • package-private (not a keyword) – accessible within the class and classes in the same package.

This is the default access level in Java when no access modifier is specified. This combined with protected make packages a tool for encapsulation beyond classes in Java.

Similarly, C# has assemblies, which MSDN defines as “a collection of types and resources that forms a logical unit of functionality”. In C#, the meaning of protected is identical to that of C++, but the language has two additional forms of protection that relate to assemblies and that are analogous to Java’s protected and package-private.

  • internal – accessible within the class and classes in the same assembly.
  • protected internal – accessible within the class, its derived classes, and classes in the same assembly.

Examining encapsulation in other programming languages will continue to turn up similarities and differences. Common encapsulation idioms are generally adapted to language-specific features. The fundamental concept remains the same, but the scope and implementation vary. So it should come as no surprise that D also approaches encapsulation in its own, language-specific manner.

Modules

The foundation of D’s approach to encapsulation is the module. Consider this D version of the C snippet from above:

module mymod;

private size_t _count;

void printMessage(string msg) {
    import std.stdio : writeln;

    writeln(msg);
    _count++;
}

size_t numPrints() { return _count; }

In D, access modifiers can apply to module-scope declarations, not just class and struct members. _count is private, meaning it is not visible outside of the module. printMessage and numPrints have no access modifiers; they are public by default, making them visible and accessible outside of the module. Both functions could have been annotated with the keyword public.

Note that imports in module scope are private by default, meaning the symbols in the imported modules are not visible outside the module, and local imports, as in the example, are never visible outside of their parent scope.

Alternative syntaxes are supported, giving more flexibility to the layout of a module. For example, there’s C++ style:

module mymod;

// Everything below this is private until either another
// protection attribute or the end of file is encountered.
private:
    size_t _count;

// Turn public back on
public:
    void printMessage(string msg) {
        import std.stdio : writeln;

        writeln(msg);
        _count++;
    }

    size_t numPrints() { return _count; }

And this:

module mymod;

private {
    // Everything declared within these braces is private.
    size_t _count;
}

// The functions are still public by default
void printMessage(string msg) {
    import std.stdio : writeln;

    writeln(msg);
    _count++;
}

size_t numPrints() { return _count; }

Modules can belong to packages. A package is a way to group related modules together. In practice, the source files corresponding to each module should be grouped together in the same directory on disk. Then, in the source file, each directory becomes part of the module declaration:

// mypack/amodule.d
mypack.amodule;

// mypack/subpack/anothermodule.d
mypack.subpack.anothermodule;

Note that it’s possible to have package names that don’t correspond to directories and module names that don’t correspond to files, but it’s bad practice to do so. A deep dive into packages and modules will have to wait for a future post.

mymod does not belong to a package, as no packages were included in the module declaration. Inside printMessage, the function writeln is imported from the stdio module, which belongs to the std package. Packages have no special properties in D and primarily serve as namespaces, but they are a common part of the codescape.

In addition to public and private, the package access modifier can be applied to module-scope declarations to make them visible only within modules in the same package.

Consider the following example. There are three modules in three files (only one module per file is allowed), each belonging to the same root package.

// src/rootpack/subpack1/mod2.d
module rootpack.subpack1.mod2;
import std.stdio;

package void sayHello() {
    writeln("Hello!");
}

// src/rootpack/subpack1/mod1.d
module rootpack.subpack1.mod1;
import rootpack.subpack1.mod2;

class Speaker {
    this() { sayHello(); }
}

// src/rootpack/app.d
module rootpack.app;
import rootpack.subpack1.mod1;

void main() {
    auto speaker = new Speaker;
}

Compile this with the following command line:

cd src
dmd -i rootpack/app.d

The -i switch tells the compiler to automatically compile and link imported modules (excluding those in the standard library namespaces core and std). Without it, each module would have to be passed on the command line, else they wouldn’t be compiled and linked.

The class Speaker has access to sayHello because they belong to modules that are in the same package. Now imagine we do a refactor and we decide that it could be useful to have access to sayHello throughout the rootpack package. D provides the means to make that happen by allowing the package attribute to be parameterized with the fully-qualified name (FQN) of a package. So we can change the declaration of sayHello like so:

package(rootpack) void sayHello() {
    writeln("Hello!");
}

Now all modules in rootpack and all modules in packages that descend from rootpack will have access to sayHello. Don’t overlook that last part. A parameter to the package attribute is saying that a package and all of its descendants can access this symbol. It may sound overly broad, but it isn’t.

For one thing, only a package that is a direct ancestor of the module’s parent package can be used as a parameter. Consider a module rootpack.subpack.subsub.mymod. That name contains all of the packages that are legal parameters to the package attribute in mymod.d, namely rootpack, subpack, and subsub. So we can say the following about symbols declared in mymod:

  • package – visible only to modules in the parent package of mymod, i.e. the subsub package.
  • package(subsub) – visible to modules in the subsub package and modules in all packages descending from subsub.
  • package(subpack) – visible to modules in the subpack package and modules in all packages descending from subpack.
  • package(rootpack) – visible to modules in the rootpack package and modules in all packages descending from rootpack.

This feature makes packages another tool for encapsulation, allowing symbols to be hidden from the outside world but visible and accessible in specific subtrees of a package hierarchy. In practice, there are probably few cases where expanding access to a broad range of packages in an entire subtree is desirable.

It’s common to see parameterized package protection in situations where a package exposes a common public interface and hides implementations in one or more subpackages, such as a graphics package with subpackages containing implementations for DirectX, Metal, OpenGL, and Vulkan. Here, D’s access modifiers allow for three levels of encapsulation:

  • the graphics package as a whole
  • each subpackage containing the implementations
  • individual modules in each package

Notice that I didn’t include class or struct types as a fourth level. The next section explains why.

Classes and structs

Now we come to the motivation for this article. I can’t recall ever seeing anyone come to the D forums professing surprise about package protection, but the behavior of access modifiers in classes and structs is something that pops up now and then, largely because of expectations derived from experience in other languages.

Classes and structs use the same access modifiers as modules: public, package, package(some.pack), and private. The protected attribute can only be used in classes, as inheritance is not supported for structs (nor for modules, which aren’t even objects). public, package, and package(some.pack) behave exactly as they do at the module level. The thing that surprises some people is that private also behaves the same way.

import std.stdio;

class C {
    private int x;
}

void main() {
    C c = new C();
    c.x = 10;
    writeln(c.x);
}

Run this example online

Snippets like this are posted in the forums now and again by people exploring D, accompanying a question along the lines of, “Why does this compile?” (and sometimes, “I think I’ve found a bug!”). This is an example of where experience can cloud expectations. Everyone knows what private means, so it’s not something most people bother to look up in the language docs. However, those who do would find this:

Symbols with private visibility can only be accessed from within the same module.

private in D always means private to the module. The module is the lowest level of encapsulation. It’s easy to understand why some experience an initial resistance to this, that it breaks encapsulation, but the intent behind the design is to strengthen encapsulation. It’s inspired by the C++ friend feature.

Having implemented and maintained a C++ compiler for many years, Walter understood the need for a feature like friend, but felt that it wasn’t the best way to go about it.

Being able to declare a “friend” that is somewhere in some other file runs against notions of encapsulation.

An alternative is to take a Java-like approach of one class per module, but he felt that was too restrictive.

One may desire a set of closely interrelated classes that encapsulate a concept, and those should go into a module.

So the way to view a module in D is not just as a single source file, but as a unit of encapsulation. It can contain free functions, classes, and structs, all operating on the same data declared in module scope and class scope. The public interface is still protected from changes to the private implementation inside the module. Along those same lines, protected class members are accessible not just in derived classes, but also in the module.

Sometimes though, there really is a benefit to denying access to private members in a module. The bigger a module becomes, the more of a burden it is to maintain, especially when it’s being maintained by a team. Every place a private member of a class is accessed in a module means more places to update when a change is made, thereby increasing the maintenance burden. The language provides the means to alleviate the burden in the form of the special package module.

In some cases, we don’t want to require the user to import multiple modules individually. Splitting a large module into smaller ones is one of those cases. Consider the following file tree:

-- mypack
---- mod1.d
---- mod2.d

We have two modules in a package called mypack. Let’s say that mod1.d has grown extremely large and we’re starting to worry about maintaining it. For one, we want to ensure that private members aren’t manipulated outside of class declarations with hundreds or thousands of lines in between. We want to split the module into smaller ones, but at the same time we don’t want to break user code. Currently, users can get at the module’s symbols by importing it with import mypack.mod1. We want that to continue to work. Here’s how we do it:

-- mypack
---- mod1
------ package.d
------ split1.d
------ split2.d
---- mod2.d

We’ve split mod1.d into two new modules and put them in a package named mod1. We’ve also created a special package.d file, which looks like this:

module mypack.mod1;

public import mypack.mod1.split1,
              mypack.mod1.split2;

When the compiler sees package.d, it knows to treat it specially. Users will be able to continue using import mypack.mod1 without ever caring that it’s now split into two modules in a new package. The key is the module declaration at the top of package.d. It’s telling the compiler to treat this package as the module mod1. And instead of automatically importing all modules in the package, the requirement to list them as public imports in package.d allows more freedom in implementing the package. Sometimes, you might want to require the user to explicitly import a module even when a package.d is present.

Now users will continue seeing mod1 as a single module and can continue to import it as such. Meanwhile, encapsulation is now more stringently enforced internally. Because split1 and split2 are now separate modules, they can’t touch each other’s private parts. Any part of the API that needs to be shared by both modules can be annotated with package protection. Despite the internal transformation, the public interface remains unchanged, and encapsulation is maintained.

Wrapping up

The full list of access modifiers in D can be defined as such:

  • public – accessible everywhere.
  • package – accessible to modules in the same package.
  • package(some.pack) – accessible to modules in the package some.pack and to the modules in all of its descendant packages.
  • private – accessible only in the module.
  • protected (classes only) – accessible in the module and in derived classes.

Hopefully, this article has provided you with the perspective to think in D instead of your “native” language when thinking about encapsulation in D.

Thanks to Ali Çehreli, Joakim Noah, and Nicholas Wilson for reviewing and providing feedback on this article.

DMD 2.083.0 Released

Version 2.083.0 of DMD, the D reference compiler, is ready for download. The changelog lists 47 fixes and enhancements across all components of the release package. Notable among them are some C++ compatibility enhancements and some compile-time love.

C++ compatibility

D’s support for linking to C++ binaries has been evolving and improving with nearly every release. This time, the new things aren’t very dramatic, but still very welcome to those who work with both C++ and D in the same code base.

What’s my runtime?

For a while now, D has had predefined version identifiers for user code to detect the C runtime implementation at compile time. These are:

  • CRuntime_Bionic
  • CRuntime_DigitalMars
  • CRuntime_Glibc
  • CRuntime_Microsoft
  • CRuntime_Musl
  • CRuntime_UClibc

These aren’t reliable when linking against C++ code. Where the C runtime in use often depends on the system, the C++ runtime is compiler-specific. To remedy that, 2.083.0 introduces a few new predefined versions:

  • CppRuntime_Clang
  • CppRuntime_DigitalMars
  • CppRuntime_Gcc
  • CppRuntime_Microsoft
  • CppRuntime_Sun

Why so much conflict?

C++ support also gets a new syntax for declaring C++ linkage, which affects how a symbol is mangled. Consider a C++ library, MyLib, which uses the namespace mylib. The original syntax for binding a function in that namespace looks like this:

/*
 The original C++:
 namespace mylib { void cppFunc(); }
*/
// The D declaration
extern(C++, mylib) void cppFunc();

This declares that cppFunc has C++ linkage (the symbol is mangled in a manner specific to the C++ compiler) and that the symbol belongs to the C++ namespace mylib . On the D side, the function can be referred to either as cppFunc or as mylib.cppFunc.

In practice, this approach creates opportunities for conflict when a namespace is the same as a D keyword. It also has an impact on how one approaches the organization of a binding.  It’s natural to want to name the root package in D mylib, as it matches the library name and it is a D convention to name modules and packages using lowercase. In that case, extern(C++, mylib) declarations will not be compilable anywhere in the mylib package because the symbols conflict.

To alleviate the problem, an alternative syntax was proposed using strings to declare the namespaces in the linkage attribute, rather than identifiers:

/*
 The original C++:
 namespace foo { void cppFunc(); }
*/
// The D declaration
extern(C++, "foo") void cppFunc();

With this syntax, no mylib symbol is created on the D side; it is used solely for name mangling. No more conflicts with keywords, and D packages can be used to match the C++ namespaces on the D side. The old syntax isn’t going away anytime soon, though.

New compile-time things

This release provides two new built-in traits for more compile-time reflection options. Like all built-in traits, they are accessible via the __traits expression. There’s also a new pragma that lets you bring some linker options into the source code in a very specific circumstance.

Are you a zero?

isZeroInit can be used to determine if the default initializer of a given type is 0, or more specifically, it evaluates to true if all of the init value’s bits are zero. The example below uses compile-time asserts to verify the zeroness and nonzeroness of a few default init values, but I’ve saved a version that prints the results at runtime, for more immediate feedback, and can be compiled and run from the browser.

struct ImaZero {
    int x;
}

struct ImaNonZero {
    int x = 10;
}

// double.init == double.nan
static assert(!__traits(isZeroInit, double));

// int.init == 0
static assert(__traits(isZeroInit, int));

// ImaZero.init == ImaZero(0)
static assert(__traits(isZeroInit, ImaZero));

// ImaNonZeror.init == ImaZero(10)
static assert(!__traits(isZeroInit, ImaNonZero));

Computer, query target.

The second new trait is getTargetInfo, which allows compile-time queries about the target platform. The argument is a string that serves as a key, and the result is “an expression describing the requested target information”. Currently supported strings are “cppRuntimeLibrary”, “floatAbi”, and “ObjectFormat”.

The following prints all three at compile time.

pragma(msg, __traits(getTargetInfo, "cppRuntimeLibrary"));
pragma(msg, __traits(getTargetInfo, "floatAbi"));
pragma(msg, __traits(getTargetInfo, "objectFormat"));

On Windows, using the default (-m32) DigitalMars toolchain, I see this:

snn
hard
omf

With the Microsoft Build Tools (via VS 2017), compiling with -m64 and -m32mscoff, I see this:

libcmt
hard
coff

Yo! Linker! Take care of this, will ya?

D has long supported a lib pragma, allowing programmers to tell the compiler to pass a given library to the linker in source code rather than on the command line. Now, there’s a new pragma in town that let’s the programmer specify specific linker commands in source code and behaves rather differently. Meet the linkerDirective pragma:

pragma(linkerDirective, "/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2");

The behavior is specified as “Implementation Defined”. The current implementation is specced to behave like so:

  • The string literal specifies a linker directive to be embedded in the generated object file.
  • Linker directives are only supported for MS-COFF output.

Just to make sure you didn’t gloss over the first list item, look at it again. The linker directive is not passed by the compiler to the linker, but emitted to the object file. Since it is only supported for MS-COFF, that means its only a thing for folks on Windows when they are compiling with -m64 or -m32mscoff. And some say the D community doesn’t care about Windows!

Of course there’s more!

The above are just a few cherries I picked from the list. For a deeper dive, see the full changelog. And head over to the Downloads page to get the installer for your platform. It looks a lot nicer than the boring list of files linked in the changelog.