This Week in D August 2, 2015

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.


Open D Jobs

A jobs page is the D Wiki. Take a look if you're interested, and add yours if you know of one that is available!

In the community

Community announcements

See more at digitalmars.D.announce.

Significant Forum Discussions

There was a review of this week. The proposal is a significant evolution of the json code from vibe.d and is intended to be a new stdlib upgrade from the old std.json with a nicer interface. The review pointed out that the stream parser is allocation-free, but the DOM parser does allocate, but does not support allocators (because allocators are still experimental in Phobos too).

A little more work will probably be done on the module and it will likely be added to Phobos.

Stack Overflow

Jonathan M. Davis, author of std.datetime, answered a question on Stack Overflow about the rationale behind some methods and he also elaborated on the difference between SysTime and DateTime - explaining how it works with time zone and daylight saving time.

Tip of the Week

Reading dmd's error messages is the topic of our tip this week. An important practical skill when developing D code is knowing what the compiler error messages mean and how to fix them. Often, they are pretty easy to understand, but the first time you see one can be a bit confusing. Knowing the common error message patterns will help you quickly debug code.

The biggest tip when reading the error messages is to scroll all the way to the top and read the first error message. Often, the first error is the only valid one, and subsequent errors are caused by that first one. Fixing one at a time, then rerunning the compiler can save a lot of time. This is especially true in template mismatches or parse errors. The biggest exception to this general rule are undefined identifier errors or missing module errors. You can fix all those in one pass without recompiling in between. Type mismatch or "no template matches" errors are often caused by undefined identifiers though, so once you fix those typos, recompile and see if the other errors disappear before spending any more time thinking about them.

It is also helpful to understand the causes of a few other common errors. For example, Error: class foo.Bar(T) is used as a type indicates that you used a template as a type - in other words, you forgot to instantiate it with arguments in a declaration:

   class Bar(T) { }
   Bar b = new Bar(); // error, Bar is used as a type
   Bar!int b = new Bar!int(); // this is what you should do (with the correct arguments to the template, of course)

If the compiler complains that no overload matches and the two method signatures look identical, double check the constness of the object and the method. It is easy to forget a const somewhere.

"No matching template found for..." errors might be caused by a simple typo in a lambda. Be sure to check the first error message, which might be obscured by several lines of template errors! The first line is probably something simple.

not an lvalue typically means you tried to pass a function's return value to a function expecting ref, such as std.conv.parse. If you can change the function you are calling, making it auto ref might help. Otherwise, you can try a non-ref overload (for example, in the place of std.conv.parse), or put the return value in an intermediate:

	takes_ref(your_function()); // error, your_function is not an lvalue
	auto tmp = your_function(); // use an intermediate...
	takes_ref(tmp); // and now this works

If using a std.algorithm function and it complains about no matching template, you will want to check your lambda signature and custom range definitions. After writing a range, put static assert(isInputRange!YourType); under it. Also use static assert to check other features you intended to implement, like isForwardRange or hasLength. Now, the compiler will double-check this for you at the declaration point, making errors much easier to find.

Tip: also write unit tests for your templates, trying to instantiate them with various types of input. You don't even need to run the tests themselves, just make sure they compile to ensure your code doesn't blow up unexpectedly with different sets of arguments.

A mistake I make a lot is trying to call std.algorithm.sort with a lambda that returns an int, like cmp on strings. This won't work - the lambda needs to return bool instead. So try (a, b) => cmp(a,b) < 0 instead of cmp(a,b), for example. (This specific example is unnecessary by the way, as sort does that comparison by default with strings.)

The error given is just static assert, invalid predicate passed to sort, but the cause is often a wrong return value or something similar. Knowing this can save a lot of frustration in trying to figure it out.

Library writers, also try to make your code return helpful error messages. If you trigger a failing static assert, make sure the message includes why as best you can, perhaps even using reflection to dig into details. The time it takes for you to make these messages will be much appreciated by your users! A good error message at compile time can save hours of debugging.

Users, remember, imperfect error messages could be better... but if you get to know what they are really saying, the benefit is still pretty significant. When you see a confusing error message, take note of what cause it so if it happens again, you can handle it that much faster next time.

Finally, if you are writing a tutorial, don't neglect common errors the user might face while experimenting with your lessons! A student who can't read compile errors will have a hard time when they try branch out on their own.

Learn more about D

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