Skip to main content

Makes switch() and case: work with any object or primitive

118 replies [Last post]

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
patrikbeno
Offline
Joined: 2004-10-11

Gladly, friend ;-) (But be aware of the fact that for extremely large values of 1, 1+2=3.14 ;-)

Are we gonna optimize this further?
If not, I wonder how this information affects your opinion on this RFE.

monika_krug
Offline
Joined: 2004-10-14

It would be nice if it worked at least for Strings. But then one might as well implement it for all objects.

So +1.

Monika.

kobit
Offline
Joined: 2003-06-13

Yes, maybe for all Comparable objects.
+1

Artur

tsinger
Offline
Joined: 2003-06-10

No, use OO-design instead.

Instead of something like this:
[code]public int getValue(Foo foo) {
final int value;
switch (foo) {
Foo.A:
value = 1;
break;
Foo.B:
value = 2;
break;
default:
value = 0;
break;
}
return value;
}[/code]
better write:
[code]public class Foo {
public static final Foo A = new Foo(1);
public static final Foo B = new Foo(2);
private final int value;
private Foo(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

public int getValue(Foo foo) {
return foo.getValue();
}[/code]

patrikbeno
Offline
Joined: 2004-10-11

This is type safe enumeration pattern and in Java5 it is already designed in a much better way than you present.

However, you missed the whole point completely. This is about [b]desision-making[/b] not about encapsulation and polymorphism. I want 'switch' to become fully equivalent to 'if/else' construct. All I want is that 'switch(expression)' and 'case value:' work with objects.

And don't tell we should do all flow control using OOP. not all, not every case, not all the time.

kcpeppe
Offline
Joined: 2003-06-15

>
> This makes switch(){} statement more flexible, it is
> backward compatible and makes Java more object
> oriented.
>

If there is one thing that switch is not.. it OO. If you catagorize the syntax in Java you can clearly see that there is stuff that works with objects and stuff that works with primitives. The reason that we have while, if, do, for, switch is because we cannot send a message to a primitive. A switch is a functional substitue for polymorphisum (or a poor replacement for a double-dispatch). It makes no sense to use switch (or a for, while, if or do) in a language where all elements are first class objects.

kcpeppe
Offline
Joined: 2003-06-15

>
> This makes switch(){} statement more flexible, it is
> backward compatible and makes Java more object
> oriented.
>

I'm sorry to have to come out against another one of your proposals. If there is one thing that switch is not.. it OO. If you catagorize the syntax in Java you can clearly see that there is stuff that works with objects and stuff that works with primitives. The reason that we have while, if, do, for, switch is because we cannot send a message to a primitive. A switch is a functional substitue for polymorphisum.

patrikbeno
Offline
Joined: 2004-10-11

[i]> I'm sorry to have to come out against another one of your proposals. [/i]

Doesn't matter. Getting used to ;-)

[i]> If there is one thing that switch is not.. it OO.[/i]

That's why I am talking about it. [b]let's make it OO ![/b]
Why not? What we can lose? What can we break?

Wouldn't it be nice?

kcpeppe
Offline
Joined: 2003-06-15

why do we need a switch (a functional construct) in an obstensivly OO langauge that nicely supports polymorphisum? A switch is nothing more than a calculated goto! On what basis can we switch on an object?

patrikbeno
Offline
Joined: 2004-10-11

1) we cannot remove switch. but we can improve it.
2) so you say we don't need if/while/switch etc. ? what world do you live in?

3) i consider myself OO purist but it can be overhead if just need to do:

switch (errorType) {
case ERROR: setBackground(RED); break;
case WARNING: setBackground(YELLOW); break;
default: setBackground(WHITE); break;
}

kcpeppe
Offline
Joined: 2003-06-15

> 1) we cannot remove switch. but we can improve it.
> 2) so you say we don't need if/while/switch etc. ?
> what world do you live in?
this one dude... what one do you live in? ;)

Now lets twist your brain.. consider that we can closures and consider that we had a class call... Boolean.. and consider that it had two instances, true and false. Now wouldn't it be interesting if for, while, and if were all methods implemented by true and false.... In that world, the if method for true could look like

public method if( Closure closure) {
closure.execute();
}

and the method if for false would look like
public method if( Closure closure) {}

>
> 3) i consider myself OO purist but it can be overhead
> if just need to do:
>
> switch (errorType) {
> case ERROR: setBackground(RED); break;
> case WARNING: setBackground(YELLOW); break;
> default: setBackground(WHITE); break;

Humm, how does one know if errorType is an ERROR, WARNING or something else?

patrikbeno
Offline
Joined: 2004-10-11

closures? feasible but i would not implement 'if' as closure:
Trouble is that you will instantiate and initialize your closure even if it never gets executed. You have to provide two implementations. not a big deal with 'if'
but how would you implement switch with closures? Will you provide 10 different implementations just to do a simple thing?

[code]
Boolean.TRUE.if(new Closure() {
doSomething();
});
[/code]

and how would you implement if/else if/else?
Seems like good old if() is much better...

[i]> Humm, how does one know if errorType is an ERROR, WARNING or something else? [/i]

screen component just cares about these types so whay should it care?
it is typical problem. If you need to change screen background according to some status (mentioned error type), where the implementation belongs? To screen component or to ErrorType class? And what is another screen component decides that it will change font size according to error type? What would you do?

Message was edited by: patrikbeno

kcpeppe
Offline
Joined: 2003-06-15

> closures? feasible but i would not implement 'if' as
> closure:

read the posting again.. if is the method, the closure is the code that gets executed if the message is sent to true.

> Trouble is that you will instantiate and initialize
> your closure even if it never gets executed.

Now, you are assuming implementation.... I'd suggest that this doesn't necessaryly have to be the case.

> and how would you implement if/else if/else?

lets see ;)

