multi-line Strings

A

Arne Vajhøj

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

Naming constants to be the same as the name of the value they represent,
yes...that's stupid.

But nothing about your example suggests that's actually how the
constances
should be named in the scenarios you describe.

If you are multiplying by a constant, there's a reason. Often, for
example,
you are converting units (hours per day, days per week, etc., following
your "date conversions" theme). The conversion itself is the correct name
(e.g. "hoursPerDay", "daysPerWeek", etc.) in those examples. Similar
logic
can be applied to other values.

public static final int MILLIMETERS_PER_METER = 1000;
public static final int MILLIGRAMS_PER_GRAM = 1000;
public static final int MILLIAMPERES_PER_AMPERE = 1000;
public static final int MILLISECONDS_PER_SECOND = 1000;

Great aids to understanding, I'm sure.


Which of these would you prefer:

A)

request.setWeight(1000 * response.getWeight());

B)

request.setWeight(MILLIGRAMS_PER_GRAM * response.getWeight());

C)

// convert from grams to milligrams
request.setWeight(1000 * response.getWeight());

D)

request.setWeightInMilliGrams(1000 * response.getWeightInGrams());

I don't think #B is that far fetched.

Arne
 
A

Arne Vajhøj

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

Naming constants to be the same as the name of the value they represent,
yes...that's stupid.

But nothing about your example suggests that's actually how the constances
should be named in the scenarios you describe.

If you are multiplying by a constant, there's a reason. Often, for example,
you are converting units (hours per day, days per week, etc., following
your "date conversions" theme). The conversion itself is the correct name
(e.g. "hoursPerDay", "daysPerWeek", etc.) in those examples. Similar logic
can be applied to other values.

There may be exceptions, to be sure. But I would say that the Java coding
guidelines make lots of sense in this area. Values such as 0, 1, -1, and
maybe even 2 in some cases generally are used in ways that are so clear as
to obviate any need for a named constant. But pretty much any other value
can benefit from a proper name, to allow the code to properly express for
what purpose the value is being used.

It is not obvious to me that 1 is that different from 7 in relation to
readability.
It's a pity...often the standard pedogogical justification for using named
constants is so that you can change the value in one place, rather than
having to go replace it everywhere in code. But this is faulty for at least
two reasons:

-- Even when the purpose is to make it easier to change a value, it's a
VERY good idea to go visit every single place in the code that value is
used, even when the value itself is being represented by a named constant.

Having a named constant doesn't get you out of doing that. It just makes it
simpler, because you don't have to visit places in the code the same
numeric value is being used for some completely different purpose.

Simpler means fewer mistakes.
-- The justification fails to convey the other very important reason for
using named constants, which is to keep the code readable and, especially!,
self-explanatory. A literal value might be plainly obvious to you, but not
everyone reading the code is going to have the same view. Writing in words
what the constant means, and using that in the code instead, ensures that
the code as read actually explains what the code does.

That one good argument exist should not be hold against another good
argument.

Arne
 
A

Arne Vajhøj

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

It certainly is.

The benefits of the constants are:
* make it easy to change the value later all but only places where it should
* increase readability by acting as documentation

TWO fails to achieve any of those. It is far from given that all
constants of 2 must be changes. TWO does not tell any more than 2.

if(daysPaymentOverdue() > 2) {
setAlarmLevel(2);
}

should not be converted to:

if(daysPaymentOverdue() > TWO) {
setAlarmLevel(TWO);
}

but to:

if(daysPaymentOverdue() > NO_DAYS_TO_SET_ALARM) {
setAlarmLevel(ALARM_NO_PAYMENT);
}

Arne
 
S

Stefan Ram

Peter Duniho said:
And of course, constants such as 100 or 400 (such as Arved mentioned) are
even less obvious.

I believe that, technically, in

»MILLISECONDS_PER_SECOND« is a variable (albeit a »constant
variable«, JLS7 4.12.4), and »1000« is a literal
(not a »constant« [but a »constant expression«]).

»Real« constants are technically: enum constants,
constants in interface types (static final fields of
other classes come close to them) and in annotation
types. (There also are »case constants« in case labels.)

Constant variables can be a part of constant expressions.
 
J

Jim Janney

Eric Sosman said:
I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

Naming constants to be the same as the name of the value they represent,
yes...that's stupid.

