First impressions of programming in D

For the past three years, it's been a bit of a tradition here at No Time To Play to review programming languages. Too bad my last two forays didn't work out so well, driving me back to more popular options. Lately however I've been in an experimental mood again. After circling for a while, I decided to finally give D a try. Conveniently, the official website at dlang.org now has a Linux archive I could install without fuss.

D is one of those languages that set out to fix C++, only without throwing the baby out with the bathwater like Java did. For the longest time, I was dismissive of the idea, especially as D has failed to get much traction in the 17 years since it was created. Guess it's not easy to be noticed from the crowd when your competitors are standing on piles of corporate money. In retrospect, D has something better, or rather someone: Andrei Alexandrescu, a leading computer scientist of the 21st century, who also contributed much to C++. And the latter turned out very well indeed.

Unlike more fashionable alternatives, D is also very pragmatic: there's no fancy new syntax, and no attempt to reinvent error handling, objects or threads. It also doesn't provide easy cross-compilation (bummer), or any killer library nobody else has. Web app frameworks are a dime a dozen these days. So why bother?

That's a good question actually. C++ borrowed many features from D back in 2011, and is even more vendor-independent; also a lot more portable. Most other languages come with a built-in garbage collector (though few allow you to disable it entirely if you need to). And frankly, most of the time I need the expressiveness of a dynamic language much more than the performance of a compiled one.

When I do need the performance, however, D is a lot easier to understand and remember than C++. The syntax and semantics for, say, associative arrays just make sense. Iterators are a lot simpler. And the rules for modules are a breath of fresh air.

Otherwise, it's a modern programming language with built-in support for unit tests and documentation (handled by the compiler, no less), an official build tool and package manager, support for common file formats in the standard library, the works. Speaking of the standard library, it ships as source code in the package; how's that for openness!

As of this writing, I'm yet to complete a working piece of software in D, or for that matter run any benchmarks on the executables it produces. In any event, they seem average in size; stripping them saves less space than I'm used to seeing.

Last but not least, how best to make use of it is an open question. A few released games were supposedly written in D, so I guess this at least makes it on topic here. And hey, sometimes the usefulness of a new tool in the toolbox doesn't become apparent until later. So give it a chance.

A glance at the Nim programming language

I love learning new things. That's helped me stay on top of this ever-changing business we call IT. And part of the fun is how random it can be. Take the past two days: I was reading about the new zipapp module in Python; from that I moved to the setuptools suite, which in turn mentioned the reStructuredText file format. Curious to know what other tools support it, the next day I looked over a suitable list... which in turn mentioned the Nim programming language.

That made for a really busy evening.

Nim belongs to the new crop of application programming languages, like Go and Swift, that embrace garbage collection, type inference and high-level data structures to ease the burden of overworked software developers, while still providing the performance and simplified distribution that come with native code compilation. Unlike the others, however, Nim doesn't have a powerful corporation behind it, instead being a community project.

First impression: for Unix-like platforms, Nim comes in a source package with few dependencies apart from a C compiler. It builds without a hitch, in a little more time than Python 3 (not that I measured), and runs out of the box without being installed. Setting up cross-compilation for Windows was as easy as installing MingW and adding a couple of lines to a configuration file; for other operating systems I'd need a virtual machine, but oh well. The generated executables aren't too large despite the static linking, either.

On to the language proper, we're talking a Python-lookalike, with a rich syntax and many different features. It can be overwhelming at first sight, but at least everything is crystal-clear: the mark of good design. The standard library is very pragmatic, too. Typically for the current generation of languages, it includes modules to deal with CSV, JSON and various databases, plus a HTTP client and server. Notably, a simple cross-platform TUI (text user interface) is provided by default, with the promise of a GUI toolkit to be added down the road.

Other conveniences include the ability for a source file to work as either a module or a main application, fine-grained numeric types, and precise control over memory allocation. A flexible syntax makes Nim well-suited for the creation of domain-specific languages, too. The object system is simple and quirky, but metaprogramming allows for layering a traditional class system on top, much like you can in Javascript or Lua. Other familiar features like exceptions and assertions are however built-in. To help with safety, you can declare types to exclude nil values, procedure arguments are immutable by default, and variables can be as well.

