Avoiding Naming Things

I find myself agreeing with Raymond Hettinger’s notes about code style. He has a wonderful talk where he explains how to write Pythonic-code, but his comments are extremely astute across languages: https://youtu.be/wf-BqAjZb8M?t=41m36s.
One of the most important things he said in my opinion:

In all languages, should you use good variable names? Are you sure? Does the need vary from language to language?
In fact, it does. In C, I make a type declaration, a file pointer f. Then, I call a function with f in it. Is f a good variable name?
It is a perfectly decent variable name because I had a type declaration that said it’s a file pointer and that was right beside where I made the call. In other words, you have more information than the variable name: you have the declaration.
In Python, do we have type declarations? No.
So should you be a lot better about your variable names to make up for the loss of information? Yes.
In different languages we code to their strengths and weaknesses. Where there is the redundancy in C from the type declaration you don’t need to add as much information to the variable name because you have additional information.

2 Likes

Personally I find that line of reasoning entirely unconvincing.

  1. By extension of the outlined reasoning, naming becomes more important even for typed languages that support type inference because of the implied nature of the type of an entity. Developers usually welcome type inference within a typed language - but this argument essentially implies a tradeoff of an added naming burden because of the lack of proximity of the type specification.

  2. The argument ultimately conflates the notion of the type of an entity and the role of an entity. I’ve always preferred that the name of an entity identifies its role rather than simply restating its type. I’ll grant that there are some types that are so specialized that they were designed to only fit one role but even these types can be (ab)used in surprising ways.

At the other end of the spectrum are types like integer - which could be used in the role of a counter, quantity, scaled currency value, identifier, etc., where in many cases the valid range of the entity is mostly implied (though some languages have ways of specifying a derived narrowed type). But even when we have, lets say, three currencies, naming helps to differentiate each of the specialized roles that these currency values have.

f is not a perfectly decent variable name for a file pointer if there are other file pointers … several files related to input, lookup, output - each with it’s own specialized, subtly different role.

So I actually suspect a misinterpretation of the circumstances where one can get away with short names - while the type can provide some of the information there can be other peripheral information that helps out. e.g.

m = increment(n)

The name n already implies an integer (though that isn’t reliable) but the name of the function adds further evidence to what the role of n might be - though in this isolation we still don’t know if we’re counting an iteration, accumulating the quantity of widgets in a bin, or increasing the fare on a taxi meter.

m = increment(n, step)

The above example demonstrates that often the entity which is the focus of the processing is usually the one that can get away with the shortest name because:

  • Everything is about that entity
  • The role of the entity is likely identified by the name of the “package” that contains the processing that revolves around that entity, e.g. the function name.

And ultimately

increment(n)

could still be a very poor name if it’s role is actually

next_widget_id(current_id)

i.e. the fact that the next id can be generated via a simple increment is an implementation detail - what is important is that we can somehow get the id of the next widget that needs to be processed.

So the guideline is still: “effective naming matters” - regardless how hard it may be. But it’s still just a guideline. Long names aren’t necessarily effective but at the same time short names shouldn’t become an avoidance strategy for convenience (or laziness) sake.

5 Likes

In functional statically typed languages best practice definitely isn’t to have Integers or Strings - they’re IDs, PhoneNumbers, Dollars etc.

So you end up with more verbose ways of defining the inputs and outputs of your functions,

Not,

Float -> Float -> Float

But, for example,

USD -> EURUSDRate -> EUR

and, if you’re smart you can apply some constraints in the type system to such things…

So, as was said above, the language is for the programmer not the computer - and this is triple-y so with functional type systems.

Basically we are pushing some of the verbosity up into the type system and out of the logic, which leads to my next point -

This gives a convincing argument, that overly verbose code is a code smell,

It makes a good point - if you are verbosely naming things, you are more likely than not implicitly biased against abstraction and polymorphism…

Obviously it depends what type of code you are writing - but if your default is ‘verbosity’ - maybe it’s good to reflect on whether your code is often reuseable

There is no right or wrong. I love the debate, but there’s a place for everything - as with many debates, if you come down extremely on one side or the other, you better have good reasons for that : )

1 Like

You should name your types, then they are strongly enforced not only in names but also in making sure of not passing the wrong thing to the wrong place. :wink:

height -> width -> area

Or you can even use named arguments in ocaml so you have to do something like doSomething ~height:42 ~width:16 or whatever you want to name them, then you can still have it be ints for example, and do not the type declaration changes too (the name is part of the typespec, the above would not be int -> int -> int but rather height:int -> width:int -> whateverIreturn, and at compile-time it is all just a normal unwrapped integer regardless of the method you use. ^.^

Yes, precisely! This is type-driven programming. :slight_smile:
You define the types first, then just write the functions that transform types to types. :slight_smile:

2 Likes

And luckyly not an issue for us.

  • Managing state
1 Like

Nice I follow this rule for some time, now, derived from Andy Hunt’s Context Is King.

The consequence, very often is, the larger the scope of a variable the more explicit the name.

2 Likes

I’m with you— sometimes I think many of my fellow developers are allergic to keystrokes. Removing the descriptive parts of the code solely for the sake of brevity is what made Perl a write-only language.

1 Like