Tuesday, January 25, 2005

Another consequence of seven, plus minus two

Let's call q(method)=
+amount of arguments
+amount of temporary variables
+amount of instance variable references
+amount of global references
+1 for self
+1 if using super
+1 if the answer is not self

The function q(x) represents the amount of named distinctions referenced in a method. Logically, this amount should not exceed the amount we can hold in our heads. Therefore, for any method x, it should be that q(x) is no higher than 9, and preferably no higher than 7.

We humans don't have a lot of scratch RAM space - but it certainly doesn't show by the way we write code, er, amass spaghetti together!

Personally, I'd rather let the average person have no trouble reading code I write, so let's take q(x)<=7 for all x. It only takes some effort to get used to, but in the end you write code that is easier to maintain even for yourself.

Remember all those lovely algorithms in Knuth's The Art of Computer Programming?... well, hmpf.

4 comments:

Andrei N.Sobchuck said...

+1 for each self in the method?

Andres said...

+1 for self is to be taken just once - one of the things that you need to keep in mind when looking at a method is the receiver. Same with super.

Andrei N.Sobchuck said...

Then, after replacing direct references to instance variables with mutators, metrics will be better.
IMHO, that isn't right. So,
q('self aGetter anotherObject use: self') = 3, but not 1
The results of #aGetter and #anotherObject are implicit temporary variables.

Andres said...

Yes, metrics should be better with accessors because that is how everything should happen in Smalltalk - by sending messages.

I did not mean to capture the effect of so-called implicit temporary variables because a) their effect is constrained to a single statement as opposed to a method, and b) no name is given to these intermediate receivers.

In other words, when you read a method, it is much more important to remember given names used than anonymous receivers.