Monday, November 30, 2015

Shopping list or how to name a function parameter

- Hunny!
- Yes, hunny!
- Can you please run to the store and get few things?
- For sure, hunny! What do you need?
- I need bread, eggs, cheese, milk, apples and pears. Get 2, a dozen, a pound, 2 litres, a bag and 4 or 5!


Funny eh? This is how some language define the functions. Luckily, Objective C and Swift are different. You can use named parameters that makes the life easier.

Here are some rules for naming the parameters:

1. The names should follow all the rules a regular variable should follow:
- it should be clear what is their purpose
- can be as long as needed, but not longer than that
- use a capitalization rule (for example camel case)

See here for more details.

2. Number of parameters

The number of parameters should be as small as possible.

Uncle Bob (aka Robert C. Martin) says in his "Clean Code" book:

"The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway."

If you do require more than three parameters, then it is time to refactor and pack those parameters into their own class.

2. External versus local name

For each parameter, Swift allows an external and a local name. By default, the first external parameter is omitted and the subsequent once are the same as the local ones. See here for more details.

When to use external ones? All the times, except when you have really good reason not to.

For example, for a function that computes the maximum of two number, it is obvious what the parameters are:

func max (a:Int,_ b:Int) -> Int{
    if (a>b) {
        return a
    } else {
        return b

print(max(7, 3))

Accept the first external parameter as missing by default, only when the function makes it clear which is the first parameter:

func createFullNameForFirstName(firstName:String, lastName:String) -> String {
    return "\(lastName), \(firstName)"

print(createFullNameForFirstName("Ford", lastName: "Harrison"))

You can add the first parameter, by duplicating the name, as follows:

func createFullName(firstName firstName:String, lastName:String) -> String {
    return "\(lastName), \(firstName)"

print(createFullName(firstName:"Ford", lastName: "Harrison"))

The parameters should be named in such a way that, together with the function name, should provide all the needed information for the function usage. The developer using the function, should not need to look at the the function documentation, or worse, at the function implementation to see how to use it.

No comments:

Post a Comment