But nothing about your example suggests that's actually how the constances
should be named in the scenarios you describe.

If you are multiplying by a constant, there's a reason. Often, for example,
you are converting units (hours per day, days per week, etc., following
your "date conversions" theme). The conversion itself is the correct name
(e.g. "hoursPerDay", "daysPerWeek", etc.) in those examples. Similar logic
can be applied to other values.

public static final int MILLIMETERS_PER_METER = 1000;
public static final int MILLIGRAMS_PER_GRAM = 1000;
public static final int MILLIAMPERES_PER_AMPERE = 1000;
public static final int MILLISECONDS_PER_SECOND = 1000;

Great aids to understanding, I'm sure. (And stop calling me Millie!)

public static final int MILLISECONDS_IN_24_HOURS = 1000 * 60 * 60 * 24;

One should not, of course, write MILLISECONDS_PER_DAY due to the
possibility of DST.
 
A

Arved Sandstrom

[...]
If you are multiplying by a constant, there's a reason. Often, for example,
you are converting units (hours per day, days per week, etc., following
your "date conversions" theme). The conversion itself is the correct name
(e.g. "hoursPerDay", "daysPerWeek", etc.) in those examples. Similar logic
can be applied to other values.

public static final int MILLIMETERS_PER_METER = 1000;
public static final int MILLIGRAMS_PER_GRAM = 1000;
public static final int MILLIAMPERES_PER_AMPERE = 1000;
public static final int MILLISECONDS_PER_SECOND = 1000;

Great aids to understanding, I'm sure. (And stop calling me Millie!)

I guess your intent is to be sarcastic. But personally, I think using a
named constant does in fact make it clearer.

I would not be a stickler for making those named constants, and of course
have used literal values like those in code without naming them. But using
them as a named constant would in fact make the code clearer.

And of course, constants such as 100 or 400 (such as Arved mentioned) are
even less obvious.

As I said, there may be exceptions. SI units are notoriously easy to
convert, so as long as your variables and methods are well-named (i.e. are
clear about the units they represent), a named constant may not be called
for when converting. So, fine...if you like, there's one of your
exceptions.

That doesn't take way from the more general validity of my comments.

Pete
Pete, I know where you're coming from, but Eric more accurately captured
the scenarios I was thinking of. 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.

As for the 100 or 400, I was thinking for example of the Gregorian day
to Julian day number formula
(http://en.wikipedia.org/wiki/Julian..._Gregorian_calendar_date_to_Julian_Day_Number).
You can see how many constants are involved here, including 100 and 400.

I would use named constants for precisely ZERO (0) of these numbers.
Mainly because the Java or Perl or C# version of the method for doing
this conversion will have a descriptive name, I will have it commented
and include a link to a decent explanation perhaps. If a programmer
looks at the 365 or 100 or 400 in that complete formula and doesn't
understand what the numbers mean then named constants won't help either
- they have bigger problems.

My points are this:

(1) Sometimes numbers truly have no other name;

(2) Often there is context (naming, commenting, rest of the code) that
makes it abundantly clear what a number is.

AHS

* Let's not get started on how this isn't exact rounding. It isn't, no,
most of us understand that. But it's pretty decent and fairly
language-agnostic and pretty accurate numerical rounding.
 
G

Gene Wirchenko

Exactly.

As an example of either or both of the points I was trying to make.

UK post codes are pretty complex -- much more so than they look (e.g. see:
http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
) but many programmers don't realise that at first and so expect to be able to
use regular expressions for (say) input validation. A quick web search turns
up tons of examples of people looking for regexps for matching UK post codes.

Canadian Postal Codes have a bit of complexity, too, but I think
that the UK system wins on that. After checking the Wikipedia
article, it seems that the UK system is *too* complex.

The U.S. system has some odd exceptions, too.

[snip]

Sincerely,

Gene Wirchenko
 
G

Gene Wirchenko

On Tue, 18 Dec 2012 13:22:42 -0000, "Chris Uppal"

[snip]
or better yet:

request.setWeightInMg(convertGtoMg(response.getWeightInG());
^^2 ^1
Capitalisation matters in SI. 1) "Mg" means megagrams. 2) S/B
"g".

[snip]

Sincerely,

Gene Wirchenko
 
