
It was infinitely long – over 250 standard lines! –, had half a dozen required arguments and did everything under the sun. This is, of course, as we’ll discuss later, a bad idea, but let’s put that aside.
#THE POWER OF TEN RULES FOR DEVELOPING SAFETY CRITICAL CODE CODE#
Wrong! They very much do.Ī few months ago, I saw some code written by a mentee of mine.

It’s a little surprising to even see this – I mean, shouldn’t you do this stuff anyway? Yes, you should, except some people think that because so much of R is done in the interpreter anyway, rules do not apply to them. Know the rules and their rationale, so that you know when to break them.Use a consistent style and automated code quality tools.Aggressively manage package and version dependencies.Don’t use require() to import packages into the namespace.Refer to external functions explicitly.In God we trust, everyone else we verify.The Ten Commandments of Defensive Programming in R 1Īnd so, without further ado, here are the ten ways I implement these in my day-to-day R coding practice – and I encourage you to do so yourself. Equally, it’s legitimate to look for a parameter, then check for a configuration file if none was provided, and finally try checking the arguments with which the code was invoked before raising an error. One example is repeating a HTTP request that has timed out: there’s no need to immediately error out, because quite frankly, that sort of stuff happens. It is perfectly legitimate to handle problems.

Fail creatively: not everything needs to be a failure.Failures should be handled appropriately. For every developer, it’s a judgment call to ensure whether a particular issue would be a a debug/info item, a warning or an error (which by definition means halting execution). Fail appropriately: failure should have appropriate effects.Fail conspicuously: when something is broken, it should return a very clear error message, and give as much information as possible to help unbreak it.Fail safe: where there is a failure, your code should ensure that it relinquishes all locks and does not acquire any new ones, not write files, and so on.Fail fast: your code should ensure all criteria are met before they embark upon operations, especially if those are computationally expensive or might irreversibly affect data.Rather, the fundamental idea is to write code that fails well. The idea of defensive programming is not to write code that never fails. I have done so with an eye to users who do not come from the life critical systems community and might not have encountered defensive programming before, so some of these rules apply to all languages. So below, I have collected my top ten principles of defensive programming in R. But where R code is integrated into a pipeline, runs autonomously or is embedded into a larger analytical solution, writing code that fails well is going to be crucial. In fact, much – if not most! – R code is actually executed interactively, where small glitches don’t really matter. R, while fun and powerful, is not going to run defibrillators, nuclear power plants or spacecraft.

The topic of defensive programming in R is, admittedly, a little unusual.
