This Week in D: Tip of the Week Index

2016-aug-07.html

There is a hidden magical variable in druntime called rt_trapExceptions that you can set to false to cause uncaught exceptions to abort the program. But, since this is checked before any of your code is run (including static constructors!), you need to declare your own C main to set it:

oct-04.html

This week's tip was written by Rikki Cattermole:

Interfaces: D headers and separating concerns of implementation

dec-20.html

What are out params and how do they differ from ref params?

Think of out params as being additional return values rather than as arguments in the traditional sense and you should be ok.

2016-mar-20.html

The D exception class hierarchy does not start with Exception. The base class is actually Throwable, with two child classes: Exception and Error. Why is this?

Subclsses of Exception are meant to signify a recoverable runtime problem. A function throws an exception when it cannot complete the operation you asked it to do, but has reason to believe that a solution may exist further up the call chain, that the rest of the program is still able to function normally. For example, a file copy function may throw a subclass of Exception when the filesystem prohibits the copy. The calling function may reasonably try again and expect success later. The programmer did nothing wrong, the execution environment just wasn't able to comply at this time. The fact that the function may throw is part of its public interface.

2016-mar-06.html

This week, I want to talk about struct subtyping and how it can work as a kind of named arguments.

My simpledisplay.d has an experimental text component which, while being far from finished, already has a single function which can do a number of things like change color, add text, or change text style attributes:

sep-27.html

This week, I want to talk about using UDAs and private implementations to generate modified public functions.

UDAs (user-defined attributes) in D can only attach data to a declaration. They cannot transform code on their own. Thus, you need to use some kind of annotated input to generate the modified output. Sometimes, the generated output is is a class which is used through a static interface, or network implementation code for remote procedure calls. These are fairly straightforward because you don't need to call the generated code directly - you can use the ordinary interface and perhaps a factory function.

2016-sep-11.html

Never name anything init. The language will allow it, but you'll get random breakage that is a pain to debug unless you have some idea where to look.

All types in D have a built in property called init that returns the initial value for it. However, this is not a keyword so there is nothing preventing you from defining your own member with the name... which breaks all the code that expects item.init to return the built in value. Among the things that make this assumption is std.range.. which is used heavily throughout Phobos.

jul-19.html

This week, I was asked a question about alias this and constructors. I will reproduce my answer here as it may be of general interest: just how does alias this work? What is the rule on constructing structs inside classes?

Is there any reason why implicit conversion from Foo to Thing is permitted in a regular method but not in a constructor?

2016-nov-06.html

D allows trailing commas in most places where it needs a comma separated list, including arrays and function definitions:

dec-06.html

D has an excellent feature called bounds checking. Arrays and slices know their own length, so trying to access an index before or after the valid area of the array will throw a RangeError, protecting you from memory corruption problems.

Bounds checking is useful for safety, correctness, and debugging, but in tight loops, it can be a performance hit. As such, the compiler has an option to disable it: -boundscheck=[on|safeonly|off] bounds checks on, in @safe only, or off.

2016-jun-19.html

I did some minor changes to my png.d this week that caused a major reduction in memory usage: changing temporary allocations to reuse a manual buffer and free it when I'm done with it.

Another part was transitioning away from std.zlib and using the C interface, etc.c.zlib instead. std.zlib (which has been mentioned before in these tips) allocates a lot of temporaries without cleaning up after them.

2016-aug-28.html

Today's tip is courtesy of Richard Andrew Cattermole on the topic of bindable events.

So you want to have bindable events for your program, what do you do? Well naturally of course you jump into delegates and maybe a getter and setter for it as well. Or how about going the Java way with a heavy OOP approach? Well all of these are generally hard to work with and generally require manual registration processes with a side of boiler plate for the end user.

2016-nov-13.html

This week's tip comes from p0nce's D idioms page and is on assuming @nogc.

One of the problems with using @nogc in practice is that a lot of functions that could be annotated with it aren't. (I have argued before that I feel this is a major design flaw in @nogc and I don't expect the situation to change much, but today we're talking about moving forward with the status quo regardless.) Unlike @safe which has @trusted to let you escape, @nogc has no middle ground.

2016-feb-21.html

Following up on last week, I want to talk about minimizing string mixins.

I've noticed a trend among D programmers: we have a bad habit of reaching for string mixins (and, perhaps, other generic tools..) when we don't strictly need them. It is true that string mixins can do just about anything, but as we learned in Star Trek VI, let us redefine progress to be that just because we can do a thing, it does not necessarily follow that we must do that thing.

2016-sep-18.html

This week's tip is courtesy of ketmar, writing about an event system. The following his his writing:

This is simple "event bus" system, which works somewhat similar to "signals" concept, but is slightly easier to use.

2017-may-21.html

Contributed by ketmar.

Emulating synchronized(obj) call.

2016-jan-10.html

This week's tip is not D specific, but one I feel is important: when writing tests, make sure you cover the edge cases.

The main metric I see people talk about with testing, especially in D with its built-in code coverage analyzer via dmd -cov, is the percentage of code lines covered by tests. However, I feel the percentage of the problem domain covered is more important... and harder to automatically measure.

2016-mar-27.html

A lot of people ask me if there's a way to get a stack trace while running. This is an updated version of the code from the appendix in my book to show just the most relevant lines. It returns a string which you can print out using your favorite functions.

2016-oct-02.html

This week's tip is an old one, about member function pointers, by Walter Bright.

The tip is here: Member Function Pointers in D, and summarized, it suggests:

2016-sep-04.html

This week's tip actually comes from Walter Bright himself: you can use identity template specializations with constraints to make a generic fallback.

nov-22.html

A lot of people ask me for metaprogramming debugging tips. My biggest tip is to just remember that metaprogramming is still programming!

If you are making a code generator, make sure it runs at ordinary runtime before running it at compile time. Code with string mixins can be ugly, but it is still basically just ordinary string generation code. Inspect the generated string for correctness! Try replacing mixin(code_generation_function()) with pragma(msg, code_generation_function()) to print it at compile time, or simply use writeln or std.file.write to print it out and compile and run the program as an ordinary program with ordinary output!

2017-jan-15.html

When working with class inheritance, it is possible to call a method from a base class, even when it is overridden by a child class, by using the specific class name at the call site. Observe:

sep-13.html

If you work with a large project in D, it is possible that you will be forced to face the reality that dmd has a number of bugs. Each week, we see several bugs, usually minor but sometimes major, get fixed, but in the mean time, you don't want these bugs to interrupt your development.

As such, it is helpful to be familiar with some of the harder-to-fix bugs and techniques to work around them with minimal disruption wherever possible.

nov-15.html

Function and struct/class templates in D are often written in short form, like so:

2016-aug-21.html

This week, I wrote on Stack Overflow about auto ref returning functions, what they do and why you'd use them. Here, I'll reproduce that answer for this audience.

auto return functions' primary use case is in a template where the function body changes based on some compile time parameter. auto ref just extends that to allowing a ref return too. Behold:

2016-nov-27.html

D structs have an initializer, even if they are used for interfacing with C. This is a small blob of data called something like _Dxxstruct_name__initZ, or can be all zeroes, and is generated with the interface module.

So if you use the initializer from the interface module, but do not link it in, you get an undefined symbol.

oct-25.html

D's structs are a remarkably flexible part of the language and can enable more than you'd think at first glance. This week, I want to show you a trick I used in dom.d to beat Javascript on style.

2016-feb-14.html

This week, I want to explain away some confusion about string mixins.

A string mixin is used, typically with some string generating code, to inject some dynamic code at compile time into your program and is invoked with the mixin keyword followed by a parenthesized expression yielding a string:

2017-feb-19.html

This week's tip is from Basile.

D tooling lacks a good, reliable thing to refactor the code. However one of the most used refactoring operation, which is to rename an identifier or a type, can be done directly using the compiler.

sep-20.html

This week, I want to highlight a tip I wrote about string mixins over on Stack Overflow. The short of it is always use local names in string mixins, avoiding the use of things like T.stringof.

