Pete, I know where you're coming from, but Eric more accurately captured
the scenarios I was thinking of.
His examples are exceptions to the rule, not demonstrations of a good rule.
Another example is the old-style and somewhat language-agnostic pseudocode
round(d*100.)/100.
for rounding to 2 decimal places (substitute other powers of ten for
rounding to less or more decimal places). [*] Here there is no meaning
for those constants other than TEN or a HUNDRED.
Writing code like that is silly. You should use a proper "round()" method
that takes as input the number of decimal places to use.
As "silly" as it may be, it's a known technique for rounding to a
specified increment - see
http://en.wikipedia.org/wiki/Rounding#Rounding_to_a_specified_increment.
I didn't trot out the technique as an endorsement, it's an example.
Forget how silly the technique is, give me a great constant name that
replaces "100." in that formula.
In either case, arguably the number of decimal places to round by should be
declared itself as a constant. Writing "100" by itself tells the reader of
the code nothing about why one is rounding to two decimal places, versus
some other number. This is true whether you use a more descriptive, more
functional "round()" method or go with the "*100, /100" approach.
Here's a thought - maybe _why_ you are rounding to 2 decimal places is
because you want to round to 2 decimal places. No reasonable named
constant is going to tell you that business requirement #17 required
that the rounding be the same as an existing Excel table from
spreadsheet such-and-such.
I didn't just pull that out of a hat either - I've had to do exactly
that the past few months. If you can come up with a named constant that
doesn't look like a paragraph that can express motives like that, please
trot out an example.
"Expressive code" means that the reader understands _why_ the code is
implemented the way it is, not just _how_. A literal 100 by itself used in
rounding tells the reader only _how_.
All code always tells you _how_. Only expressive code tells you _why_.
And in every case, those constants are meaningless as literals. Naming
them allows the code to self-document.
We seriously differ here. Inside a short method with a proper name there
is no way that those numbers are meaningless.
Comments get lost, go out of date, etc. Only the code is guaranteed to
remain, so it's always better to document using the code itself, rather
than external sources.
Try this one on for size - the method name is also code. For this
example - Gregorian date to Julian day number, or the reverse case) - a
fairly short and obvious method name very accurately describes what's
being done. If the comments have been removed then a reasonably
intelligent programmer should be able to Google the underlying algorithm.
If you're about to suggest that the method name could be mangled at some
point then God help us - the same coder who does that may also rename
your constants.
I think that's wrong. You may argue that if the programmer cannot after
sufficient thought understand what the numbers mean, then there's a
problem. But that's not the bar here. The bar is for _rapid_, unambiguous
comprehension. Names provide that while literal numbers do not.
"Sufficient thought"? It's a _Gregorian date to Julian day number_
formula - how many seconds should it take a person to sort of get what
most of the numbers stand for? Like 365 and 100 and 400?
For that matter, follow the first link I provided and look at
http://en.wikipedia.org/wiki/Julian..._Gregorian_calendar_date_to_Julian_Day_Number.
Please give me a concise and sensible named constant for all 13 numbers
involved in the formula.
Then tell me why it matters. 99 percent of programmers don't care what
the exact meaning of each individual number is, and well over half won't
get the math. And you think it's essential that each be a named constant?
Denigrating someone just because they didn't instantly understand what you
mean is wrong. The only "bigger problem" such a person has is the problem
that they are having to read code written by someone who didn't feel like
making it expressive enough.
I believe in expressive. I think some of your philosophies, like this
one here, actually make code harder to understand.
Wrong. We aren't naming the _numbers_ themselves. We are describing them
in a way that explains how and why they are used in the code.
I happen to believe there are plenty of examples where the context
provided by the code using that number, including variable and method
names, does a much better job.
Let me give you an example: the use of 31 in many functions for hashing
strings. What are you going to nominate as a name for that particular
number?
Every number you could ever use has such a description that can be
incorporated as a name. In some cases, we forego this, rather than
including things like "forLoopIncrementByOne". As I said, exceptions do
exist.
But your rounding and calendar examples to me a clearly on the other side,
benefitting clearly from having named constants in the code rather than
just plain literals.
"Abundantly clear" is in the eye of the beholder.
Clearly so.
AHS