A

Arved Sandstrom

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
 
A

Arved Sandstrom

On Mon, 17 Dec 2012 20:45:58 -0400, Arved Sandstrom wrote:

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when
doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow
the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

Naming constants to be the same as the name of the value they represent,
yes...that's stupid.

But nothing about your example suggests that's actually how the
constances
should be named in the scenarios you describe.

If you are multiplying by a constant, there's a reason. Often, for
example,
you are converting units (hours per day, days per week, etc., following
your "date conversions" theme). The conversion itself is the correct
name
(e.g. "hoursPerDay", "daysPerWeek", etc.) in those examples. Similar
logic
can be applied to other values.

public static final int MILLIMETERS_PER_METER = 1000;
public static final int MILLIGRAMS_PER_GRAM = 1000;
public static final int MILLIAMPERES_PER_AMPERE = 1000;
public static final int MILLISECONDS_PER_SECOND = 1000;

Great aids to understanding, I'm sure.


Which of these would you prefer:

A)

request.setWeight(1000 * response.getWeight());

B)

request.setWeight(MILLIGRAMS_PER_GRAM * response.getWeight());
field "weight" in the Response class is in grams, and that
C)

// convert from grams to milligrams
request.setWeight(1000 * response.getWeight());

D)

request.setWeightInMilliGrams(1000 * response.getWeightInGrams());

I don't think #B is that far fetched.

Arne
Well, now that we are into units, strictly speaking I don't like any of
the above. Unless you do something like F# with measures, there really
isn't much to help you in a language like Java except rigorous
discipline enforced through standards and reviews. Named constants won't
help you, because how do you have a guarantee in B) that
response.getWeight() is returning grams, and that request.setWeight()
expects milligrams? All the named constant is ensuring is that you're
multiplying by 1000, which the literal value of 1000 in the code would
have done equally well.

AHS
 
G

Gene Wirchenko

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.

Why? You are just going to have to raise 10 to the power of 2.
Not surprisingly, that is 100.
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.

It is a common idiom. Outside computing, multiplying by 100 by
moving the decimal point two places to the left is understood by many,
including elementary school children.

[snip]

Sincerely,

Gene Wirchenko
 
A

Arved Sandstrom

On 12/14/2012 11:24 AM, Daniel Pitts wrote:
For instance, I have seen people avoid "?" and "&" by introducing the
constants QUESTION_MARK and AMPERSAND. This is bad.

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

It certainly is.

The benefits of the constants are:
* make it easy to change the value later all but only places where it
should
* increase readability by acting as documentation

TWO fails to achieve any of those. It is far from given that all
constants of 2 must be changes. TWO does not tell any more than 2.

if(daysPaymentOverdue() > 2) {
setAlarmLevel(2);
}

should not be converted to:

if(daysPaymentOverdue() > TWO) {
setAlarmLevel(TWO);
}

but to:

if(daysPaymentOverdue() > NO_DAYS_TO_SET_ALARM) {
setAlarmLevel(ALARM_NO_PAYMENT);
}

Arne
I agree, completely, because those are magic numbers.

My argument is expressed rather by this contrived example:

public int doubleInteger(int value) {
return value * 2;
}

and I also trot out my rounding to an increment example again.

In a more meaningful sense, what I've also been trying to say is that -
and I strongly believe that this is the case with the formula for
Gregorian date to Julian day number conversion - that you gain nothing,
and probably lose in readability, by trying to concoct named constants
for all the literal numbers involved in any number of situations.

Let's take another almost absurd example, the volume of a sphere. Apart
fro providing a named constant for pi, who is going to do that for the 4
or the two 3's? Well, from the sounds of it Peter would, but who else?

Point being, for any number of algorithms the numbers are _not_ magic.
They are documented formulae. If it is known what the formula is that is
being expressed in code (including my simplistic "doubleInteger"
method), it serves no purpose to supply named constants for the numeric
literals. IMHO.

AHS
 
E

Eric Sosman

[...]
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?

Not precisely what you asked for, and not even the value
that you asked for, and not in Java, but a colleague once found:

#define HASHSIZE 51 /* a smallish prime */

You may cringe when you are ready, Gridley.
 
L

Lew

Eric said:
Arved said:
[...]
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?