public void ifthenelse( Closure ifClosure, Closure elseClosure); would be the signature.

In true you execute the ifClosure and if false you execute the elseClosure. seems pretty simple enough. If true and false a cononicalized as they should be, then you really only have one instance of each and this stuff is only written once.

> Seems like good old if() is much better...

try to expand your linking beyond C++ for a while ;)
>
> [i]> Humm, how does one know if errorType is an
> ERROR, WARNING or something else? [/i]
>
> screen component just cares about these types so whay
> should it care?
> it is typical problem. If you need to change screen
> background according to some status (mentioned error
> type), where the implementation belongs? To screen
> component or to ErrorType class? And what is another
> screen component decides that it will change font
> size according to error type? What would you do?

use the true and tried anti-switch mechanisum... called polymorphisum.....

patrikbeno
Offline
Joined: 2004-10-11

> read the posting again.. if is the method, the
> closure is the code that gets executed ...

yes I know I just haven't said what I meant (hurry, you know) :-)

> Now, you are assuming implementation.... I'd suggest
> that this doesn't necessaryly have to be the case.

Sure but I am trying to stay on Java base. we are not inventing new language, neither we transform Java into something competely different.

if you say [i]callme(new One(), new Two())[/i], both One is created, then Two is created and finally they are passed to callme() method as arguments.
You wanna change this just because of closures? And how. Suggest, i am really curious.

> > and how would you implement if/else if/else?
>
> public void ifthenelse( Closure ifClosure, Closure
> elseClosure); would be the signature.
> ...

Now write down an example and say it's better than old way.
I think we definitelly need basic control flow instructions just for simplicity of most common tasks.
I know what world you live in. it must be some university. :-)

> > Seems like good old if() is much better...
>
> try to expand your linking beyond C++ for a while ;)

In this case, I just don't want to. I am pretty sure I need classic if, if/elseif/else as well as while/do and
switch.

I believe it can be all done in a pure OO way but some things just should be left as they are.

What's wrong with if/else/while ?? It's pretty straightforward.

> use the true and tried anti-switch mechanisum...
> called polymorphisum.....

please give me example based on a scenario I described. Until then, I just cannot imagine.

[i]Pretty funny how such simple proposal (which I never expected to invoke replies longer than +1/-1/not worth it) can lead to such a religious discussions about core language...:-)[/i]

kcpeppe
Offline
Joined: 2003-06-15

> I know what world you live in. it must be some
> university. :-)

ha... there are some pretty large systems that move large amounts of money and control large shipping lanes based on smalltalk, a language does not NOT have if, if then else, do, while, switch, and any other flow control construct. So, I don't live in the University.. I live in the read world.

> [i]Pretty funny how such simple proposal (which I
> never expected to invoke replies longer than
> +1/-1/not worth it) can lead to such a religious
> discussions about core language...:-)[/i]

if that is all you're looking for -1

;)

patrikbeno
Offline
Joined: 2004-10-11

I am still eagerly waiting for that 'switch' example of yours. Come on!

dragonchick
Offline
Joined: 2003-06-16

IMHO...
For simple switch will be enough:

final static private int ERROR = 0;
final static private int WARNING = 1;
final static private int DEBUG = 2;
final static private int INFO = 3;

final static private String[] ERROR_TYPES =
{"error", "warn", "debug", "info"};
final static private List errorTypes = java.util.Arrays.asList(ERROR_TYPES);

int errorTypeInt = errorTypes.size()+1;
if (errorTypes.contans(errorType) {
errorTypeInt = errorTypes.indexof(errorType);
}

switch (errorType) {
case ERROR: setBackground(RED); break;
case WARNING: setBackground(YELLOW); break;
case DEBUG: setBackground(GREEN); break;
case INFO:
default: setBackground(WHITE); break;
}

at more complex cases, OO should be used.

tackline
Offline
Joined: 2003-06-19

I don't see the point of defining constants if you're only going to use them once. Another problem with that code is there is no reason to assume that the constants match the indexes. One of the better ways of writing it is:

import java.util.*;
import static java.awt.Color.*;
class Cases {
private static final List errors;
private static final int ERROR = 0;
private static final int WARNING = 1;
private static final int DEBUG = 2;
private static final int INFO = 3;
static {
errors = new ArrayList(Collections.nCopies(4, null));
errors.set(ERROR, "ERROR");
errors.set(WARNING, "WARN");
errors.set(DEBUG, "DEBUG");
errors.set(INFO, "INFO");
assert !errors.contains(null);
assert new HashSet(errors).size() == errors.size();
}
public static void main(String[] args) {
switch (errors.indexOf(args[0])) {
case ERROR: setBackground(red); break;
case WARNING: setBackground(yellow); break;
case DEBUG: setBackground(green); break;
case INFO: case -1: setBackground(white); break;
default: throw new Error();
}
}
private static void setBackground(java.awt.Color color) {
System.out.println(color);
}
}

In this case it'd be far, far better to use a map anyway.