Writing Good Functions

This is a subjective post on what I consider good practices for writing functions (or methods in an OO language like Java). I’m aware that functions are OO languages are technically “methods” but I’m going to use the term “function” for simplicity.

1. Atomic Functions

It started many years ago in uni when a requirement for an assignment was that our functions must not be longer than 20 lines, or else we’d lose marks. The idea was to split up the functions if they exceeded 20 lines. Yes, keeping functions as short as possible can help to reduce confusion and aids with maintenance. But the most important thing is not the length, but to have the function do as little as possible (not a bit of this and a bit of that, but one thing). I don’t think that putting an arbitrary limit on function length is particularly helpful. By the way, in a later uni project, having “learnt” from the previous assignment I split all my functions up so each was tiny – then I lost marks for having too many small functions! Well…that’s uni for you.

2. Descriptive Function Names

Not many argue that a function signature such as incIdx(v) is helpful to anyone – it’s too cryptic. But how about getProducts()? It’s better and will suffice in a compiled language such as Java where the IDE will show the return type. However in an interpreted language such as PHP, it’s not that great unless you use PHPdoc so the IDE will tell you what it expects for the return type, otherwise you have to look in the function to see what it returns.

What if you need a function that returns a product based on the parameter you pass to it? You can pass getProductBy(name) or getProductBy(price). In a language that allows for method overloading, you should make use it of. In a language without method loading, I feel it’s fine to write multiple functions like: getProductByName(name) or getProductByPrice(price). Of course don’t forget PHPDoc. Some people might write getProductBy(value, by) and do a sequence of if/else statements inside the function and use the parameter “type” to determine what to retrieve – but I think that’s unnecessarily confusing.

3. Organizing Functions

Usually I prefer to group functions by relationship first, then by alphabetical order inside of those groups. Only doing it alphabetically isn’t really helpful unless you have a photographic memory and remember the names of each function.

4. Returning Early

I actually read about this on www.debuggable.com quite a while ago. To anyone but beginner programmers this concept is so deeply ingrained, but when I was first getting into coding years back I was confused to see 2 or more returns within a function. Then I discovered how ridiculously simple it all was – when a function encounters a return, it returns the value and the function quits at that point. It returns the value obviously, but most importantly it returns control to the code that called it. You will often have multiple returns in a function, each return within a conditional, and then you will have a default return in case none of the conditions were satisfied.

3. Replacing class variables with functions

There are times when you may want to replace class variables with functions to avoid duplicating data. I consider doing this when the value of a variable is completely dependent on 1 or more other variables. For example, if air pressure is completely dependent on the variable altitude (in reality air pressure is a function of altitude and temperature), then we could write a function getAirPressure() which calculates the air pressure based on the altitude and then returns it. 

VPS Backup Epic Fail

This blog is hosted with Slicehost (soon to be Rackspace) and they have an excellent backup and restore system. I tried it just to test it out and it did a extremely fast and perfect restore. It is essentially a bare metal restore which can be done easily through the control panel. Great thing is, it’s only $5 a month for the backup service. Unfortunately that cannot be said for all web hosts…

I have a website hosted at a VPS in Australia (I don’t name the company), and I’m paying a huge premium for backups (way more than $5). I tried to upgrade Ubuntu from 8.04 LTS to 10.04 LTS and the VPS suffered a catastrophic failure. No problems I thought, I’ll just do the bare meta restore and the site will be up and running within minutes. NOT SO. This is no Slicehost. The so-called bare metal restore was totally impossible (even for the network engineers at the web host) as it was hosted on a remote service and required a remote connection to my VPS. Errr, what?? Considering that the VPS had been damaged to the point where I could not even log in as root, how exactly was a remote connection possible? To me this defeats the entire purpose of a bare metal restore!

In any case, it’s very strange that their engineers could not restore the backup by just re-provisioning the VPS and restoring the backups with the root access that they require.  Now I’m looking for another Australian VPS – I have my eyes on the iinet VPS which looks pretty good. Hopefully their backups are actually restorable!

The lesson I learnt here is to test my backups. There’s no point having one and paying for it if it turns out that you can’t do a restore. Of course I have backups of all the data on more than 1 local computer, so nothing has been lost apart for my sanity. In addition, do not depend only on RAID10 for data safety, it will only give you protection from hardware failure but offers zero protection against intentional or unintentional data corruption.