• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

Switch abuse?

 
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Consider the following:


Putting aside any typos I may have made moving this from one machine to antoher I have two central questions:

1. Do you consider the use of switch to be in bad form? I rarely have use for switch, but in this particular case I'd like the fall through. However, given that CENTER and RIGHT must both modify x the need to check for x == 0 makes me think it's not a good approach.

2. When dealing with Swing it is unfortunate that at some point you are forced to use a subclass of JComponent. Putting aside the flaws in Swing and accepting it as it is, do you think it's better to extend JComponent in a situation such as this one or return a JComponent with a method signature similar to getJComponent(). I've been tossing this back and forth in my head for weeks now and I've been unable to come to any conclusion about which ought to be preferred. At the moment, anything that is intended to be directly added to a GUI as a JComponent extends JComponent. Anything that has some responsibility tied to a GUI, but is not necessarily a GUI component itself, returns a JComponent in some form.
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Fallthroughs are generally considered bad form, although I'll use them sometimes if one case is similar to another but with a small addition. But here you've got a fallthrough and a case that checks whether it was reached by a fallthough, and that's really pretty gross. I'd just hoist "y" out of the switch, make all the cases explicit, and write:

 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Do you consider the use of switch to be in bad form? I rarely have use for switch, but in this particular case I'd like the fall through. However, given that CENTER and RIGHT must both modify x the need to check for x == 0 makes me think it's not a good approach.


Yes.
Prefer to use a strategy. A switch forces the use of "compiled strategies" with the potential to also force a O(n) lookup (as opposed to always O(1) with a strategy). It is also a better abstraction - that is, if you provide the alternative, it will generally "feel" more correct simply because it more closely aligns with your requirements.

Instead of:
switch(n) where n is of type T
prefer:
interface Strategy{Association get(T t);}
with an implementation that matches your otherwise switch.

I have summarised the issue here, but I'm quite sure there is other literature on it.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

But here you've got a fallthrough and a case that checks whether it was reached by a fallthough, and that's really pretty gross.



Yes, that's what made my stomach turn. The code didn't look good, but I wasn't sure what a better solution was. It's not uncommon for me to see something bad and know it's bad, but not be able to pinpoint what illicits the reaction in me.

I'd just hoist "y" out of the switch, make all the cases explicit, and write:



Unfortunately the code supplied won't exhibit quite the same behavior as what I was doing. I wrote the code intending to do nothing and use the supplied Graphics (g) if no Location was specified. Checking for (loc != null) before setting the new Graphics (g2) and the y would make it the same though. In that case though is there any reason to use a switch statement at all? What about:



Part of the problem may be that the class is trying to do too much in both specifying and not specifying locations. I'm trying to balance ease of use against my natural inclination to make every class as small and reuseable as possible with as few responsibilities (one ideally) as possible. I considered giving it eight locations including NORTHWEST, NORTHEAST, SOUTH, etc. but only the four I implemented in this (no location is effectively NW) are ever likely to actually be used.


switch(n) where n is of type T
prefer:
interface Strategy{Association get(T t);}
with an implementation that matches your otherwise switch.



I never used Strategy before but I have a plethora of information on Strategy now. It certainly seems like a better alternative to switch, though isn't this case a bit trivial for it?

Actually now that I think about it I believe I have used Strategy or something akin to it for handling importing, parsing and performing matching on files. Depending on the source a handler is created to retrieve the data and the handler is passed to an importer. The importer analyzes the data then picks a parser for the data type or throws an error (which is then handled by asking the user to select the type or abort), then the parsed information is passed to a matcher and then the (now updated) data is passed to a controller which takes care of presenting it to the user. The way it picks and chooses which of each to use seems somewhat similar to what I'm reading about Strategy. Though maybe it's not.
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


It certainly seems like a better alternative to switch, though isn't this case a bit trivial for it?


I don't believe in a case that is too trivial. Trial and error has brought about this perception. There is never a good reason to use switch/case, always prefer a strategy, even if only because it is a more appropriate abstraction (if it isn't, a switch/case certainly isn't either).
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tony Morris:

I don't believe in a case that is too trivial. Trial and error has brought about this perception. There is never a good reason to use switch/case, always prefer a strategy, even if only because it is a more appropriate abstraction (if it isn't, a switch/case certainly isn't either).



I wasn't suggesting it should be switch/case because it was trivial. I was suggesting that it should be if/else. I noticed you specifically mentioned it never being too trivial to not use a switch/case and since I don't think switch/case is appropriate I wonder how Strategy pairs up against a simple if/else in an example like this.
 
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ken,
Kudos on using the new type-safe enums. But reading the code in your first and second posts makes me think you are misinterpreting how a switch works with this enum type: switch(loc){...} will throw a NullPointerException if loc is null. You may be assuming that it will skip the rest of the statement instead, but noooo....

Anyhowdy, it may be more fun to nix switch and pix strategy. Instead of introducing an interface and implementing it separately, consider "constant-specific" methods, as demonstrated by the Operation enumeration in Sun's "New Features and Enhancements" document:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
 
Jeff Albertson
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
By the way, that wasn't a subliminal message. I wasn't permitted to post a method named "e-v-a-l".
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jeff Albrechtsen:
Ken,
Kudos on using the new type-safe enums. But reading the code in your first and second posts makes me think you are misinterpreting how a switch works with this enum type: switch(loc){...} will throw a NullPointerException if loc is null. You may be assuming that it will skip the rest of the statement instead, but noooo....

Anyhowdy, it may be more fun to nix switch and pix strategy. Instead of introducing an interface and implementing it separately, consider "constant-specific" methods, as demonstrated by the Operation enumeration in Sun's "New Features and Enhancements" document:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html



ick! Prefer:
interface DoubleOperation{double getDouble(Operation o) throws NullPointerException;}
Binding an enum to an implementation detail (which is completely unrelated to an enum) is horrible best case scenario.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Kudos on using the new type-safe enums. But reading the code in your first and second posts makes me think you are misinterpreting how a switch works with this enum type: switch(loc){...} will throw a NullPointerException if loc is null. You may be assuming that it will skip the rest of the statement instead, but noooo....



I was assuming that. I've never had a case where switch/case seemed appropriate so I haven't used one. At this point it's kind of moot because I don't think anyone has suggested that a switch/case is appropriate and I don't think one is either.

Anyhowdy, it may be more fun to nix switch and pix strategy. Instead of introducing an interface and implementing it separately, consider "constant-specific" methods, as demonstrated by the Operation enumeration in Sun's "New Features and Enhancements" document:



I hadn't thought about that in this case. I'm not sure I like the idea of attaching implementation to an enum though.
 
Jeff Albertson
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tony Morris:
Binding an enum to an implementation detail (which is completely unrelated to an enum) is horrible best case scenario.[/QB]



Binding addition to PLUS, subtraction to MINUS, multiplication to TIMES and division to DIVIDES is binding a completely unrelated implementation detail?
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Precisely (almost).
You are binding implementation detail to the enum type itself.
It's a lack of separation of two distinct and unrelated (OK, mildly related once you add a human to the scenario, which I choose not to do under a formal and objective analysis) operations.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jeff Albrechtsen:


Binding addition to PLUS, subtraction to MINUS, multiplication to TIMES and division to DIVIDES is binding a completely unrelated implementation detail?



Isn't an enumerated type more or less an identifier? As I understand it an enumerated type is responsible for what it identifies, now how to perform whatever operation it identifies. TIMES would indicate multiplication, I'm not sure it should be responsible for performing that multiplication too.

I must point out that I'm also of the opinion that the real world doesn't necessarily permit for intellectual satisfaction in these matters. It may be binding an implementation detail and this may be considered a bad practice, but it may nonetheless be an optimal solution in many cases.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
With all this talk about switch/case being bad I'm starting to wonder if there's ever a case where it's appropriate?
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ken Blair:
With all this talk about switch/case being bad I'm starting to wonder if there's ever a case where it's appropriate?



