Rational argument for not defining string constant for empty string?

D

david.karr

So let's say you're working with a developer who has accepted the
wisdom of defining constants for oft-used hardcoded strings. They
then decide that lines like this:

String foo = "";

should instead be:

String foo = StringConstants.EMPTY_STRING;

Assuming you conclude, as I do, that this is going too far, what
rational and logical arguments would you present to convince someone
that doing this is a mistake?
 
S

Stefan Ram

david.karr said:
So let's say you're working with a developer who has accepted the
wisdom of defining constants for oft-used hardcoded strings.

It depends on the presumed/expected change structure.

I refactor

... print( "Paris" ) ...
...
... print( "Paris" ) ...

to

paris = "Paris"

... print( paris ) ...
...
... print( paris ) ...

/only if/, whenever the first "Paris" is changed, the
second also needs to change in exactly the same way.

So, constants are not defined for hardcoded strings
but for co-changing entities.
They
then decide that lines like this:
String foo = "";
should instead be:
String foo = StringConstants.EMPTY_STRING;
Assuming you conclude, as I do, that this is going too far, what
rational and logical arguments would you present to convince someone
that doing this is a mistake?

Every change costs time (including the time for discussing
it) and has the risk of introducing errors, so there is a
change overhead. We only want to pay the change overhead if
the change brings as an even larger benefit with a
sufficient certainity.

So, when /they/ want to change something, /they/ need to
bring forward reasons for this, making it visible how the
change should have such a benefit with a sufficient
certainity. Then, we can discuss this here.
 
M

Mike Schilling

david.karr said:
So let's say you're working with a developer who has accepted the
wisdom of defining constants for oft-used hardcoded strings. They
then decide that lines like this:

String foo = "";

should instead be:

String foo = StringConstants.EMPTY_STRING;

Assuming you conclude, as I do, that this is going too far, what
rational and logical arguments would you present to convince someone
that doing this is a mistake?

The point of defining a string constant is to

1. Give the string a meaingful name
2. Make life easier for developers, who can refer to the constant rather
than type the string (especially useful with an IDE)
3. Ensure the string doesn't get mistyped.
4. Allow the string value, if it needs to change, to be changed in one
place.

Inventing a constant that simply means "the empty string" accomplishes none
of these.

1. We already know that "" is the empty string. The name EMPTY_STRING adds
no new information
2. "" is easier to type than the constant
3. There's a very small change of mistyping "".
4. here's no other possible value for StringConstants.EMPTY_STRING

However, if an empty string is being used for some specific purpose, e.g. to
mean "this value is unknown", it would make perfect sense to define

public static final String UNKNOWN_VALUE = "";

1. Anyone reading the program knows that the value is unknown as opposed to
being known to be empty
2. Developers don't have to recall whether unknwn values are empty strings
or nulls
3. More or less the same as 2 in this case
4. If you later decide that "" is a valid value, UNKNOWN_VALUE can be
changed to, say, "*unknown*".
 
S

Stefan Ram

Mike Schilling said:
1. We already know that "" is the empty string. The name EMPTY_STRING adds
no new information

Actually, it holds /less/ information. We do not know its text,
it could be defined as

EMPTY_STRING := "EMPTY_STRING"

or

EMPTY_STRING := "empty"

or so.
 
D

david.karr

The point of defining a string constant is to

1. Give the string a meaingful name
2. Make life easier for developers, who can refer to the constant rather
than type the string (especially useful with an IDE)
3. Ensure the string doesn't get mistyped.
4. Allow the string value, if it needs to change, to be changed in one
place.

Inventing a constant that simply means "the empty string" accomplishes none
of these.

1. We already know that "" is the empty string.  The name EMPTY_STRING adds
no new information
2. "" is easier to type than the constant
3. There's a very small change of mistyping "".
4. here's no other possible value for StringConstants.EMPTY_STRING

However, if an empty string is being used for some specific purpose, e.g. to
mean "this value is unknown", it would make perfect sense to define

  public static final String UNKNOWN_VALUE = "";