Please see the link for a detailed explanation and example. Also notice the example of an iffy error message in there. A common complaint about D this week has been error messages. I agree a lot of them could use work... but in the mean time, knowing them will help you make quick understanding of them.

2017-mar-12.html

Today's tip is from ketmar about avoiding false positives on the 32 bit GC implementation.

It is often handy to have a list of something in your data types. Like list of strings, or some structs. And you may need to access any list item by index, fast. The obvious choice for that is dynamic array.

2016-feb-07.html

The compiler has semi-internal names for constructors and destructors, which are normally named via the this keyword: __ctor and __dtor.

If you are trying to reference them in a context where the this keyword is not accepted, try using the __ctor or __dtor alternative names instead.

aug-02.html

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.

2017-may-28.html

I was asked on IRC this week for a technique to make a complex string mixin without exposing a helper function by name. private doesn't work, since privacy only takes effect across module boundaries, and the mixed in symbols are likely used in the same module... so how can we do it?

There's a really easy answer: use an anonymous function with mixin. The syntax looks very similar to common Javascript patterns - you must put parens around the function, as well as at the end of it to call it, like so:

2016-jan-17.html

Here's a quick debugging tip: when testing code, you can paste this line scattered throughout your code to get it to print out the last line executed:

2016-jan-03.html

A brief tip this week, but one that has eluded a lot of users I've observed: adding seconds to a DateTime or SysTime is as simple as using the + operator:

2016-apr-24.html

std.stdio is somewhat infamous for reusing its buffer: a significant potential performance enhancement (and definitely a right choice to have available, but not necessarily a good choice for the default, considering how many new users trip up on this), but also something users need to be aware of in order to .dup the buffer when needed.

Well, std.stdio is not the only place where mutable buffers cause a pitfall! std.zlib does not overwrite a buffer you pass it... but it does keep a reference to it, meaning YOU must not overwrite the buffer, or you will be liable to get an exception with the message "Data error".

2016-jan-31.html

Today, I want to write about comments. Yes, what code does should be easy to see from the name or the code itself. But why it is doing that is an entirely different story and that's where comments are uniquely useful.

Everybody knows /* add one to i */ i += 1; is useless. Even /* skip past closing character */ i += 1; is arguably best written as skipPastClosingCharacter(); or whatever.

2016-feb-28.html

This week's tip is courtesy of Mahdi Mohammadi and is How to create and use a D package.

To create a D package, you first need to have dub utility (plus D compiler, dmd). You can download pre-compiled dub binaries from here.

dec-13.html

If you need to clear an associative array, some people try to assign [] to it, and find it doesn't work. Instead, you can use = null to clear an AA.

On built-in arrays, [] and null are basically the same thing, but [] is typed T[], with T deduced automatically from context or contents, and null has a special type all to itself (which you can reference in your code with typeof(null), which you can overload on, but remember ONLY the null literal has this type). [] can implicitly convert to other array types, and thus, for example, int[] foo = []; works, but it can not convert to associated array types, so int[string] foo = []; does not work.

nov-01.html

If you see an error message in Phobos along the lines of "no matching template for...", often adding .array right before it in the range pipeline will fix the problem.

This week, I wrote up a more detailed explanation with other alternative solutions on Stack Overflow to answer this FAQ and provide some background on why it works - and doesn't work - the way it is.

2016-apr-10.html

This week, I want to talk about techniques to decouple programs and minimize dependencies in D. Five techniques come to mind:

Java-style interfaces are available if your code fits static substitution well. With interfaces, you need to define a list of methods that you depend on inside the interface. Then, you write functions that take objects that statically fulfill this interface. User code can define other object that fulfil the same interface and are thus usable by your code, without your code necessarily being aware of any particular implementation.

2016-sep-25.html

V0.5.2 of Emsi's containers library was released this week, a library which I feel should get a little more attention.

Emsi is a company which uses D in data analysis software with some performance needs. To achieve their goal, they needed a collection of data containers to work with their data efficiently and wanted flexibility on memory allocation strategies to optimize in that area.