The Evils Of Positional Arguments

January 16, 2009

A few days ago I found myself writing pure ansi C code, after over two years of not touching it at all. In fact, these two years consisted mostly of Python, and a little of C#, both very far from it. While coding away, trying to get re-accustumed to mallocs and frees, return values instead of exceptions and pointer arithmatic, I had to perform a memcpy. Very easy, of course, but I could not for the life of me remember how to call it. I remembered rather vividly that it had 3 arguments, named ‘dst’, ‘src’ and ‘len’, the first two being void* and the latter.. perhaps plain int? But in which order they came, I could not recall. Now, that is not so evil, of course, because a quick look at the C reference refreshed my memory (until next time). This repeated with other functions (such as memset). But only when it started to happen with my own functions, I realized how unnatural it is for me, to remember things by order and not by name. Names allow us to establish a context, to find reasoning. Also, we are (relatively) good at remembering names.

By using position as a way for transferring parameters, we are essentially calling them “one”, “two”, “three” and etc., which are still names, but are devoid of context or meaning, and are the same for every function. It is not only hard to remember the right order; we can endure it (as reality proves), but it makes our code less readable, less natural.

Also, it complicates changing existing APIs. Move an argument from its position, and you have to change the position everywhere in the code. This can easily lead to subtle bugs (consider switching dst and src, it may be very hard to find where this happened!). So if you append parameters, they must come in the end, which somtimes does not make much sense.

While all programming languages (that I know of) sin in this evil of positionality , one device takes it one step ahead: Regular expressions. Specfically, RE Substitution. Not only do you address its matches using numbers, but actually figuring out which number goes to which match can be confounding. I cannot count how many bugs this must have produced.

In conclusion:

Design your systems differently.
Let computers count. Let humans use names!