1. Anyone reading the program knows that the value is unknown as opposed to
being known to be empty
2. Developers don't have to recall whether unknwn values are empty strings
or nulls
3. More or less the same as 2 in this case
4. If you later decide that "" is a valid value, UNKNOWN_VALUE can be
changed to, say, "*unknown*".

Thanks, all good points.

If I were to present this to someone, I think I would put some of your
justification for the "meaningful name" point back into the statement
itself. It's important to qualify that the "meaningful name" is of no
added value if it doesn't provide more information than the value it's
defined to represent (and to Stefan's point, perhaps even less than
zero if it's not completely unambiguous what value the constant
represents).
 
M

Martin Gregorie

should instead be:

String foo = StringConstants.EMPTY_STRING;
Inventing something like a StringConstants class causes problems on just
about every level. A constant is only meaningful within some context, so
should be defined in a superclass or class that is logically part of the
context and is named appropriately. The constant name should reflect is
meaning within the context.
Assuming you conclude, as I do, that this is going too far, what
rational and logical arguments would you present to convince someone
that doing this is a mistake?
The person proposing this idea is probably an MBA or related organism and
so won't understand logic or rational arguments.
 
L

Lothar Kimmeringer

Stefan said:
Actually, it holds /less/ information. We do not know its text,
it could be defined as

EMPTY_STRING := "EMPTY_STRING"

or

EMPTY_STRING := "empty"

or so.

That would be a new entry for the dailywtf. Best until now was
enum Bool = {True, False, FileNotFound}


Regards, Lothar
--
Lothar Kimmeringer E-Mail: (e-mail address removed)
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!
 
A

Arne Vajhøj

So let's say you're working with a developer who has accepted the
wisdom of defining constants for oft-used hardcoded strings. They
then decide that lines like this:

String foo = "";

should instead be:

String foo = StringConstants.EMPTY_STRING;

Assuming you conclude, as I do, that this is going too far, what
rational and logical arguments would you present to convince someone
that doing this is a mistake?

It does not provide any value. "" is readable and will never
change value.

This is just code clutter.

One of the most important aspects of good rules is to
know when they apply and when they do not apply.

Note that:

String foo = "";

is better than:

String foo = StringConstants.EMPTY_STRING;

but in some contexts it would be even better to use:

String foo = FOO_DEFAULT;

because "" wil never change value, but the default value of
foo could change.

Arne
 
A

Arne Vajhøj

The point of defining a string constant is to

1. Give the string a meaingful name
2. Make life easier for developers, who can refer to the constant rather
than type the string (especially useful with an IDE)
3. Ensure the string doesn't get mistyped.
4. Allow the string value, if it needs to change, to be changed in one
place.

Inventing a constant that simply means "the empty string" accomplishes none
of these.

1. We already know that "" is the empty string. The name EMPTY_STRING adds
no new information
2. "" is easier to type than the constant
3. There's a very small change of mistyping "".
4. here's no other possible value for StringConstants.EMPTY_STRING

Very well explained.
However, if an empty string is being used for some specific purpose, e.g. to
mean "this value is unknown", it would make perfect sense to define

public static final String UNKNOWN_VALUE = "";

1. Anyone reading the program knows that the value is unknown as opposed to
being known to be empty
2. Developers don't have to recall whether unknwn values are empty strings
or nulls
3. More or less the same as 2 in this case
4. If you later decide that "" is a valid value, UNKNOWN_VALUE can be
changed to, say, "*unknown*".

Even though I completely agree with the point, then I am not sure
that I like the example.

Valid values having special semantics can create a lot of problems.

Arne
 
M

Mike Schilling

Arne said:
Very well explained.


Even though I completely agree with the point, then I am not sure
that I like the example.

Valid values having special semantics can create a lot of problems.

Sure do. Perhaps think of the example as realizing after the fact that the
empty string is a valid value, but non-alphanumeric strings never will be.
 
A

Andreas Leitgeb

Mike Schilling said:
3. Ensure the string doesn't get mistyped.

I think to vaguely remember the existence of mistyped (w.r.t orthography
of the corresponding natural language word) constants' names in Java's
standard library. :) It was mentioned in this group, some while back.
 
E

Eric Sosman

That would be a new entry for the dailywtf. Best until now was
enum Bool = {True, False, FileNotFound}

