This Week in D May 29, 2016

Welcome to This Week in D! Each week, we'll summarize what's been going on in the D community and write brief advice columns to help you get the most out of the D Programming Language.

The D Programming Language is a general purpose programming language that offers modern convenience, modeling power, and native efficiency with a familiar C-style syntax.

This Week in D has an RSS feed.

This Week in D is edited by Adam D. Ruppe. Contact me with any questions, comments, or contributions.

Statistics

Major Changes

Phobos' documentation is getting some cleanup - a PR changed XREF macros to a more generic REF macro (inspired, in part, by my documentation fork at dpldocs.info). There are currently at least 11 different ways to make links in ddoc. Each one removed will make crosslinking easier for documentation authors, so this seems small, but will be a big help later on.

On the website, the D Language Foundation got a page describing it now, and a couple other pages are in the works, including a tour of D site and a D users page (not yet public).

Beta D 2.071.1-b2 was also released this week.

In the community

Boston-area D Meetup Group Created

Would you like to know more?

Community announcements

See more at the announce forum.

Notable threads

The horribly-named Our Sister thread is actually about a reference-counted string type, the thing Andrei Alexandrescu has apparently been working on.

In this thread, there is discussion on what its public API should be, the level of compatibility with built-in char[] slices and @safe guarantees, and of course, some discussion on the details of its memory management strategy.

There wasn't a whole lot of detail worked out in the thread (yet, it is still somewhat young), and people did discuss a notable topic, though tangential to the main point: if we can convert to a scope slice. I don't think that is going to happen, but the RCStr (whatever its final name may be) is coming, and this thread is the most insight we've had into its recent progress yet.

Tip of the Week

I made up a new filthy hack this week: foo => "bar" key/value literals in D! And Vladimir Panteleev, as he often does, took the raw concept and made a named args library out of it.

Read the linked post for the way it works - basically, I extract a lambda's argument name to use as the key, and use its return value as the value, co-opting that lambda syntax for the key/value hack.

But, what I want to expand a bit upon here is the process that led to it. Basically, I was working on my REST API client library, integrating it with my Javascript-style var module for easier construction of JSON requests. I wanted to create a var object with syntax like common Javascript or Ruby libraries offer.

My jsvar.d does include a JSON literal parsing function, using a json!q{} construct in D. That's a template (using the user-defined literal pattern) combined with a D token string to give a vaguely Javascript syntax... but pretty different semantics. Since the q{} string in D is just a string literal, you cannot actually interpolate runtime values into it. (Well, you could use mixin, but then the syntax moves quite a bit away from JS again)

So, it works for static data, but that's not very interesting for the REST use-case. I could, of course, simply construct the object, even wrapping it in a delegate to do inline on the function call:

   restapi.request( (ref obj) {
       obj.value = whatever;
       obj.other_value = things_work;
   });

That delegate receives an object created by the library, and being taken by ref, you can replace it wholesale or just set your keys and values on it.... but this is still slightly bulkier than Javascript, especially when nesting objects. What else can we do?

Well, C-style struct initializers, labels, and associative array literals all use colons, like a JSON object, can we use them? C struct initializers no, they only work in specific contexts (and btw, I'd like to see them removed from the language). There's no such reflection capability to get at labels and the following expressions, so they are out too.

AA literals certainly come close, they are the nearest D language construct designed for this purpose, but they are strongly typed, meaning the key must be quoted and the value must be wrapped in a var initializer. ["key" : var("bar")] rather than JS's {key: "bar"}. Not bad, but what else can we do?

A variadic template is the existing D solution to heterogeneous key/value types. To do this, you write a auto magic(T...)(T args) {} function which loops through the arguments, assuming they are key/value pairs. The result looks like:

    magic(
      "key", "value",
      "next key", 10,
    );

Again, keys must be quoted, and there must be commas between each element - D sees them as just a list of values, the language itself isn't aware that any of them are interpreted as keys.

Such works (and is used in Phobos in a few places, see std.typecons.Tuple, for example), but is still a bit syntactically clunky.

I really wanted to get a colon.... or a fat arrow, like Ruby would use... hmmm, I thought, D *does* have a fat arrow syntax: the short-form lambda.

   arg => return_expression

And D has reflection over function definitions. Oh my, I think I can hack this! And I did.

BTW, the fat arrow syntax can also take an anonymous typed argument: (int) => 4 is legal D (the parenthesis are required here though, unlike with the single argument name case). Anyone wanna hack up a new Tuple with specs like Tuple!((int) => "x", (int) => "y")? Should be possible!

I call this a filthy hack and I actually believe the traditional delegate initializer, with the object passed to it from the library to be populated, or the actual D associative array syntax are probably better to use in the real world. They will work more as expected, since they aren't abusing the syntax to mean something it wasn't intended to express (think for a moment about D scoping and variable shadowing rules and consider what happens if you used x=>x in my key/value hack....), but nevertheless, thinking outside the box like this can sometimes yield useful results.

I encourage you all to consider what D can to today before you ask for new syntax to be added - perhaps the thing you want can already be close-enough achieved by working with the existing language! Just write what you want it to look like, then consider what the D compiler would think of it... and use metaprogramming to extract what you want!

Just don't go TOO nuts. We still want our D code to be understandable by people who still have a few marbles actually still in their head, rather than lost all over the floor like me :)

Learn more about D

To learn more about D and what's happening in D: