Useful Redundancy – Clearly Passing Functions Clearly, In Python

Posted on September 26, 2015

0


CC-by-SA

It has been a while since I last posted on my blog. Too busy with my girls. Regular school, plus Japanese school on Saturdays and ballet. Oh my, no much time for anything else. Then I realized I’ve been having this post on my drafts for over six months. Maybe now is the time to pull the trigger on it.

I have this habit of making some things redundant for visibility’s sake. One example is when I’m passing functions as arguments. Let’s consider the following, extremely simple functions in Python:

def foo(fn):
	return fn()

def bar():
        lst=[for n in xrange(1,10)]
	for x in lst:
		print lst
	return None

Function foo takes a parameter (hopefully a function or callable object), and returns its invocation. Function bar takes zero or more arguments, prints them to standard output, and return nothing.

Simple enough, isn’t? A simple combination of them, like this:

foo(bar)

will produce output like this:

>>>foo(bar)
1
2
3
4
5
6
7
8
9

It is a very simple function call, but that is not how I would do it. Instead, I would opt for this:

foo(fn=bar)

My convention is use ‘fn’ as the name of a parameter representing a callable object. It makes it clearer (not necessarily clear, but clearer than the opposite) what the code is passing to the function in question.

People might think “Ok, I get that.”, However, I do not stop there. Instead, in real work, I take my redundancy further:

foo(fn=lambda : bar())

I can understand people rolling their eyes asking why. It can be a cumbersome practice, specially when you are putting a whole bunch of functional code together.

Well, the reason is quite simple: it helps me avoid snafus like this:

foo(bar())

Which will result in crap like this:

>>>foo(bar())
1
2
3
4
5
6
7
8
9
Traceback (most recent call last):
  File "<input type="text" />", line 1, in 
  File "<input type="text" />", line 2, in foo
TypeError: 'NoneType' object is not callable

Function bar gets executed, which in turn prints its numbers as expected. But then it returns None, which gets passed to foo. Now foo tries to execute None which obviously is going to crap out.

Now, more eyeballs are going to roll with thinking ranging from “Well, testing or code review will catch it”, to “only stupid people make mistakes like this.”

But I think differently. I’m a big advocate of Joel Spolksy’ “Making Wrong Code Look Wrong” principle. If you have never read about that, you should.

My experience is that crap hits the fan at the 11th hour with deadlines to be met yesterday. You are tired, or whatever, and sooner or later a snafu will be produced, it will go through the cracks, and voila, someone will call you from across the globe at 3AM in the morning to troubleshoot some crap you broke 6 months ago in code you don’t remember anymore.

That’s life. That’s reality. If you ever work in competitive environments with non-trivial systems, that is an inevitability.

So practices like the one I mentioned in the examples above, though they do not eliminate snafus, they highly reduce their occurrences.

Why? Because if you make it the habit of having some formalized, structured redundancy in your code, any deviations thereof are 1) most likely errors, and 2) highly visible.

This practice is no different from the C/C++ practice of placing r-values to the left of the equality operator to avoid accidental assignment (the compiler will vomit a violent error if you, by mistake, use ‘=’ instead of ‘==’):

return 0 == (*someptr); /* will never cause an accidental assignment, compiler won't let you */

Or no different from comparing a string literal to a string variable/parameter in Java as a means to avoid accidental NPEs:

return "somestring".equals(someVar); // will never NPE.

That’s just of one the few, uber-verbose practices I use, which sometimes make people scratch their heads, but that, in the end, tends produces more reliable code. These are things that have stood the test of time in my line of work. YMMV obviously.

CC-by-SA

Advertisements
Tagged: