www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - A switch/case too far...

reply Mike James <deepc fishing.net> writes:
I was looking thru some DWT examples and there is plenty of code like this...

if (myObj is thisObj)
    // do something
else if (myObj is thatObj)
    // do something else
else ...

It occured to me how much neater it would be if the there was a switch/case
construct that could deal with it..

switch (myObj) {
    case thisObj:
        // do something
        break;
    case thatObj:
        // do something else
        break;
    default:
        // do nothing
}

I'm not sure how much compiler 'magic' would be required :-)
May 20 2008
next sibling parent reply "Koroskin Denis" <2korden gmail.com> writes:
On Tue, 20 May 2008 15:06:38 +0400, Mike James <deepc fishing.net> wrote:

 I was looking thru some DWT examples and there is plenty of code like  
 this...

 if (myObj is thisObj)
     // do something
 else if (myObj is thatObj)
     // do something else
 else ...

 It occured to me how much neater it would be if the there was a  
 switch/case construct that could deal with it..

 switch (myObj) {
     case thisObj:
         // do something
         break;
     case thatObj:
         // do something else
         break;
     default:
         // do nothing
 }

 I'm not sure how much compiler 'magic' would be required :-)
There is a pitfall: should the compiler check for logical equality (opEqual) or instance equality (is)? "myObj is thisObj" is definately not the same as "myObj == thisObj", but how do you choose? And what about possible side effects? a.opEquals(b) can give different result each time being called, and therefor cannot be used in a switch statement unless it's marked as pure, which is to be implemented, I hope :)
May 20 2008
next sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
The simple solution to that would be:

case is thisObj:
case is thatObj:

Makes sense and confuses no one, imho...

-[Unknown]


Koroskin Denis wrote:
 On Tue, 20 May 2008 15:06:38 +0400, Mike James <deepc fishing.net> wrote:
 
 I was looking thru some DWT examples and there is plenty of code like 
 this...

 if (myObj is thisObj)
     // do something
 else if (myObj is thatObj)
     // do something else
 else ...

 It occured to me how much neater it would be if the there was a 
 switch/case construct that could deal with it..

 switch (myObj) {
     case thisObj:
         // do something
         break;
     case thatObj:
         // do something else
         break;
     default:
         // do nothing
 }

 I'm not sure how much compiler 'magic' would be required :-)
There is a pitfall: should the compiler check for logical equality (opEqual) or instance equality (is)? "myObj is thisObj" is definately not the same as "myObj == thisObj", but how do you choose? And what about possible side effects? a.opEquals(b) can give different result each time being called, and therefor cannot be used in a switch statement unless it's marked as pure, which is to be implemented, I hope :)
May 20 2008
prev sibling parent "Janice Caron" <caron800 googlemail.com> writes:
2008/5/20 Koroskin Denis <2korden gmail.com>:
 There is a pitfall:
 should the compiler check for logical equality (opEqual) or instance
 equality (is)?
I like the following idea: if the case statement specifies a type, check that the object can be implicitly cast to that type; if the case statement specifies a value, check for equality. So: switch(typeof(a)) { case B1: // RTTI dynamic cast test // ... case B2: // ... } But switch(a) { case a1: // equality test // ... case a2: // ... }
May 20 2008
prev sibling next sibling parent Sean Reque <seanthenewt yahoo.com> writes:
Mike James Wrote:

 I was looking thru some DWT examples and there is plenty of code like this...
 
 if (myObj is thisObj)
     // do something
 else if (myObj is thatObj)
     // do something else
 else ...
 
 It occured to me how much neater it would be if the there was a switch/case
construct that could deal with it..
 
 switch (myObj) {
     case thisObj:
         // do something
         break;
     case thatObj:
         // do something else
         break;
     default:
         // do nothing
 }
 
 I'm not sure how much compiler 'magic' would be required :-)
This could be done, but as far as I understand it would in effect do the exact same thing as the if/else statements and would therefore serve only as syntactic sugar. There are also other ways to avoid the kind of code above. For instance, you could create a map of objects to function pointers/delegates at runtime and perform a single lookup instead.
May 20 2008
prev sibling next sibling parent reply Gregor Richards <Richards codu.org> writes:
DISCLAIMER: This suggestion is not serious. Oh please dear god no.

This would be simple if you could switch on a single-value function 
returning bool, and if there was some form of sections ala Haskell, e.g.:

switch (a is) {
     case b:
(etc)
}

  - Gregor Richards
May 20 2008
parent BCS <ao pathlink.com> writes:
Reply to Gregor,

 DISCLAIMER: This suggestion is not serious. Oh please dear god no.
 
 This would be simple if you could switch on a single-value function
 returning bool, and if there was some form of sections ala Haskell,
 e.g.:
 
 switch (a is) {
 case b:
 (etc)
 }
 
 - Gregor Richards
 
I think you might be able to implement that using recursive templates (like I demonstrated in my D '07 talk) it would look something like this Switch!(Object, bool function(Object a, Object b){return a is b;}, A). Case!(B, {action();}). Case!(C, {something();}). End(); OTOH I think you get an issue with not being able to alias local stuff. p.s. No I'm not serious either.
May 20 2008
prev sibling next sibling parent janderson <askme me.com> writes:
Mike James wrote:
 I was looking thru some DWT examples and there is plenty of code like this...
 
 if (myObj is thisObj)
     // do something
 else if (myObj is thatObj)
     // do something else
 else ...
 
 It occured to me how much neater it would be if the there was a switch/case
construct that could deal with it..
 
 switch (myObj) {
     case thisObj:
         // do something
         break;
     case thatObj:
         // do something else
         break;
     default:
         // do nothing
 }
 
 I'm not sure how much compiler 'magic' would be required :-)
That could be nice, however I think RTTI checks like that should be avoided. It would be much better to use polymorphism then break abstraction using a switch statement. -Joel
May 21 2008
prev sibling parent reply terranium <spam here.lot> writes:
Janice Caron Wrote:

 I like the following idea: if the case statement specifies a type,
 check that the object can be implicitly cast to that type; if the case
 statement specifies a value, check for equality. So:
 
     switch(typeof(a))
     {
         case B1: // RTTI dynamic cast test
             // ...
 
         case B2:
             // ...
     }
 
there is no need for RTTI for *implicit* cast.
May 22 2008
parent reply "Janice Caron" <caron800 googlemail.com> writes:
2008/5/22 terranium <spam here.lot>:
 there is no need for RTTI for *implicit* cast.
I know. So what?
May 22 2008
parent reply terranium <spam here.lot> writes:
Janice Caron Wrote:

 2008/5/22 terranium <spam here.lot>:
 there is no need for RTTI for *implicit* cast.
I know. So what?
so what's the meaning of
 check that the object can be implicitly cast to that type
 
     switch(typeof(a))
     {
         case B1: // RTTI dynamic cast test
     }
?
May 22 2008
parent reply "Janice Caron" <caron800 googlemail.com> writes:
Well, convenience and readability, of course.

    switch(typeof(a))
    {
        case B1:
            // stuff
            break;

        case B2:
            // stuff
            break;

        case B3:
            // stuff
            break;
    }

looks cooler than

    {
        auto t = cast(B1)a;
        if (t != null)
        {
            // stuff
        }
    }
    {
        auto t = cast(B2)a;
        if (t != null)
        {
            // stuff
        }
    }
    {
        auto t = cast(B3)a;
        if (t != null)
        {
            // stuff
        }
    }

(in my opinion, at least). That said, I don't really care much about
this proposal one way or the other. It's only sugar, after all.
May 22 2008
parent "Koroskin Denis" <2korden gmail.com> writes:
On Thu, 22 May 2008 17:30:14 +0400, Janice Caron <caron800 googlemail.com>  
wrote:

 Well, convenience and readability, of course.

     [skip]
    (in my opinion, at least). That said, I don't really care much about
 this proposal one way or the other. It's only sugar, after all.
terranium most probably found your fault with the following:
 check that the object can be implicitly cast to that type
Since implicit cast always succeeds, there is no need for such a switch, that's why it should work with *explicit* cast only, it's an error otherwise: class A { } class B : A { } class C { } B a = new B(); switch (b is) { case A: // always succeeds, and therefore makes no sense break; case C: doSomething(); // error, unreachable code break; }
May 22 2008