Thursday, November 26, 2015

How to name your variables and your kids

Story one

Some time ago, I travelled in India and one of things that amazed me was that, after I was introducing myself, everybody was asking: “What does your name mean?”

"What do you mean what does it mean, it is a name, names mean nothing", I was thinking.

Of course I was wrong. Most of the names mean something:

John means gracious
Mary means sea
Will means of course will, desire
and so forth

Even my name Dragos, comes from Drag which means loved in Romanian. My Indian friends were amazed when I was telling them that.

Looking for the meaning of a name might help choosing a name for your kids.  Even if it is nicer to find out after you've already chosen one.

*

How about the variable we use in our code?



Funny story two

One friend told me that once he was reviewing the code a colleague wrote. All the variables had cryptic names: aaa, AbC, temp, xx, Y, etc. When he asked him why did he use such strange names, the guy replied: “Because it does not even matter, the compiler is changing the names anyway.”

*

So, let’s get to the point.

First, why is the name important? That is pretty straight forward: so somebody else (and yourself in few months) can get an idea what the variable is doing without looking at the code.

So here are few rules about naming a variable or a constant:

1. Choose a rule for capitalizing and stick to it

For example in Swift, camel case is mostly used. For constants, add a k in front

var age:Int
var userAddress:String
let kMinutesPerHour = 60


2. Names are nouns

var carName, distance, timeInMinutes

but no:

var compute, decide: int

Exception, the boolean values that can be past participle

var found, crashed: Bool

3. No comment needed

The name should be such a good one that it does not require a comment with it. If it does, it is not a good name

For example, replace:

var time: Int //in seconds

with

var timeInSeconds: Int

Add a comment only when you want to add more information

//used to decide if the system should enter in sleep mode
var timeInSeconds: Int

4. Speak English

Use English words and make the names readable.

You should be able to say the variable if somebody calls you on the phone.

userName is a good one but bnkVldUser is not a good one even if you know it is a bank valued customer

5. Who are you

The name must answer to the question: “Who are you?” “I am [variable name]”

“I am homeViewController” sounds good

“I am storesViewController” sounds not


7. Be specific

userName is good.

name is not. Whose name? The same, id is a poor choice.

user is a good name only if it means a user object. But if it means the user name or user id, it is not a good choice.


8. Define the variables and constants in the most restrictive context possible

If the variable is used only in a function make it local to the function. If it is used only by a class make it private. Very rarely you need global variables.

If you need global constants. add them in the class where it makes the most sense. If it doesn't, create a separate file for constants.


9. Do not use class variables to pass information among class functions.

They should be as independent as possible

For example:

class Address {
    var street = "", city = "", country = ""
    private var fullAddress=""
    
    func generateCompactAddress() {
        self.fullAddress = "\(self.street), \(self.city), \(self.country)"
    }
    
    func getFormattedAddress() -> String {
        return "Your address is \(self.fullAddress)"
    }
}

var address = Address()
address.street = "9 Lemmon St."
address.city = "Toronto"
address.country = "Canada"

print(address.getFormattedAddress())

The code will print nothing, of course. The reason is that we forgot to call generateCompactAddress that was populating the full address.

A better solution is:

class Address {
    var street = "", city = "", country = ""
    
    func generateCompactAddress() -> String {
        return "\(self.street), \(self.city), \(self.country)"
    }
    
    func getFormattedAddress() -> String {
        return "Your address is \(generateCompactAddress())"
    }
}

var address = Address()
address.street = "9 Lemmon St."
address.city = "Toronto"
address.country = "Canada"

print(address.getFormattedAddress())

The code will now work and we got rid of a variable.

10. Shortest but no shorter than that

Make the variable name as short as possible, but no shorter than that. Also make it as long as needed.

Swift is following the tradition of Objective C that is known for long names.

So if you need to name a variable userNameBeforeEnteringLoginScreen so be it. With the modern IDE, one rarely needs to type a full name as the tool is autocompleting it for you.

11. Never use negation in boolean values

example:

try to understand this fast

var isNotLogged, isNotAdmin: Bool

isNotAdmin = true
isNotLogged = false

if !(!isNotLogged && !isNotAdmin) {
    print("Huh?!?")
}

12. Don't be creative

Do not invent your own convention. For example do not consider to add str for each string or nbr for each number when nobody does that.

13. Do not be smarty pants.

While a name might look funny to you, it might not for others. You might confuse the next developer.

For example: dyingWish for a crash message ain't a good name.

Nor is

tro: Bool
g: String

1 comment:

  1. Good article, Dragos.

    'generateCompactAddress' should probably be ranmed to 'generateFullAddress', because 'fullAddress' property is assigned a value inside the function. It's a good idea to be consistent. You might also consider making it private.

    ReplyDelete