I'll offer one that a colleague once came across
(in a different programming language):

#define HASHSIZE 51 /* a smallish prime */

The day when compilers can detect this class of error
is the day when we'll all lose our jobs.
 
S

Stefan Ram

Eric Sosman said:
#define HASHSIZE 51 /* a smallish prime */
The day when compilers can detect this class of error
is the day when we'll all lose our jobs.

Already today one can write:

#define HASHSIZE 51
#define HASHSIZE_ASSERTATIONS \
assert new java.math.BigInteger( HASHSIZE ).isProbablePrime( 999999 ); \
assert HASHSIZE >= 1; \
assert HASHSIZE <= 1000;

. I'd call this the »replace-comments-by-asserts refactor«.

However, the word »smallish« has a certain vagueness that
can be resolved by a human given a certain application/context.
So my translation to »<= 1000« might not be appropriate.
 
R

Roedy Green

String foo = "";

should instead be:

String foo = StringConstants.EMPTY_STRING;

The first generates almost the same code and is terser.

If it were your money, would you pay programmers to type the longer
form?


--
Roedy Green Canadian Mind Products
http://mindprod.com

Responsible Development is the style of development I aspire to now. It can be summarized by answering the question, “How would I develop if it were my money?” I’m amazed how many theoretical arguments evaporate when faced with this question.
~ Kent Beck (born: 1961 age: 49) , evangelist for extreme programming.
 
A

Arne Vajhøj

Already today one can write:

#define HASHSIZE 51
#define HASHSIZE_ASSERTATIONS \
assert new java.math.BigInteger( HASHSIZE ).isProbablePrime( 999999 ); \
assert HASHSIZE>= 1; \
assert HASHSIZE<= 1000;

Do you run your Java code through the C preprocessor?

Arne
 
A

Arne Vajhøj

The first generates almost the same code and is terser.

If it were your money, would you pay programmers to type the longer
form?

In projects where developers are paid for programming, then the
time to type in code is usually insignificant.

Arne
 
S

Stefan Ram

Arne Vajhøj said:
Do you run your Java code through the C preprocessor?

Sometimes I run Java code through a preprocessor.

For example, I write the file »Add.java« in the
directory »de/dclj/ram« as:

$include /java.gpp
$define VERSION slr@2009-08-29T17:35:33+02:00
$define SINCE slr@2007-08-30T01:17:50+02:00
HEADER
/**
REFERENCES */

@de.dclj.ram.meta.quality.Cleaned(2)
DECLARE(interface)< Domain >
{ public void add( final Domain value ); }

The preprocessor generates from this:

/* Copyright 2004-2010 Stefan Ram.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

package de.dclj.ram;

/**

@version slr@2009-08-29T17:35:33+02:00
@since slr@2007-08-30T01:17:50+02:00
@see <a href="http://www.purl.org/stefan_ram/java/de/dclj/ram/Add.java">source code</a>
@see <a href="http://www.purl.org/stefan_ram/html/ram.jar/de/dclj/ram/Add.html">documentation</a>
@see "<a href='http://www.purl.org/stefan_ram/pub/ram-jar'>Library homepage</a> (Must be opened in a <i>new window</i>, outside of frames, to avoid a 403 status code.)" */

@de.dclj.ram.meta.quality.Cleaned(2)
@de.dclj.ram.meta.description.Copyright( "Copright 2004-2009 Stefan Ram" )
@de.dclj.ram.meta.description.TypePath( "de.dclj.ram.Add" )
@de.dclj.ram.meta.description.Cleared( "slr@2009-08-29T17:35:33+02:00" )
public interface Add /* de.dclj.ram.Add */< Domain >
{ public void add( final Domain value ); }

Thus, the preprocessor inserts some boilerplate and
derives the name of the type declared from the file
name.
 
M

Mike Schilling

Eric said:
I'll offer one that a colleague once came across
(in a different programming language):

#define HASHSIZE 51 /* a smallish prime */

The day when compilers can detect this class of error
is the day when we'll all lose our jobs.

By the time compilers are smart enough to detect this, they'll spend their
mornings hangng around free memory flirting with that cute defragmenter.
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top