Using enums to avoid using switch/if

M

Mayeul

Lew said:
And for-each loops are little more than glorified for() loops with the
additional hassle that you might forget that you needed an index.
Generics are little more than glorified Objects with the additional
hassle that you need to actually understand the type model of your
code. Assertions are little more than glorified if statements with
the additional hassle that you might forget and leave them on in
production. Methods are little more than glorified goto statements
with the additional hassle that you have to match up by type all the
arguments. If statements are little more than glorified gotos with
the additional hassle that you have to remember your braces or
mismatch your 'else' clauses. Object-oriented programming is little
more than glorified assembly-language programming with the additional
hassle that you have to understand the model for your application.

Really, one example was far enough. I get it, a language feature or
construct is to be used where it actually helps.

I so happen to really not think much of switch in most situations where
OOP is available. And I also happen to think it encourages to forget
'break' statements (or miss the presence or absence of break statements
when reading the code) if it is not supposed to return. A more serious
inconvenience than what you pointed out in your examples. That is what I
think. Hence 'If you ask me.'

As much as my seemingly-condescending* tone might make you think it was,
it wasn't my point. My point was that in the given example, replacing if
ladders with switch would buy little in terms of bloat, and that taking
advantage of enums is more likely to.


* I don't really sound like that on purpose. I learn English on teH
InTerNets and that sort of expressions are overused and tend to be
memorized for later reuse more easily.
 
M

Mayeul

Lew said:
APIs are not written by how the client plans to use it, but by how the
API writer intends the client to use it.

Throwing a run-time exception is a perfectly valid option. It
represents programmer error in the client.


Programming without exceptions isn't the wisest move. What he
suggested isn't "programming by exceptions", it's programming with
exceptions. Just what do you think exceptions are for, anyway?

Throwing an exception for an illegal argument is standard and
perfectly good practice.

Lew, what the hell already?

I am willing to accept I might have said something quite different than
what I meant. But you only seem to reinforce what I said, while making
it sound like I said the opposite. Why?
 
L

Lew

I am willing to accept I might have said something quite different than
what I meant. But you only seem to reinforce what I said, while making
it sound like I said the opposite. Why?

I read what you said as advice not to throw an exception, whereas what
I wrote was advice to throw an exception.

I also read what you said:
Shouldn't that depend on how you plan to use it?

as coming from the point of view of the consumer of the method. I
averred that the relevant perspective is that of the author of the
method.

So I was stating the opposite of the two points I thought you made.
If you meant something different from what I gathered, please do
clarify.
 
L

Lew

Mayeul said:
As much as my seemingly-condescending* tone might make you think it was,
it wasn't my point. My point was that in the given example, replacing if
ladders with switch would buy little in terms of bloat, and that taking
advantage of enums is more likely to.

Looking at source code, switch statements are far more compact than if
ladders. Looking at run-time, switch statements typically use much faster
low-level instructions than a series of if statements, with less impact on
branch prediction.
 
K

Karl Uppiano

Lew said:
Looking at source code, switch statements are far more compact than if
ladders. Looking at run-time, switch statements typically use much faster
low-level instructions than a series of if statements, with less impact on
branch prediction.

You can use enums in place of if/switch in a state machine, where each state
is an enum. Each enum has an execute method that returns an enum for the
"next" state. The "next" state is determined by the current state and
possibly internal state variables. This helps eliminates the continual
checking of conditional logic to determine what to do next, which can have a
noticeable improvement on efficiency.

State state = State.BEGIN;

do {
state = state.execute();
} while (state != State.END);

The program logic is contained in the execute method for each enumerated
state. This is a great way for implementing things like parsers, datastream
decoders and scripting engines. Before enums came along, I used classes, but
the idea is about the same either way.
 
K

Karl Uppiano