Not precisely what you asked for, and not even the value
that you asked for, and not in Java, but a colleague once found:

#define HASHSIZE 51 /* a smallish prime */

You may cringe when you are ready, Gridley.

I wasn't ready, but the cringing happened perforce.

That is a definite candidate for The Daily WTF.
 
A

Arne Vajhøj

On 12/17/2012 8:11 PM, Peter Duniho wrote:
On Mon, 17 Dec 2012 20:45:58 -0400, Arved Sandstrom wrote:

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when
doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow
the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

Naming constants to be the same as the name of the value they
represent,
yes...that's stupid.

But nothing about your example suggests that's actually how the
constances
should be named in the scenarios you describe.

If you are multiplying by a constant, there's a reason. Often, for
example,
you are converting units (hours per day, days per week, etc., following
your "date conversions" theme). The conversion itself is the correct
name
(e.g. "hoursPerDay", "daysPerWeek", etc.) in those examples. Similar
logic
can be applied to other values.

public static final int MILLIMETERS_PER_METER = 1000;
public static final int MILLIGRAMS_PER_GRAM = 1000;
public static final int MILLIAMPERES_PER_AMPERE = 1000;
public static final int MILLISECONDS_PER_SECOND = 1000;

Great aids to understanding, I'm sure.


Which of these would you prefer:

A)

request.setWeight(1000 * response.getWeight());

B)

request.setWeight(MILLIGRAMS_PER_GRAM * response.getWeight());
field "weight" in the Response class is in grams, and that
C)

// convert from grams to milligrams
request.setWeight(1000 * response.getWeight());

D)

request.setWeightInMilliGrams(1000 * response.getWeightInGrams());

I don't think #B is that far fetched.
Well, now that we are into units, strictly speaking I don't like any of
the above. Unless you do something like F# with measures, there really
isn't much to help you in a language like Java except rigorous
discipline enforced through standards and reviews. Named constants won't
help you, because how do you have a guarantee in B) that
response.getWeight() is returning grams, and that request.setWeight()
expects milligrams? All the named constant is ensuring is that you're
multiplying by 1000, which the literal value of 1000 in the code would
have done equally well.

None of these methods prevent errors.

But some are easier to read-understand than others and some have
less side effect clutter.

Arne
 
A

Arne Vajhøj

[...]
There may be exceptions, to be sure. But I would say that the Java coding
guidelines make lots of sense in this area. Values such as 0, 1, -1, and
maybe even 2 in some cases generally are used in ways that are so clear as
to obviate any need for a named constant. But pretty much any other value
can benefit from a proper name, to allow the code to properly express for
what purpose the value is being used.

It is not obvious to me that 1 is that different from 7 in relation to
readability.

You mean as literals?

I guess it depends on how 1 is being used. There may even be self-evident
uses for the literal 7. I just happen to think it probably occurs more
often (MUCH more often) with 1 than with 7.
[...]
-- The justification fails to convey the other very important reason for
using named constants, which is to keep the code readable and, especially!,
self-explanatory. A literal value might be plainly obvious to you, but not
everyone reading the code is going to have the same view. Writing in words
what the constant means, and using that in the code instead, ensures that
the code as read actually explains what the code does.

That one good argument exist should not be hold against another good
argument.

No, it shouldn't. Sorry if what I wrote seemed to say it did. I just feel
that when the concept is being taught, teachers often use the "just change
the value in one place" argument alone. This fails to truly capture the
full importance of using named constants rather than literals, and at the
same time leads new programmers to incorrectly believe that it's always a
reasonable practice to go changing a named constant's value without then
visiting every place in the code that uses that named constant.

(In some cases, that's not required. Small code base, coupled with a
straight-forward use of the named constant, can obviate the need to
double-check uses of the named constant. But in any large code base,
especially in a team, there's always the possibility that some schmuck went
and wrote some code that depends on the specific value of the named
constant. It's important to defend against that).

Very few practices completely prevent schmuk's doing something
bad.

It is good to review the code impacted by changing the value for
a constant.

Besides the risk of a schmuk not having used the constant, then
there are also other risks.

Like the new value being outside boundaries for which the
code is valid.

Arne
 
A

Arne Vajhøj

On 12/14/2012 03:47 PM, markspace wrote:
On 12/14/2012 11:24 AM, Daniel Pitts wrote:
For instance, I have seen people avoid "?" and "&" by introducing the
constants QUESTION_MARK and AMPERSAND. This is bad.

I wonder, in general, where the line should be drawn? Java coding
guidelines recommend that 1 and -1 can be used as literals, but other
integer constants should defined as a "constant" by the programmer.
[ SNIP ]

If I am multiplying by 2, or 10, or 1000, or using 100 or 400 when doing
some forms of date conversions, almost all the time the context will
make it clear what that constant is. If I were to religiously follow the
coding guidelines, in no small number of cases I'd have to define
constants that were called TWO or THOUSAND...which is sort of stupid.

It certainly is.

The benefits of the constants are:
* make it easy to change the value later all but only places where it
should
* increase readability by acting as documentation

TWO fails to achieve any of those. It is far from given that all
constants of 2 must be changes. TWO does not tell any more than 2.

if(daysPaymentOverdue() > 2) {
setAlarmLevel(2);
}

should not be converted to:

if(daysPaymentOverdue() > TWO) {
setAlarmLevel(TWO);
}

but to:

if(daysPaymentOverdue() > NO_DAYS_TO_SET_ALARM) {
setAlarmLevel(ALARM_NO_PAYMENT);
}

Arne
I agree, completely, because those are magic numbers.

My argument is expressed rather by this contrived example:

public int doubleInteger(int value) {
return value * 2;
}

and I also trot out my rounding to an increment example again.

In a more meaningful sense, what I've also been trying to say is that -
and I strongly believe that this is the case with the formula for
Gregorian date to Julian day number conversion - that you gain nothing,
and probably lose in readability, by trying to concoct named constants
for all the literal numbers involved in any number of situations.

Let's take another almost absurd example, the volume of a sphere. Apart
fro providing a named constant for pi, who is going to do that for the 4
or the two 3's? Well, from the sounds of it Peter would, but who else?

Point being, for any number of algorithms the numbers are _not_ magic.
They are documented formulae. If it is known what the formula is that is
being expressed in code (including my simplistic "doubleInteger"
method), it serves no purpose to supply named constants for the numeric
literals.

It do happen that values are obvious in a given context and will never
have to be changed.

My experience though is that "obvious" varies quite a bit between
people, geographic locations, time etc..

So if there is just the slightest doubt, then I suggest using a
named constant.

The cost is very small and maybe it will benefit the maintenance
programmer sitting with the code in 15 years.

Arne
 
A

Arne Vajhøj

While I'll grant that your (B) is OK, I'd point out that if you are mixing mg
and g in the same program then you are already in a state of sin.

Given that that might be necessary (and anyway sin is acceptable these days ;-)
I'd want to be lot more explicit.

request.setWeightMg(1000 * response.getWeightG());

That was #D.

I do not like that due to the pollution of the method names.
or better yet:

request.setWeightInMg(convertGtoMg(response.getWeightInG());

I still do not like the polluted set and get names.

But the conversion method is certainly a solution.

And the constant in that method may not require the named constants.
Or just go the full OO hog:

request.setWeight(response.getWeight());

And leave it to the Request, Response, and (in particular) the Weight classes
to sort out mutually convenient units and conversions themselves

I don't think that would be very practical, because one of the classes
would have a method using a different unit than the rest of the class.

Arne
 
A

Arne Vajhøj

[SNIP]
Or just go the full OO hog:

request.setWeight(response.getWeight());

And leave it to the Request, Response, and (in particular) the Weight classes
to sort out mutually convenient units and conversions themselves

A third option is to supply the unit as a separate argument:

// Sets the mass to the given value in kilograms
public void setMass( float massInKg ) { ... }

// Sets the mass to the given value in the specified unit
public void setMass( float value, Unit<Mass> inputUnit ) {
this.setMass( inputUnit.convertTo( value, Unit.KILOGRAM ) );
}

// Returns the value of the mass in kilograms
public float getMass( ) { ... }

// Returns the value of the mass in the specified unit
public float getMass( Unit<Mass> outputUnit ) {
return Unit.KILOGRAM.convertTo( this.getMass(), outputUnit );
}

That is a very nice way.

And doing it that way in software controlling an airplane makes
sense to be.

But it may be quite a bit cumbersome in a typical XXX KLOC
business app.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top