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

Carl Banks imbosol at aerojockey.com
Mon Jun 2 02:49:34 EDT 2003


Ben Finney wrote:
> On Fri, 30 May 2003, Irmen de Jong wrote:
>> 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

Yes.  All of these are taking it WAY too far.


> 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 can read the source code.  IMO, it's a far better to spend your
time making code readable enough so that you don't need a silly name
to know what a constant is used for.


> You'd make an educated guess.  But if I would just
> use NUMBER_BASE instead, you wouldn't have to guess at all.

It's a nice little idea that might be true in your little ideal world.

However, I find, in practice, that excessive use of named constants
can severely decrease the readability of a program.  There are many
reasons.


First, the names chosen for constants are often misleading and lead to
confusion.  For example, take your example NUMER_BASE.  What is the
base?  You think it's entirely clear to me what NUMBER_BASE is, but
it's not.  Sure, I know what it's (supposed to be) used for.  But I
don't know what it IS.  Is it a decimal base?  Hexadecimal?  Some odd
value?  If you use the constant NUMBER_BASE in your code, you'd force
the reader to have to find the definition; whereas, if you use just a
number, then the reader will probably see that it's a base right away
since it's the second argument of int.

What I'm saying is, your argument depends on constants being
well-named, and that's a rare thing, and you have produced a
poorly-named yourself.


Second, sometimes the value of the constant itself is more important
to readability than the name.  I'll give you an example.  Suppose I
have to do the following calculation:

    math.sin(x*PI/2.0)

You want me to write it like this:

    math.sin(x*RADIANS_IN_RIGHT_ANGLE)

I can tell you that it's far, far less readable.  I can't
overemphasize how much less readable the latter is to me.  Why?
Because PI/2.0 is ingrained in me.  I studied engineering; I am at one
with radians.  When I see PI/2.0, I immediately know what I'm looking
at.  When I see RADIANS_IN_RIGHT_ANGLE, I have to think about what it
means and what value it has.  It's not ingrained; I never studied any
engineering equations with such a constant in it.  You see, the named
constant RADIANS_IN_RIGHT_ANGLE makes it harder to read.  The constant
PI, on the other hand, increases readability, because it appears in
all the equations I learned.

I find that a good number of constants I use in my code are more
readable as-is.  Granted, I'm an engineer, and do a lot of number
work.  Most other programmers will not find this to be true as often
as I, but still, sometimes the constant is more readable itself, and
giving such a constant a name is counterproductive.


Third, it can be a pain to debug.  You looking at your code trying to
figure out where the mistake is, and you can't see if there's anything
obvious, because you don't know the values of all the constants.  Not
to mention, there is the possibility of an error in the named constant
itself, which is a hard one to track down.


Fourth, sometimes a number is just a number.  Giving a name to
something that isn't anything other than the number 2, or an entry in
a matrix, is just silly.


Finally, it's often just a lot of work for a very negligible benefit.
You might spend an extra ten minutes defining constants, but it might
only save a grand total two minutes down the line.


What I'm saying is, it's not always a good idea to name every single
constant.  Like most things, discretion is best.  It is very
beneficial to name constants in many situations, but not all.

Something like DEGREES_IN_RIGHT_ANGLE?  It's never going to change,
it's not likely to be misunderstood in context, and the number 90
means more to most people reading it than a verbose phrase.



-- 
CARL BANKS




More information about the Python-list mailing list