In the way of tools, Nim comes with the usual suite to assist with building, documentation and package management (but not testing — that's handled by a standard library module).

As of this writing I've only played with Nim, and have no plans to use it seriously yet. But it's an option to keep in mind for the future, especially as the project is still young, so there is ample room for improvement.

A first look at the Go programming language

It's not easy to keep up with new developments in IT, especially when you work long hours, or for that matter when you no longer learn quite as easily as you used to when you were twenty. So far I was lucky to pick my technologies well: expertise in Python, HTML5 and even Java (for now) has only grown more marketable in recent years. It still felt like falling into a rut as of late, and moreover I kept stumbling across projects written in the Go programming language. After some hesitation, I decided to take the plunge, and it turns out I can still learn a new programming language in a couple of days. Go me!

And what a language it is.

Go is mostly targeted at server-side software, which makes it less relevant for games unless you're doing multiplayer. Then again, it's just as good for command-line apps (think tools), and there's a healthy choice of libraries for text-based user interfaces that don't require separate DLLs.

But what's it like, exactly?

I'd say Go is an odd duck of a language, except it's more of a platypus. Good to see programming language designers having some guts, after decades of slavishly imitating C.

In the way of downsides, the elephant in the room is of course the lack of proper exceptions, which just seems odd for a modern programming language. But look at it this way: in a compiler, is a source file with syntax errors really an exception? Is it truly unexpected? I'd say it's business as usual. Too many programmers use exceptions as a crutch, and don't even get me started about doing flow control with them. The real problem here is code becoming verbose and muddled when you have to check for errors at every step. But hey, at least exception haters can shut up now and enjoy their absence.

A smaller problem is the lack of assertions, which are really useful in the 1% of cases when you really want to assert something instead of simply checking, and other quibbles are surfacing during work: I keep forgetting to create variables instead of simply assigning to them, since it's a slightly different operator, or to propagate errors properly when I'm not dealing with them on a local level. I also keep expecting automatic semicolon insertion to bite me in the behind like it tends to in Javascript, but it hasn't happened yet, so there's that.

Upsides are more numerous and important. Fine-grained numeric types for performance tuning. A static type system that doesn't get in the way. Type inference. Dynamic typing on request via the empty interface and type assertions. (How many other languages have type assertions? Only C++, and only for templates — through various kludges.) It's not as good as generics, but it provides a lot more flexibility than critics of the language like to claim.

Moreover, the language is small and clean. It took me one afternoon to take the official tour, and another day to half-read, half-skim a textbook — Learning Go if anyone's interested. The next morning, I was able to code a "Hello, world!" correctly from memory on first try, and two days later I'm already productive. Compared to the intricacies you have to learn before even trying to use C++, for instance, or the overwhelming size of the Java standard library, this is a breath of fresh air. Most documentation does seem to omit useful details, such as multiline strings and function argument unpacking, but the reference manual has you covered.

I'd draw a conclusion, but it's too early before completing even one project successfully in Go. That said, unpleasant surprises seem unlikely at this point, and now I have another tool on my belt, one that opens up new opportunities. Take a look.

Comments

I enjoyed working with Go when I was trying it out for a project, but at the time it had a few performance characteristics that didn’t quite work out for what I was trying it for. It also lacked any reasonable way of doing multi-indexed data structures, and calling into a an external C library to provide that functionality had a huge performance gotcha in how they handled multithreaded access to the linked stack concept.

This was all back in the 1.x days (1.1, I think) and the project itself has no relevance to me anymore. I might go back and revisit Go at some point, although I don’t really work in any of the problem domains it seems suited for at the moment.

fluffy


Well, the language is at version 1.7.4 now (1.8 coming next month), so I imagine things have improved since you last tried it. But yeah, I ran into a similar problem where my choice of architecture turned out to be a poor fit for the language, resulting in overly verbose code (performance is still decent, though, if hardly anything to write home about). But that just means it’s not suitable for just any project — which is true of any programming language ever, and I already have an idea of how to make better use of it next time.

Felix