The Unspoken Parameter
I have a difference of opinion with many of my peers. I think that the unspoken parameter is a code smell, and that it is detrimental to readability, whereas my peers don’t think so or else don’t care. My position is that a function should be self-documenting. That implies that it is explicit about its function. Modern code I see doesn’t seem to follow the same philosophy, but is rather like the old and horrible code I saw years ago.
Back in the days of basic, it worked this way:
let $a = 12; let $b = "hello" let $c = "early morning" gosub 1024 let $f = $c let $b = "goodbye" gosub 1024 print $c
Something happens at “gosub 1024″, and of course without a good label you have no idea what it is. Nor what varibles it uses as parameters, nor what variables it sets before returning. It could be doing anything. If you look carefully, you can see that the code expects $c to have been changed (probably). It also looks like maybe we expect $b to be an input that somehow changes the value returned by $c. We don’t know from this code if the routine at 1024 uses $a or $c as inputs also, and whether there
are other variables it looks at or changes. The intent of the function is totally obscured by three facts:
- The input to the function is not explicit, since the routine draws data quietly from its global environment
- The output of the function is implicit, since the routine quietly modifies varibles in its environment
- The intent of the functions is not explicit, since the identifier of the subroutine is a line number
Explicit is better than implicit, named is better than unnamed, and scoped is better than global. This is why BASIC sucked. We all abandoned it as quickly as we could. We moved to C and then to ANSI C. In ANSI C we had function prototypes and that was a major move in the right direction. OO took us even further in this good direction, and all of us old guys could write more and more explicit code.
But in Java, I see plenty of classes where methods will set values in fields (instance variables) , call some no-parameter functions that return void, and then retrieve values from the fields. The parameters could be explicit, but then the functions would be static. Static is bad (some say) so programmers are reluctant to create or call them. This is one of the ways that some Java programs suck.
An unspoken parameter list is a code smell, if not a programmer smell.
My assertion (and the reader may hate me for it) is that fully-declared functions are inherently more readable than void-returning, no-parameter member functions. Period. So join me in this: whenever you see a function call with unspoken parameters, ask the author how much they liked BASIC and then remind them that you didn’t. And fix their code so that there are no unspoken parameters and no unspoken returns.

I agree 100%
But then coming from a former Pascal/Modula 2 programmer who was dragged into C++ kicking and screaming, what do you expect?
Comment by Walter Moore — 2007-February-13 @ 01:20
So even though a method is using fields, you’d rather have the fields passed as parameters?
Comment by Michael Feathers — 2007-February-13 @ 01:50
Yes and no. I realize that I didn’t make everything clear above. Let’s try this clarification.
If we’re talking about a private function, I can certainly test it easier (passing whatever I please and getting and answer directly, instead of seeding variables in the instance, and harvesting the instance variables after). The function will explain itself much better. See if you get the same warm-n-fuzzies. I would like private functions to be essentially like static functions (not really reliant on “this”/”self”), but I want the possibility of swapping them out at test time. So I need them to be overrideable functions even though I want them to behave “self-lessly”
With a public function, the tell-don’t-ask variety, there should be the fewest possible formal arguments. The public interface needs to have minimal surface area (fewest methods with fewest parameters). It’s not very cool for an outsider to hand the object its guts.
Of course, if the public no-argument functions have to run out and harvest parameters from the environment, then it is also overreaching and will be hard to test and hard to understand. I definitely want to present this as a balancing of forces, and not an absolute.
For helper/explanatory methods and utility functions, the whole seed-and-harvest thing destroys the readability of the class. It is detrimental everywhere, but is not the greatest detriment possible and may be overridden by other concerns.
So:
however
I hope that clears up any deeply wrong misgivings I may have given before. I still think the whole seed-and-harvest thing is generally wrong, but that it could create greater wrongs if it were allowed to break encapsulation and push work out to clients of a class.
Comment by Tim — 2007-February-13 @ 03:27