Named constants -- no such thing as "too obvious"

Ben Finney bignose-hates-spam at and-zip-does-too.com.au
Mon Jun 2 01:16:41 CEST 2003


On Fri, 30 May 2003, Irmen de Jong wrote:
> Ben Finney wrote:
>> Many programmers in many languages break the "use named constants"
>> rule, but one of the most egregious examples seems to be constants
>> for number of seconds in an hour, day, week, etc.
>> 
>> Using the numeric literal '604800' instead of 'SECS_PER_WEEK' is as
>> bad as using '3.14159265' instead of 'math.pi', for all the same
>> reasons: it's prone to hard-to-find typing errors, it's not obvious
>> to anyone unfamiliar with the value of the constant, it gives no
>> context as to why this number is being used, etc.
> 
> That's why I'm usually writing it as "60*60*24*7"
> Although giving this kind of numbers their own constant sounds
> reasonable.
> 
> But I'm not too fond of HOURS_PER_DAY and the other 'simple' ones.
> Why, it's 24, this will *never* change, *everybody* knows this,

Everyone knows that "hours per day" is 24.  But, if you see a literal 24
in code, how can you know that it means "hours per day"?  Could it not
mean "beers in a slab"?  "number of lines on the default terminal"?

Could a literal 7 in the code not also mean "colours in the rainbow"?
"number of deadly sins"?

Moreover, if you see a 24 and assume "ah, that's because it's the number
of hours in a day", what if you're wrong?

What if the code has to deal with several other "obvious" constants,
that just happen to have the value 24?  How will the reader know which
instance of 24 is HOURS_PER_DAY and which is BEERS_PER_SLAB?  If you
don't write it so, then they're guessing -- and when reading code,
especially when trying to debug it at the same time, guesswork is to be
avoided as much as possible.

Using a named constant avoids all this guesswork.

> and if your code isn't clear when you use the number 24 directly,
> I think the rest of your code has a problem, and it won't improve
> much when you're using the HOURS_PER_DAY constant instead.

In addition to all their other benefits, named constants make code
easier to read.  If you make me guess about all the "obvious" constants
in your code, it is much harder to read.

> We might as well name the following constants:
> FIRST_INTEGER_AFTER_ZERO=1
> NUMBER_OF_DIGITS_IN_BASE_TEN=10
> FOUR_TIMES_PI=math.pi*4

These do not define numbers in terms of *intent*, the way that
HOURS_PER_DAY or BEERS_PER_SLAB do.  They give no context that wasn't
already present (i.e., that these are numbers).

Would you disagree, though, with setting these named constants:

START_ARRAY_INDEX = 1
NUMBER_BASE = 10
DEGREES_IN_RIGHT_ANGLE = 90

Now there is context for these numbers.  When I use the literal number
10 in my code, am I using it because it's the number base I want to use?
How can you know?  You'd make an educated guess.  But if I would just
use NUMBER_BASE instead, you wouldn't have to guess at all.

Code is written only once; it is read many more times than that.
Spending a little time when writing the code to make it more readable
will pay off much better than simply writing 24 because "everyone will
know that means HOURS_PER_DAY".

> I think these kind of constants are *too* obvious and only make
> your code harder to read. BUT: this depends on the situation!
> I always think about the readability and maintainability while writing
> the code. Perhaps in some parts, these 'obvious' constants are
> needed to improve the code, but usually they are not (my opinion).

My opinion is, it's impossible to guess ahead of time what will be
obvious to the reader, so I should take any reasonable steps to reduce
the amount of guessing they need to do.

Code should have as few surprises and mysteries as possible.  Named
constants, even for "obvious" constants, help reduce mystery with very
little effort.

-- 
 \      "I guess we were all guilty, in a way. We all shot him, we all |
  `\   skinned him, and we all got a complimentary bumper sticker that |
_o__)                      said, 'I helped skin Bob.'"  -- Jack Handey |
http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B




More information about the Python-list mailing list