Karl Uppiano said:
You can use enums in place of if/switch in a state machine, where each
state is an enum. Each enum has an execute method that returns an enum for
the "next" state. The "next" state is determined by the current state and
possibly internal state variables. This helps eliminates the continual
checking of conditional logic to determine what to do next, which can have
a noticeable improvement on efficiency.

State state = State.BEGIN;

do {
state = state.execute();
} while (state != State.END);

The program logic is contained in the execute method for each enumerated
state. This is a great way for implementing things like parsers,
datastream decoders and scripting engines. Before enums came along, I used
classes, but the idea is about the same either way.

P.S. One might argue that "while (state != State.END)" is continually
checking conditional logic to determine what to do next. That's true, but
it's much more efficient than a switch statement or a series of if
statements each iteration. You need *some* way to exit the loop. I suppose
State.END.execute could unconditionally throw an exception, which eliminate
even the need to check state != State.END each time through the loop, but I
think that's getting a bit pathological, no?
 
M

Mayeul

Lew said:
I read what you said as advice not to throw an exception, whereas what
I wrote was advice to throw an exception.

OK, well I meant: there is no such absolute rule. Whether to throw an
exception or not should depend on whether it is expected behavior to
request for an operator just to know whether it exists. (Now admittedly,
in the given example we probably never need to 'just know'.)
I also read what you said:

as coming from the point of view of the consumer of the method. I
averred that the relevant perspective is that of the author of the
method.

So I was stating the opposite of the two points I thought you made.
If you meant something different from what I gathered, please do
clarify.

I don't think we need to take author or consumer separately here. As
stated above, my point was, either we may need to know whether an
operator exists, in which case it is probably unwanted to force checking
for an exception. Either an unknown operator is always an error, and the
method should throw an exception.
 
R

Roedy Green

I need a mechanism to map string to enum.

see the built-in valueOf function. I often override it to make it
case insensitive and allow aliases.

See http://mindprod.com/jgloss/enum.html
--
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.
 
L

Lew

Lew quoted or indirectly quoted someone who said :
Why do you not attribute the quote to the one who actually wrote it?

Roedy said:
see the built-in valueOf function.  I often override it to make it
case insensitive and allow aliases.

I doubt that very much. Static methods cannot be overridden.

While there is some value in hiding the 'valueOf' method, I prefer to
use a differently-named method for the same purpose. I am loathe to
(apparently) change the behavior of such a standard, language-defined
method as 'Enum.valueOf'. Instead I use a static 'fromString()'
method to be the companion for 'toString'.

The 'Enum' Javadocs suggest that '[a]n enum type should override
[toString] when a more "programmer-friendly" string form exists.' I
find it mnemonic and symmetrical to go from "programmer-friendly"
string form to enum constant with 'fromString'. This also preserves
the semantics of 'valueOf' as documented in the JLS. Furthermore, I
use 'valueOf' as the fallback if 'fromString' is otherwise unable to
locate the enum constant.

My enum template is:

/* ${name}.java
*/
package ${package};

/**
* ${name}.
*/
public enum ${name}
{

private final String repr; // "friendly" representation
/**
* Constructor.
* @param rep String representation of enum value.
*/
${name}( String rep )
{
this.repr = rep;
}

@Override
public final String toString()
{
return this.repr;
}

/**
* Look up enum constant from String representation.
* @param rep String representation of enum value.
* @return ${name} constant matching the representation.
*/
public static ${name} fromString( final String rep )
{
if ( rep == null )
{
return null;
}
for ( ${name} val : values() )
{
if ( rep.equals( val.toString() ) )
{
return val;
}
}
return valueOf( rep );
}
}
 
L

Lew

I doubt that very much.  Static methods cannot be overridden.

Then I have this, "Hey! Waaaaiiit a minute!" moment. You can't even
declare a 'valueOf()' method in an enum:

JLS 8.9:
"enum type declarations ... cannot contain methods that conflict with
the automatically generated methods (values() and valueOf(String))"
 

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,774
Messages
2,569,598
Members
45,144
Latest member
KetoBaseReviews
Top