This Week in D April 6, 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.

Statistics

Major Changes

Remove deprecated clear method is a small change, but a positive one - this method was in the global scope of all modules and had a common name, causing a lot of confusion. The replacement method is called destroy and has been preferred for several months.

GC API profiling was also merged, another step toward making a better garbage collector in D.

In the community

Community announcements

See more at digitalmars.D.announce.

Significant Forum Discussions

See more at forum.dlang.org and keep up with community blogs at Planet D.

Tip of the week

Don’t do by hand what the computer will do for you. Submitted by Steven Schveighoffer

I have a D utility that processes log data from a controller. This utility accumulates runtime based on a 10 second interval log and outputs what percentage of the time certain things were turned on. The output is in tab-separated format, so excel users can read it.

Recently, I’ve had to update this utility to take into account new columns, and also to handle timestamps that go backwards (yeah, the real world’s not perfect). In my code, I have a line that looks like this:

immutable header = "TIME\tDELTA\tMISS\t … \tDHERR"; 
target.writeln(header); 

With about 40 columns.

Each line is output to show the latest timestamp, and the data for each column that accumulated between this and the previous timestamp. In order to establish the “initial” timestamp where no data has been recorded yet, I output a line that just has the time and dashes for each of the data points. The code looked like this:

// print a line with no data to show initial time stamp
target.printDate(lastTimeStamp);
// print tab separated dashes
target.writeln("\t-\t-\t-\t- ... \t-");

So adding new columns, I now had to add an appropriate number of "\t-" to this output. In this update, I also decided to print one of these whenever the log “restarts”, or the timestamps go backwards in time (usually due to the original timestamp not being correct, or the person actually changing the time on the controller), so now I would have multiple lines like this to maintain. How annoying.

Of course, being a lazy programmer, I decided to have the computer figure out how to output that set of dashes for me. First we count the number of fields in the header (done at the beginning):

immutable nfields = header.count('\t'); 

count comes from std.algorithm. Now, we need to output nfields dashes. We can use a loop, but there is a more elegant way — have the library build the string.Using ranges, we don’t even have to construct the string in memory, we can construct it lazily (yes, the library is lazy too!):

target.writeln(cycle("\t-").take(2 * nfields)); 

std.range.cycle creates a range that repeats a forward range infinitely, and std.range.take limits a large or infinite range to a finite number of elements (the multiply by 2 is because it is not aware of the original string’s length). Super-win, now I only ever have to update the original column string.

Little things like this are what make me love D.

Other users have suggested using std.range.repeat and std.range.joiner to a similar effect. This has the benefit of not having to literal in the repeated string’s length to ‘take’:

target.writeln(repeat("\t-", nfields).joiner); 

Find more D tips at the D idioms list or buy my D Cookbook for a more in-depth examination of many D tricks.

If you'd like to submit a tip, email me.

Upcoming events

Learn more about D

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