I plan to implement a fully featured API Specification without it.
I'll leave it up to the users to decide.
 
Jeff Albertson
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ken Blair:

Isn't an enumerated type more or less an identifier? As I understand it an enumerated type is responsible for what it identifies, now how to perform whatever operation it identifies. TIMES would indicate multiplication, I'm not sure it should be responsible for performing that multiplication too.



I'm not comfortable making ex cathedra pronouncements (did I sound like a certain poster whose initials are TM, for an instant, there? ) So I can't say, out of context, whether's Sun's Operation example is bad, but where's the harm? It's certainly reasonable to have a type for operations. Then why not enumerate those operations? This assumes operations aren't open-ended, but few calcuators have docks for plugging in keypad extensions
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I'm not comfortable making ex cathedra pronouncements (did I sound like a certain poster whose initials are TM, for an instant, there? )



I wouldn't call discussing an opinion on a forum an "ex cathedra" pronouncement, so I'm not sure what you're not comfortable with.

So I can't say, out of context, whether's Sun's Operation example is bad, but where's the harm?



If we can agree that binding implementation details to an unrelated type is a bad practice then there must be some harm that commonly derives from it. This tells me that if I do this there is a pitfall somewhere along the way even if it's not immediately apparent. In this case, the "harm" might come when you try to create a different implementation of the operation but find that the implementation was directly coupled to the enum that identifies the operation. I'm not a purist though becuase this is not an ideal world. In the real world there's probably many situations where there is a very minute chance that this issue will ever come up. As I said "...it may nonetheless be an optimal solution in many cases."

It's certainly reasonable to have a type for operations. Then why not enumerate those operations? This assumes operations aren't open-ended, but few calcuators have docks for plugging in keypad extensions



And that may very well be one case where the potential problems with it may never be realized. I think that would be an exception to the rule though.
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is the notion of "bad/good practice" and failure to use objective analytical processes that leads to these somewhat blurred debates. Also, when ego is attached, I often see a blurring and sometimes a contradiction of sound methods.

Independent of my existence (and yours) there exists a reality - this is an assumption that I hope we all agree on. This reality does not care in any way about our preferences, egos or ideological thoughts. Reality can never be derived by us, since any attempt always rests on an axiom(s). For example:
"The sky is blue because I observe it to be blue"
The axiom here is that the sky is observed to be blue.
Because of this axiom (the observation), the reality is extrapolated to be that the sky is blue.
We could all vanish off the planet tomorrow, but would the sky still be blue in the independent reality? Our axioms no longer exist at least.
By invalidating the axiom, you invalidate the perceived reality - this has occurred for many centuries. Scientists in the 15th century began formalising this method of reasoning that we are all assuming (even if you don't know it).

One can state an axiom or basis, such as "do not inflict pain unto oneself". Under this axiom, banging your head on a brick wall is "bad practice". However, all one need do is change the axiom and the practice becomes good. I find it mildly amusing to watch a debate simply digress in its blurred, and never formalised, axiom, which is what many people jokingly call "the neverending debate".

Under a given axiom, which I claim *you* assume, and for now I will call it "valid software" (it does have a formal, but verbose expression), a switch/case is bad practice. Go ahead and change the axiom sure, but you leave the context that I am attempting to portray by doing so. I also claim you leave the context that *you* were attempting to portray as well, even if inadvertantly (I say this based on general forms of communication - it's a generalistion). Does "valid software" exist independently of our existence in reality? I allege "yes, under all of its own axioms". Is it trivial to express and formalise? No, that's why we have these debates. It is *this axiom* that you might like to discuss - everything else is far less likely to reveal any flaws (the steps of reasoning). The most limiting part is the use of English as the method of communication. It is extremely ambiguous, and as you have probably observed, leads to irrelevant digressions due to ambiguity or whatever it might be that day. Mathematicians have a lovely language with which to communicate with, and they can state formal proofs to each other whenever they like, and there can be no debate, except of course, the invalidation of the axiom, which is extremely difficult (hence, documented "breakthroughs"). Unfortunately, this industry is full of monkeys in a monkey cage (myself included) who have no ability to reason, so all we do is throw bananas at each other and proclaim our exceptionalism as a result. As a proponent of reality, egotism is a declared enemy.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Under a given axiom, which I claim *you* assume, and for now I will call it "valid software" (it does have a formal, but verbose expression), a switch/case is bad practice.



Are you referring to me when you say "you"? You'd be right if you said I assume the axiom you refer to as "valid software". You'd also be right if you said I don't know or fully understand it and I have declared my own ignorance of terminology on more than one occasion. If I did understand and know it I probably wouldn't be asking these questions in an intermediate Java forum to begin with. I accept my ignorance, recognize my talents and weaknesses and strive to learn and improve on a daily basis because I will never forget it is the difference between a programmer with 10 years experience and a programmer with 1 years experience 10 times. But I digress.

Correct me if I'm wrong then, but you think then that switch/case is bad practice under the (assumed) axiom. That would lead me to ask (if you have the patience), why? I will be Googling this too of course and perhaps looking up some more books. Been thinking about purchasing Knuth's work, is it still a good read? I'm not sure if his work focused on design philosophy or just on concrete use of the language(s) of that time.
 
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In OO switches should be avoided.

Don't use switches at all if possible.
 
u johansson
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, you know, you shouldn't use switches in code because if you do you hardcode and that's not good. OO is about not doing that.
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Frankly, I don't know what Tony means by "valid software".

Why *I* program, there are basically two things I care about:

- the software does what the customer needs it to do. It seems obvious to me that this can be done using as many switch statements as you like.

- the software is easy to maintain and extend. This is where type cases (switch- or if-else-statements based on a type/enum etc.) get in the way, because every time the number of types changes, all the type cases need to be examined (and it's actually easy to miss one and thereby introduce a nasty bug).

Having said that, putting polymorphic methods on a typesafe enum is a rather elegant way to implement the Strategy or State pattern with a small, fixed (at compile time) number of instances, in my opinion.

Of course there are cases where I don't want to do this, where I want more flexibility. I often use the Visitor pattern in those cases. Not sure how the DoubleOperation interface is going to help, as Tony didn't show how it would be implemented (not a switch statement inside, I assume ).

And always keep in mind that a design isn't written in stone once it's implemented - you always can (and should) refactor when circumstances change.
 
u johansson
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, Ilja Preuss , why don't you tell us how enums makes us implement the Strategy and State patterns please?
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by u johansson:
Well, you know, you shouldn't use switches in code because if you do you hardcode and that's not good. OO is about not doing that.



No more so than using an if/else is hardcoding so I don't understand your argument.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ilja Preuss:
Frankly, I don't know what Tony means by "valid software".

Why *I* program, there are basically two things I care about:

- the software does what the customer needs it to do. It seems obvious to me that this can be done using as many switch statements as you like.

- the software is easy to maintain and extend. This is where type cases (switch- or if-else-statements based on a type/enum etc.) get in the way, because every time the number of types changes, all the type cases need to be examined (and it's actually easy to miss one and thereby introduce a nasty bug).



I believe when writing software it's not just important that it be easy to extend and maintain, but that it be easy to reuse. This implicitly means to me that objects should take on as little responsibility as possible, ideally doing one thing only. If it has one responsibilty, if it does one thing only, then it can be used anywhere that is required. If it has two responsibilities, then it can not necessarily be used anywhere one is required and not the other. My experience thus far has been that objects too often take on too much responsibility under the notion of being centralized and easy to use. Sure, they end up easy to use under the very narrow context it was intended for, but they also then end up nearly impossible to reuse. There's many other things that I believe also logically follow too that I won't bother mentioning.

Perhaps that's all implied as part of being easy to maintain an extend, I'm not sure.

Originally posted by Ilja Preuss:
Having said that, putting polymorphic methods on a typesafe enum is a rather elegant way to implement the Strategy or State pattern with a small, fixed (at compile time) number of instances, in my opinion.



Assuming I understood what you meant (which is not necessarily a safe assumption) I tend to agree with you. Binding implementation to an enum makes my stomach turn on general principle, but so does spending 5 hours writing "good" code instead of 5 minutes writing "bad" code just to avoid a problem there's a .00000001% chance of ever actually encountering.

Originally posted by Ilja Preuss:
Of course there are cases where I don't want to do this, where I want more flexibility. I often use the Visitor pattern in those cases. Not sure how the DoubleOperation interface is going to help, as Tony didn't show how it would be implemented (not a switch statement inside, I assume ).



I haven't gotten a chance to look at Visitor or DoubleOperation yet, so I can't really comment. As far as what Tony said though, I tend to get the impression that Tony will always go for the flexible/O-O solution rather than cutting corners to find an "optimal" solution if he can avoid it. Sorry if I'm misrepresenting you Tony, just what I've observed from your posts, seems like you are much more of a purist than most.

Originally posted by Ilja Preuss:
And always keep in mind that a design isn't written in stone once it's implemented - you always can (and should) refactor when circumstances change.



I have to remind myself of that a lot. I have a tendency to want to code things "perfectly" up front.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by u johansson:
Well, Ilja Preuss , why don't you tell us how enums makes us implement the Strategy and State patterns please?



I'd probably call Jeff's implementation of the Operation enum - the one with the "evil" method - a Strategy.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ken Blair:
I believe when writing software it's not just important that it be easy to extend and maintain, but that it be easy to reuse. This implicitly means to me that objects should take on as little responsibility as possible, ideally doing one thing only. If it has one responsibilty, if it does one thing only, then it can be used anywhere that is required. If it has two responsibilities, then it can not necessarily be used anywhere one is required and not the other.



I agree in principle. The problem I encounter in my work is that what "one thing" is depends on context. What might look like one thing in one system, may be two or more things in the context of another. But if I split a class before I know what other context it will be used in, I might experience that it just complicated reuse, because in the new context it's still just one thing, or worse, it needs to be split along a different dimension.


My experience thus far has been that objects too often take on too much responsibility under the notion of being centralized and easy to use. Sure, they end up easy to use under the very narrow context it was intended for, but they also then end up nearly impossible to reuse.



Yes, that matches my experience, and I very often split up classes just to make them easier to read etc.

But frankly, the Operation class above hardly can be called "big" or "doing too much" to me. If we *really* find out that the "eval" method needs to be different in different contexts where we want to reuse the enum, it's quite easy to refactor, so I'd wait until that moment.

Where I wouldn't wait is if we needed to visualize the operators in a GUI. I'm very strict with my Model-View seperation, so that's where I would use a Visitor from the beginning.
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[u johansson]: Well, you know, you shouldn't use switches in code because if you do you hardcode and that's not good. OO is about not doing that.

[Ken]: No more so than using an if/else is hardcoding so I don't understand your argument.


Well, the case values of a switch statement are required to be compile-time constants, or enums (which the compiler converts to compile-time constants, which is much the same thing except the term "compile-time constant" was defined before enums were introduced. Aaanyway...) With an if statement, you can be much more flexible, comparing dynamic variables to other dynamic variables. Or even to final variables which were loaded from a property file at runtime - that's something you can't put in a switch statement. So I would say that a switch statement does tend to force you to hard-code more than if/else does. And typically a Map is even more flexible. However there are still times when I find a switch to be an appropriate choice.

One situation that I've encountered several times where switch can be appropriate is when parsing. I may iterate through characters, switching on the value of each.

[Tony]: A switch forces the use of "compiled strategies" with the potential to also force a O(n) lookup (as opposed to always O(1) with a strategy).

I suppose in theory that potential is there. If one assumes the compier writers are sufficiently foolish. However when compiled to bytecode, the switch statement also has the potential (and in actual practice, the extreme likelihood) to take advantage of jumpswitch and tableswitch statements, which are a considerably faster than hashtable lookups. Of course this is the sort of optimization that's quite irrelevant to the majority of programs, and can be counterproductive to flexibility. However the fact remains that there are some programs that need to parse large amounts of data quickly, and in such situations it may be perfectly reasonable to sacrifice some flexibility and OO purity for the sake of performance. Thus, I can't agree to never use a switch statement, though I can certainly agree with avoiding it in most cases.

---

And a couple of truly irrelevant digressions...

---

[Tony]: Independent of my existence (and yours) there exists a reality - this is an assumption that I hope we all agree on.

Not really. Since you've been fond of inserting irrelevant physics comments amidst discussions of software engineering, I must point out that while Einstein was a staunch defender of the idea of objective reality, it's been pretty much done away with by the EPR paradox and the subsequent work of John Bell, Alain Aspect, and others. Physics, fundamentally, doesn't seem to allow for a reality independent of the observer. No matter how much that might satify our intellectual ideas of how we think the universe should work.

---

[Jeff A]: By the way, that wasn't a subliminal message. I wasn't permitted to post a method named "e-v-a-l".

Yeah, but you could have named the method "evaluate", "doEval", "evaal", "eeeval", "_eval", or many other possibilities. I think it's interesting that you turned to evil at first opportunity.
[ December 28, 2005: Message edited by: Jim Yingst ]
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jim Yingst:
[QB]
Well, the case values of a switch statement are required to be compile-time constants, or enums (which the compiler converts to compile-time constants, which is much the same thing except the term "compile-time constant" was defined before enums were introduced. Aaanyway...)

Since when does the compiler convert enums to compile-time constants?

[Tony]: A switch forces the use of "compiled strategies" with the potential to also force a O(n) lookup (as opposed to always O(1) with a strategy).

I suppose in theory that potential is there. If one assumes the compier writers are sufficiently foolish. However when compiled to bytecode, the switch statement also has the potential (and in actual practice, the extreme likelihood) to take advantage of jumpswitch and tableswitch statements, which are a considerably faster than hashtable lookups. Of course this is the sort of optimization that's quite irrelevant to the majority of programs, and can be counterproductive to flexibility. However the fact remains that there are some programs that need to parse large amounts of data quickly, and in such situations it may be perfectly reasonable to sacrifice some flexibility and OO purity for the sake of performance. Thus, I can't agree to never use a switch statement, though I can certainly agree with avoiding it in most cases.

Can you back that up? I'm assuming you're going to argue that a O(1) lookup is faster on a tableswitch than when using some kind of associative type (if not, can you beat O(1)?). Assuming this is the case, may I steal one of your arguments? The one about compilers that should do optimisations and all that? I'll bet not. What if I produced a case for you? What then? I'll tell you what, since you seem to have such validity in your words, I'll propose that you write me a switch statement, any switch statement you like, you can even compile it yourself, I won't touch it, and I'll beat it. Surely you can't pass that one up!?

---

And a couple of truly irrelevant digressions...

according to you, right? of course
---

[Tony]: Independent of my existence (and yours) there exists a reality - this is an assumption that I hope we all agree on.

Not really. Since you've been fond of inserting irrelevant physics comments amidst discussions of software engineering, I must point out that while Einstein was a staunch defender of the idea of objective reality, it's been pretty much done away with by the EPR paradox and the subsequent work of John Bell, Alain Aspect, and others. Physics, fundamentally, doesn't seem to allow for a reality independent of the observer. No matter how much that might satify our intellectual ideas of how we think the universe should work.

Well sir almighty, this part deserves a chuckle. First, I don't see the irrelevance in stating a basis of reasoning when we are... er... reasoning. Next, wtf does physics have to do with anything? You might mean perhaps philosophy or, if you permit your mind to ponder into that wild territory, astrophysics, but in any case, I'm merely attempting to portray a method of science - a more plausible basis than the egotistical ideas that are typically thrown around at least. Finally, I strongly urge you to take a second, and perhaps more, look at the work of those who you cite. I'm most willing to discuss it in great detail, much much more than some silly software engineering exercise, but of course, we'll take it off somewhere else - I look forward to it. Please exercise objectivity for the sake of constructive progressions.
---

Sometimes it's funny and I amuse myself, sometimes it's funny and I put myself up for criticism. At the end of the day, it's still funny. I expect nothing less than the wrath!

 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You know, Tony, it might help if you adopted some sort of consitent quoting style. Something that draws some sort of distinction between what you're quoting and what you're saying, for example.

A few quick answers - the remaining parts will have to wait a few days, probably.

[Tony]: Can you back that up?

I did observe it in the course of optimizing some parsing code long ago. Don't remember exact details now, and it's possible there was an alternate solution which would have worked better (or as well). I'll get back to you on this one with a more specific example.

[Tony]: I'm assuming you're going to argue that a O(1) lookup is faster on a tableswitch than when using some kind of associative type (if not, can you beat O(1)?).

That's right - a tableswitch would be O(1) too, just faster in many cases I think. (To be fair in most cases any difference would probably be negligible, but sometimes it's not.)

[Tony]: Assuming this is the case, may I steal one of your arguments? The one about compilers that should do optimisations and all that? I'll bet not.

Well I still favor letting compilers do the optimzation most of the time. Did I say at some point that this should be an absolute rule? I doubt it, but if I did, please do point out where. In general I'd let the compiler handle the optimization the vast majority of the time, but if observations and measurement indicates you'e got a bottleneck in a given area that needs to be reduced, step in and try to fix it.

[Tony]: What if I produced a case for you? What then?

You're welcome to. Or wait a few days until I get back to you. Either way, we could use some hard numbers and concrete examples.

[Tony]: I'll propose that you write me a switch statement, any switch statement you like, you can even compile it yourself, I won't touch it, and I'll beat it. Surely you can't pass that one up!?

Sounds reasonable.

---
Non-Java stuff beyond this point
---

[Tony]: according to you, right? of course

Yes, you can assume there was an "IMHO" after this and many other statements if you like, Tony. For what it's worth, I was referring mostly to my own comments, acknowledging them as irrelevant digressions. I was referring to the statements by you and Jeff too, but since in both cases I took a short quote and digressed considerably more, I felt it worthwhile to at least acknowledge that those points had little to do with the main discussion. In My Opionion. ™

[Tony]: Next, wtf does physics have to do with anything?

Good question. You're the one who repeatedly talks about the speed of light, linearity of time, and the finite or infinite extent of the universe, in the midst of discussions of Java and software engineering. It's hard for me to see the relevance too - that's why I labeled this section an irrelevant digression. QED.

[Tony]: You might mean perhaps philosophy or, if you permit your mind to ponder into that wild territory, astrophysics,

Or I might mean perhaps physics. Astrophysics is obviously a subset of physics, dealing specifically with stars (hence "astro") but I really think the more general term is appropriate for the topics under discussion. As for philosophy - well, once just about everything was considered a subset of philosophy. But for those things which we can successfully study with the scientific method, we nowadays tend to call them - well, science - rather than philosophy. I stand by "physics" as a far more apprpriate choice here than either astrophysics or philosophy. The subjects in question were properties of time near the speed of light, the extent of the physical universe, and quantum entanglement. Physics.

[Tony]: but in any case, I'm merely attempting to portray a method of science - a more plausible basis than the egotistical ideas that are typically thrown around at least.

OK. And maybe some readers find your attempts successful on that basis.

[Tony]: I expect nothing less than the wrath!

Good luck with that then. I'm going to sleep now.
[ December 28, 2005: Message edited by: Jim Yingst ]
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Personally I view every digression as a chance to learn.
 
reply
    Bookmark Topic Watch Topic
  • New Topic