Yenya's World

Tue, 15 Aug 2006

Clean Code versus undef

I like to write a clean, readable code. Sometimes even to the point that I am slow to write or fix the code when I think the current code is too ugly, but I have no immediate idea on what would be the best way to fix it cleanly. Recently I've came across an interesting dilemma, which is probably a clash between two measures of a clean code:

Rule 1:
The clean code produces no warnings. The compiler usually knows about dangerous constructs of its language, and can warn the programmer appropriately. When the programmer really wants to do something weird, there is often a way to switch the warning off (such as using two nested pairs of parentheses when an assignment is to be used as a Boolean value inside the if (...) statement).
Rule 2:
The clean code is readable. And by readable, I also mean short. The longer the code is, the more the reader has to keep in a short-term memory in order to grok the code. Perl programmers usually call this principle DWIM - Do What I Mean. So the symbols should be named appropriately, the meaning of the return values should be obvious, etc.

There is an interesting problem in Perl with an undef value. The Perl interpreter usually considers undef to be something volatile which should be handled with an extreme care. So it warns of almost every attempt to use an undef value. Yet undef has a very clean mental interpretation: it is nothing. So it is natural to expect it to behave as a neutral element of the operation in question: The concatenation undef.$string should lead to $string, length(undef) should be zero, lc(undef) should remain undef, ++$new_var should return 1 for a variable with undefined value, etc.

So I am in a situation when I have to put if (defined $var) { ... } around various parts of the code, in order to disable warnings about an unitialized value. But the code is perfectly readable (and thus clean by Rule 2) even without it. Adding more code makes the readability by Rule 2 worse.

Moreover, even Perl itself is not consistent with handling undef: The above ++$new_var construct follows the DWIM principle, and produces no warning. But something like print STDERR $log_prefix, $message, "\n"; produces a run-time warning when $log_prefix is not defined. There are definitely usages of undef where Perl should complain loudly (such as calling a method of undef, calling undef as a function, etc). But I think string concatenation or other string operations (i.e. everything that can be solved by replacing undef by an empty string) should not fall to this category.

So what do you think? Should Rule 1 have precedence here? And what about your language of choice? I know, LISP is unreadable by definition :-), but what about other languages?

Section: /computers (RSS feed) | Permanent link | 14 writebacks


Yenya's World: Linux and beyond - Yenya's blog.


RSS feed

Jan "Yenya" Kasprzak

The main page of this blog



Blog roll:

alphabetically :-)