1. switch statement

Are there any reasons for the design of the new switch statement? I thought C's switch was widely critised for its bug-proneness. IMHO, Pascal's case is nicer.

new topic     » topic index » view message » categorize

2. Re: switch statement

Critic said...

Are there any reasons for the design of the new switch statement? I thought C's switch was widely critised for its bug-proneness. IMHO, Pascal's case is nicer.

I've never heard that before. I know some languages have a select statement that has implied breaks as oppose to our switch which has fall-thru. Having fall-thru can be quite nice in many situations. Simply be aware that fall-thru exists and you shouldn't have any more problem with it than any other decision construct.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

3. Re: switch statement

I did some google searches for buggy C switch and really didn't find anything but I did find a quote on the page of PHP's switch statement (which works just like ours, and most other switch statements):

php switch page said...

Where the switch statement wins out over an "if/elseif/else" block is it's ability to "fall though" to instructions in following cases until a break is encountered. Coding something similiar using "if/elseif/else" statements could get really messy and buggy really fast depending on the switch statement.

http://us2.php.net/switch

I tend to agree. That's why it was designed the way it is. There has been talk of implementing a select statement, but it didn't go very far for 4.0 as our plates have been full for a while. I, personally, do not see the reason for it, but others may enjoy not having to type break.

Oh, the php page does a good job of explaining switch, it's a good read for anyone interested.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

4. Re: switch statement

jeremy said...

I did some google searches for buggy C switch and really didn't find anything but I did find a quote on the page of PHP's switch statement (which works just like ours, and most other switch statements):

php switch page said...

Where the switch statement wins out over an "if/elseif/else" block is it's ability to "fall though" to instructions in following cases until a break is encountered. Coding something similiar using "if/elseif/else" statements could get really messy and buggy really fast depending on the switch statement.

http://us2.php.net/switch

I tend to agree. That's why it was designed the way it is. There has been talk of implementing a select statement, but it didn't go very far for 4.0 as our plates have been full for a while. I, personally, do not see the reason for it, but others may enjoy not having to type break.

Oh, the php page does a good job of explaining switch, it's a good read for anyone interested.

Jeremy

Ok, I'm familiar from Pascal with case, but not switch, so I read both Eu 4 doc and PHP doc.

If I understand "switch" at least partly correctly, if you don't put "break" after EVERY individual case statement, EVERY case statements code will execute EVEN IF THE CASE'S CONDITION ISN'T MET? Then what are the conditions in each case statement FOR, if they're not evaluated? Have I misunderstood?

And I gotta ask, is that "fall though" expected to be the NORMAL useage of switch, and that's why break to prohibit fall through, rather than continue to allow it was chosen?

If, on the other hand, fall though would be the EXCEPTION rather than the rule, then it would seem to save a lot of typing to have used "continue" instead of "break"?

Or is it that in some programming circumstances one useage would be more prevalent, and in some other circumstances the other would be?

Dan

new topic     » goto parent     » topic index » view message » categorize

5. Re: switch statement

With a switch statement, once a case evaluates as true, then all further case statements are ignored and a break will cause the switch to be exited. Here is an example:

sequence value = "red" 
 
switch value do 
  case "apple": 
  case "pear": 
  case "orange": 
    puts(1, "It's a fruit!\n") 
    break 
 
  case "yellow": 
  case "blue": 
  case "red": 
    puts(1, "It's a color!\n") 
    break 
 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end switch 
 
-- Output is "It's a color!" 

As for break vs. continue, we choose to keep the normal functionality of a switch as defined in just about every language. It would be pretty difficult for anyone who uses multiple languages or has knowledge of another language, to come to Euphoria and start working with a backward switch. That would be serious cause of bugs and errors.

I think what some people are thinking about is actually a select statement:

sequence value = "red" 
 
select value do 
  case "apple": 
    puts(1, "It's an apple\n") 
  case "pear": 
    puts(1, "It's a pear\n") 
  case "orange": 
    puts(1, "It's an orange!\n") 
  case "yellow": 
    puts(1, "It's yellow\n") 
  case "blue": 
    puts(1,"It's blue\n") 
  case "red": 
    puts(1, "It's red\n") 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end select 
 
-- Output is: "It's red" 

A select statement does not fall-thru. Euphoria does not yet have a select statement, I just was showing the differences.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

6. Re: switch statement

jeremy said...

With a switch statement, once a case evaluates as true, then all further case statements are ignored and a break will cause the switch to be exited. Here is an example:

sequence value = "red" 
 
switch value do 
  case "apple": 
  case "pear": 
  case "orange": 
    puts(1, "It's a fruit!\n") 
    break 
 
  case "yellow": 
  case "blue": 
  case "red": 
    puts(1, "It's a color!\n") 
    break 
 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end switch 
 
-- Output is "It's a color!" 

As for break vs. continue, we choose to keep the normal functionality of a switch as defined in just about every language. It would be pretty difficult for anyone who uses multiple languages or has knowledge of another language, to come to Euphoria and start working with a backward switch. That would be serious cause of bugs and errors.

I think what some people are thinking about is actually a select statement:

sequence value = "red" 
 
select value do 
  case "apple": 
    puts(1, "It's an apple\n") 
  case "pear": 
    puts(1, "It's a pear\n") 
  case "orange": 
    puts(1, "It's an orange!\n") 
  case "yellow": 
    puts(1, "It's yellow\n") 
  case "blue": 
    puts(1,"It's blue\n") 
  case "red": 
    puts(1, "It's red\n") 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end select 
 
-- Output is: "It's red" 

A select statement does not fall-thru. Euphoria does not yet have a select statement, I just was showing the differences.

Jeremy

Ok, I'm beginning to understand, I think.

Fall through can be useful for GENERALIZING tests: red, yellow, blue all more easily resolve to "colors" via switch, wheras "keypressed" would more easily identify "y", "n", or "q" as distinct and different inputs via select.

So, has it been determined that GENERALIZING is more often a programmers intent than DISTINGUISHING?

Dan

new topic     » goto parent     » topic index » view message » categorize

7. Re: switch statement

DanM said...

Ok, I'm beginning to understand, I think.

Fall through can be useful for GENERALIZING tests: red, yellow, blue all more easily resolve to "colors" via switch, wheras "keypressed" would more easily identify "y", "n", or "q" as distinct and different inputs via select.

So, has it been determined that GENERALIZING is more often a programmers intent than DISTINGUISHING?

I think the answer is we already have a construct (not as nice in some cases as select) that does non-fallthrough, that is the if statement. We did not have a construct that did fall through. Here is another example, built off your example of y, n, q:

sequence answer = prompt_string("Continue (y/n/q)?") 
 
switch answer do 
  case "y": 
  case "Y": 
  case "yes": 
  case "Yes": 
  case "YES": 
    puts(1, "Ok, we will continue\n") 
    break 
 
  case "n": 
  case "N": 
  case "no": 
  case "No": 
  case "NO": 
    puts(1, "Ok, we will not continue\n") 
    break 
 
  case else 
    puts(1, "Ok, we are quitting\n") 
end switch 

Now, there are certainly better way's of doing that example (if upper(answer[1]) = 'Y'), but it's just another example. You can look at the source code for Euphoria and see all sorts of real life examples of a switch. Now, before I finish this message, let's take my original example:

sequence value = "red"  
 
switch value do  
  case "apple":  
  case "pear":  
  case "orange":  
    puts(1, "It's a fruit!\n")  
    break  
  
  case "yellow":  
  case "blue":  
  case "red":  
    puts(1, "It's a color!\n")  
    break  
  
  case else  
    puts(1, "I have no clue what it is \n")  
end switch  

and let's write it as if we didn't have switch at all, i.e. in Euphoria 3.x

sequence value = "red"  
 
if equal(value, "apple") or equal(value, "pear") or equal(value, "orange") then 
  puts(1, "It's a fruit!\n") 
else if equal(value, "yellow") or equal(value, "blue") or equal(value, "red") then 
  puts(1, "It's a color!\n") 
else 
  puts(1, "I have no clue what it is \n")  
end if 

Now, I suppose you could write it a little more simply:

sequence value = "red" 
 
if find(value, { "apple", "pear", "orange" }) > 0 then 
  puts(1, "It's a fruit!\n") 
else if find(value, { "yellow", "blue", "red" }) > 0 then 
  puts(1, "It's a color!\n") 
else 
  puts(1, "I have no clue what it is\n") 
end if 

but, I would encourage you to benchmark these three examples. Hm, I can't resist, I just did a benchmark, here are the results (I changed the puts to setting a message as not to have all sorts of IO hiding the timing):

C:\Develop>exwc switchifbench.ex 
  bench_switch: 0.063 
bench_if_equal: 0.187 
 bench_if_find: 0.344 

And actually, when doing a switch on integers, it's much much faster. Anyway, here is my benchmark code if you want to run it on your box:

sequence value = "red" 
sequence message 
 
procedure bench_switch() 
	switch value do 
		case "apple": 
		case "pear": 
		case "orange": 
			message = "It's a fruit!" 
			break 
 
		case "yellow": 
		case "blue": 
		case "red": 
			message = "It's a color!" 
			break 
 
		case else 
			message = "I have no clue what it is" 
	end switch 
end procedure 
 
procedure bench_if_equal() 
	if equal(value, "apple") or equal(value, "pear") or equal(value, "orange") then 
		message = "It's a fruit!" 
	elsif equal(value, "yellow") or equal(value, "blue") or equal(value, "red") then 
		message = "It's a color!" 
	else 
		message = "I have no clue what it is" 
	end if 
end procedure 
 
procedure bench_if_find() 
	if find(value, { "apple", "pear", "orange" }) > 0 then 
		message = "It's a fruit!" 
	elsif find(value, { "yellow", "blue", "red" }) > 0 then 
		message = "It's a color!" 
	else 
		message = "I have no clue what it is" 
	end if 
end procedure 
 
constant ITS=1000000 
atom t1 
t1  = time() 
for i = 1 to ITS do 
	bench_switch() 
end for 
printf(1, "  bench_switch: %.3f\n", { time() - t1 }) 
 
t1  = time() 
for i = 1 to ITS do 
	bench_if_equal() 
end for 
printf(1, "bench_if_equal: %.3f\n", { time() - t1 }) 
 
t1  = time() 
for i = 1 to ITS do 
	bench_if_find() 
end for 
printf(1, " bench_if_find: %.3f\n", { time() - t1 }) 

Jeremy

new topic     » goto parent     » topic index » view message » categorize

8. Re: switch statement

DanM said...

Ok, I'm beginning to understand, I think.

Fall through can be useful for GENERALIZING tests: red, yellow, blue all more easily resolve to "colors" via switch, wheras "keypressed" would more easily identify "y", "n", or "q" as distinct and different inputs via select.

So, has it been determined that GENERALIZING is more often a programmers intent than DISTINGUISHING?

A switch statement is really a computed goto, the way that euphoria (and many other languages) implement it.

Matt

new topic     » goto parent     » topic index » view message » categorize

9. Re: switch statement

jeremy said...

With a switch statement, once a case evaluates as true, then all further case statements are ignored and a break will cause the switch to be exited. Here is an example:

sequence value = "red" 
 
switch value do 
  case "apple": 
  case "pear": 
  case "orange": 
    puts(1, "It's a fruit!\n") 
    break 
 
  case "yellow": 
  case "blue": 
  case "red": 
    puts(1, "It's a color!\n") 
    break 
 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end switch 
 
-- Output is "It's a color!" 

This is still the dumbest conditional construct I've ever encountered. Didn't the devs discover that in most cases, break will be used and, therefore, making it NOT default is the friendlier option?

I understand that your example above is not an optimal use case for switch, but I've never actually seen one either. Can you access the dev list archives? Maybe there was a convincing example there.

And isn't there a select construct available in 4.0? I thought I had seen and even used it. getlost

Anyway, why not something like this:

sequence 
   value = "red" 
  ,fruits = {"apple","pear","orange"} 
 
switch value do 
  case in fruits: 
    puts(1, "It's a fruit!\n") 
 
  case in {"yellow","blue","red"}: 
    puts(1, "It's a color!\n") 
 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end switch 
 
-- Output is "It's a color!" 

Even this if... statement is better than that stupid switch:

sequence 
    value = "red" 
   ,fruits = {"apple","pear","orange"} 
   ,colors = {"yellow","blue","red"} -- "orange" is valid here, too. grin 
 
if find(value,fruits) then 
   puts(1, "It's a fruit!\n") 
elsif find(value,colors) then 
    puts(1, "It's a color!\n") 
else 
    puts(1, "I have no clue what it is sad\n") 
end if 
 
-- Output is "It's a color!" 

By the way, it doesn't look like select or switch are documented in the Manual! Or did I just miss it? sad

new topic     » goto parent     » topic index » view message » categorize

10. Re: switch statement

Ok, and thanks for the examples, they help, at least for those of us who are just hobby programmers smile

Dan

new topic     » goto parent     » topic index » view message » categorize

11. Re: switch statement

jeremy said...

...I just did a benchmark, here are the results (I changed the puts to setting a message as not to have all sorts of IO hiding the timing):

C:\Develop>exwc switchifbench.ex 
  bench_switch: 0.063 
bench_if_equal: 0.187 
 bench_if_find: 0.344 

Okay, now I remember why it was a good idea. SPEEEEEEEEEED!!! grin

new topic     » goto parent     » topic index » view message » categorize

12. Re: switch statement

I like the "fall-through" effect of the switch statement. We use it all the time in wxEuphoria:

object WXEUAPI  new_wxSpinCtrl(object params) 
{ 
    wxWindowID id = -1; 
    wxString value = wxEmptyString; 
    wxPoint pos = wxDefaultPosition; 
    wxSize size = wxDefaultSize; 
    long style = wxSP_ARROW_KEYS; 
    int min = 0; 
    int max = 100; 
    int initial = 0; 
    wxDeRefDS( params ); 
    int len = ((s1_ptr)SEQ_PTR(params))->length; 
    switch( len ){ 
        case 11: 
            initial = get_int( params, 11 ); 
        case 10: 
            max = get_int( params, 10 ); 
        case 9: 
            min = get_int( params, 9 ); 
        case 8: 
            style = get_int( params, 8 ); 
        case 7: 
            size = wxSize( get_int( params, 6 ), get_int( params, 7 ) ); 
        case 6: 
        case 5: 
            pos = wxPoint( get_int( params, 4 ), get_int( params, 5 ) ); 
        case 4: 
        case 3: 
            value = get_string( params, 3 ); 
        case 2: 
            id = (wxWindowID) get_int( params, 2 ); 
        default: 
            wxSpinCtrl * spin = new wxSpinCtrl( (wxWindow *) get_int( params, 1 ), 
                id, value, pos, size, style, min, max, initial ); 
 
            return BOX_INT( spin ); 
    } 
} 

-Greg

new topic     » goto parent     » topic index » view message » categorize

13. Re: switch statement

euphoric said...
jeremy said...
sequence value = "red" 
 
switch value do 
  case "apple": 
  case "pear": 
  case "orange": 
    puts(1, "It's a fruit!\n") 
    break 
 
  case "yellow": 
  case "blue": 
  case "red": 
    puts(1, "It's a color!\n") 
    break 
 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end switch 
 
-- Output is "It's a color!" 

This is still the dumbest conditional construct I've ever encountered. Didn't the devs discover that in most cases, break will be used and, therefore, making it NOT default is the friendlier option?

And go against every other programming languages definition of a switch, I don't think that would be wise. Sure, we are not PHP, but people understand an if statement. What if we were to flip it around? People would be totally confused.

if 1=1 then 
  puts(1, "1 is not = 1\n") 
else 
  puts(1, "1 is 1\n") 
end if 

This is the same as changing the way switch works. It's totally foreign for the switch construct.

euphoric said...

I understand that your example above is not an optimal use case for switch, but I've never actually seen one either. Can you access the dev list archives? Maybe there was a convincing example there.

Um, actually my example of the colors, fruits, etc... is a valid construct for switch. There's nothing wrong with that example.

euphoric said...

And isn't there a select construct available in 4.0? I thought I had seen and even used it. getlost

No.

euphoric said...

Anyway, why not something like this:

sequence 
   value = "red" 
  ,fruits = {"apple","pear","orange"} 
 
switch value do 
  case in fruits: 
    puts(1, "It's a fruit!\n") 
 
  case in {"yellow","blue","red"}: 
    puts(1, "It's a color!\n") 
 
  case else 
    puts(1, "I have no clue what it is sad\n") 
end switch 
 
-- Output is "It's a color!" 

This takes away quite a bit of power from switch as you cannot do specific things based on one item. I was working up an example and then I saw that ghaberek just posted one...

said...

By the way, it doesn't look like select or switch are documented in the Manual! Or did I just miss it? sad

http://openeuphoria.org/docs/eu400_0010.html#_103_switchstatement

Jeremy

new topic     » goto parent     » topic index » view message » categorize

14. Re: switch statement

I like the switch statement, it's already saved me a tangle of if-statements.

I'd like to make a suggestion:

value = {1,2,3} 
switch value do 
 
case 1: -- code, break 
case (1+1): -- code runs if value = 2, break 
case (var - 12): -- code , break 
case (value < 4): -- if all the elements of value are < 4, break 
case (match("cow,value)): 
end switch 

Basically, if () are encountered, then call eval() to run the expression in the (). Besides, value is somewhat executeable in a sense, i do this in http.e, and it runs fine:

switch sendheader[idx][1] do  

And i believe it executes (to dig into sendheader) because nothing is known about sendheader at compile time except it's declared as a sequence.

How to make a select switch:

switch value do 
      case a: 
break case b: 
break case c: 
end switch 

Think of it as a new two-word keyword. I did not try it. Depending on the switch parser, it may loose it's footing and crash. Basic Eu doesn't care if "break" is on another or the same line, but i don't know where it sees "case" in the context of the stack of testable conditions. I just think of "break" as Pascal's ; eol tag:

case "GET": tempheader &= sendheader[idx][1] & sendheader[idx][2] & sendheader[idx][3] & " " & httpversion & "\r\n" break -- append the http version 

useless

new topic     » goto parent     » topic index » view message » categorize

15. Re: switch statement

Kat said...

I like the switch statement, it's already saved me a tangle of if-statements.

I'd like to make a suggestion:

value = {1,2,3} 
switch value do 
 
case 1: -- code, break 
case (1+1): -- code runs if value = 2, break 
case (var - 12): -- code , break 
case (value < 4): -- if all the elements of value are < 4, break 
case (match("cow,value)): 
end switch 

Basically, if () are encountered, then call eval() to run the expression in the ().

Future versions of switch may behave this way, or at least support more complex cases (no promises smile). One of the motivations of the current switch was to offer a faster and sometimes more expressive construct than the existing if-elsif-else option.

This sort of thing (executable code) would definitely remove a lot of the speed value, though obviously not the expressiveness.

Kat said...

Besides, value is somewhat executeable in a sense, i do this in http.e, and it runs fine:

switch sendheader[idx][1] do  

And i believe it executes (to dig into sendheader) because nothing is known about sendheader at compile time except it's declared as a sequence.

Yes, it's not really any different than any other use of a subscript. Basically, it creates a temp as the result of the subscript, and uses that value to direct the flow.

Kat said...

How to make a select switch:

switch value do 
      case a: 
break case b: 
break case c: 
end switch 

Think of it as a new two-word keyword. I did not try it. Depending on the switch parser, it may loose it's footing and crash. Basic Eu doesn't care if "break" is on another or the same line, but i don't know where it sees "case" in the context of the stack of testable conditions. I just think of "break" as Pascal's ; eol tag:

No, it doesn't care about line breaks. That's just a different type of white space, as far as the scanner/parser are concerned.

Matt

new topic     » goto parent     » topic index » view message » categorize

16. Re: switch statement

jeremy said...
said...

By the way, it doesn't look like select or switch are documented in the Manual! Or did I just miss it? sad

http://openeuphoria.org/docs/eu400_0010.html#_103_switchstatement

Shouldn't that be in the contents here: http://openeuphoria.org/docs/eu400_0029.html#_302_LanguageReference

I usually go to that page and do a search when I need to remind myself of something Euphoric. smile

new topic     » goto parent     » topic index » view message » categorize

17. Re: switch statement

jeremy said...

This takes away quite a bit of power from switch as you cannot do specific things based on one item. I was working up an example and then I saw that ghaberek just posted one...

P.S. I think his example is in C, not Euphoria.

new topic     » goto parent     » topic index » view message » categorize

18. Re: switch statement

euphoric said...
jeremy said...

This takes away quite a bit of power from switch as you cannot do specific things based on one item. I was working up an example and then I saw that ghaberek just posted one...

P.S. I think his example is in C, not Euphoria.

It doesn't matter, all the functions could be euphoria and switch works the same way. Do you see the logic behind how it's doing multiple different things w/one decision and only one?

That's the benefit, which extends to Euphoria as well due to fall through.

Jeremy

P.S. On the dev list right now we are discussing putting select into 4.0, which is a much limited switch (i.e. no fall through). However, I can see in some situations that it would be nice.

new topic     » goto parent     » topic index » view message » categorize

19. Re: switch statement

euphoric said...
jeremy said...
said...

By the way, it doesn't look like select or switch are documented in the Manual! Or did I just miss it? sad

http://openeuphoria.org/docs/eu400_0010.html#_103_switchstatement

Shouldn't that be in the contents here: http://openeuphoria.org/docs/eu400_0029.html#_302_LanguageReference

I usually go to that page and do a search when I need to remind myself of something Euphoric. smile

That page is a function reference. Maybe the title should be changed to be "Library Reference" instead of "Language Reference" now that you bring that up. Currently all language constructs are defined in the section "Euphoria Reference"

http://openeuphoria.org/docs/eu400_0006.html

Jeremy

new topic     » goto parent     » topic index » view message » categorize

20. Re: switch statement

jeremy said...

That page is a function reference. Maybe the title should be changed to be "Library Reference" instead of "Language Reference" now that you bring that up. Currently all language constructs are defined in the section "Euphoria Reference"

http://openeuphoria.org/docs/eu400_0006.html

The Euphoria Reference page isn't a comprehensive language index, which is what would be most useful to anybody wanting to search for a Euphoria func/proc. So if the Language Reference isn't that, we need one. smile

new topic     » goto parent     » topic index » view message » categorize

21. Re: switch statement

mattlewis said...
Kat said...

I like the switch statement, it's already saved me a tangle of if-statements.

I'd like to make a suggestion:

value = {1,2,3} 
switch value do 
 
case 1: -- code, break 
case (1+1): -- code runs if value = 2, break 
case (var - 12): -- code , break 
case (value < 4): -- if all the elements of value are < 4, break 
case (match("cow,value)): 
end switch 

Basically, if () are encountered, then call eval() to run the expression in the ().

Future versions of switch may behave this way, or at least support more complex cases (no promises smile). One of the motivations of the current switch was to offer a faster and sometimes more expressive construct than the existing if-elsif-else option.

This sort of thing (executable code) would definitely remove a lot of the speed value, though obviously not the expressiveness.

Would it be faster to eval() when and only when () are encountered, or code like this:

case 1:
case 2:
case 3:

vs

case (x<4):

useless

new topic     » goto parent     » topic index » view message » categorize

22. Re: switch statement

Can I throw in another little thing? I use the 'C' switch statement very frequently, and one of my 'C' language compilers supports this syntax:

   switch(x) 
   { 
      case 1,3,5,7: 
         printf("Odd\n"); 
         break; 
      case 8-15: 
         printf("Bit 3 set\n"); 
         break; 
      case y: 
         printf("x matches y\n"); 
    } 

Rather than the simple single-valued case, you can have multiples, ranges and variables. It seems to me that once there is the basic switch opcode implemented, to add these enhancements would not be beyond the wit of man, even if it is beyond my wit. I wish this was the ANSI version, then I'd see it more often and maybe it would be of greater importance to add it to the new Euphoria language. IMHO, of course.

Andy

new topic     » goto parent     » topic index » view message » categorize

23. Re: switch statement

euphoric said...
jeremy said...

This takes away quite a bit of power from switch as you cannot do specific things based on one item. I was working up an example and then I saw that ghaberek just posted one...

P.S. I think his example is in C, not Euphoria.

C actually, but it's a good example of a use for fall through.

Matt

new topic     » goto parent     » topic index » view message » categorize

24. Re: switch statement

Kat said...

Would it be faster to eval() when and only when () are encountered, or code like this:

case 1:
case 2:
case 3:

vs

case (x<4):

The first would probably be faster. If all cases are integers, then what happens when the switch happens, is that it first checks for the switching value's type. If it's not an integer, then it will end up at the case else (or after the entire switch, if there is no case else). If it is an integer, then if the difference between the largest and smallest is less than a certain value (1024, currently IIRC), then it uses a simple jump table, computed by the value of the integer (offset from the min value).

If the integers are too spread out, or if not all cases are integers, then it uses find() on the cases in combination with a jump table for the cases.

Assuming we were to implement your concept of a 'dynamic' switch, then I suspect they all might have to be evaluated. It might be possible to use the previous jump table, and if nothing there is found, then evaluate each remaining case in order, and jump if it evaluates as true. There might be better ways to do it.

Matt

new topic     » goto parent     » topic index » view message » categorize

25. Re: switch statement

Note how qbasic does it:

SELECT CASE Expression 
    CASE IS >= 5 
          ... 
    CASE 2 TO 4 
          ... 
    CASE 1 
         ... 
    CASE ELSE 
         ... 
END SELECT 

The "IS" token precedes complex expression, this way simple expressions get a fast processing.

Will be great if the switch can process sequences. But may become very complex like this

for i=1 to 5 do 
 
  select case my_sequence[i] 
  case "" 
    ... 
  case other_sequence[i] 
    ... 
  case else 
    ... 
  end select 
 

May be a very powerfull, but not easy to eval

new topic     » goto parent     » topic index » view message » categorize

26. Re: switch statement

achury said...

Will be great if the switch can process sequences.

The switch statement can do sequences...

  switch x do 
     case "first": 
          action1() 
          break 
     case "second": 
          action2() 
          break 
     case "another": 
          action3() 
          break 
     . . . 
 end switch 
new topic     » goto parent     » topic index » view message » categorize

27. Re: switch statement

mattlewis said...
euphoric said...

P.S. I think his example is in C, not Euphoria.

C actually, but it's a good example of a use for fall through.

Matt

That was my point, that you can see how useful it is in C. I'd be nice to be able to do such things in Euphoria.

-Greg

new topic     » goto parent     » topic index » view message » categorize

28. Re: switch statement

euphoric said...

Okay, now I remember why it was a good idea. SPEEEEEEEEEED!!! grin

Speed is no justification for a bad syntax (a "select" statement can be optimized just like a "switch"). Apart from that, an "if"-"elsif"-statement can be optimized into a jump table too.

new topic     » goto parent     » topic index » view message » categorize

29. Re: switch statement

Critic said...

Speed is no justification for a bad syntax (a "select" statement can be optimized just like a "switch"). Apart from that, an "if"-"elsif"-statement can be optimized into a jump table too.

Did you ignore everything else that was said in this thread?

Jeremy

new topic     » goto parent     » topic index » view message » categorize

30. Re: switch statement

Critic said...
euphoric said...

Okay, now I remember why it was a good idea. SPEEEEEEEEEED!!! grin

Speed is no justification for a bad syntax (a "select" statement can be optimized just like a "switch"). Apart from that, an "if"-"elsif"-statement can be optimized into a jump table too.

I generally agree with you. But there could be cases where speed trumps syntax, and this might be one. HOWEVER, apparently we can have a select statement that's just as optimized as a switch and defaults to break instead of fallthru. Hopefully we'll get that and everybody will be happy.

new topic     » goto parent     » topic index » view message » categorize

31. Re: switch statement

Critic said...
euphoric said...

Okay, now I remember why it was a good idea. SPEEEEEEEEEED!!! grin

Speed is no justification for a bad syntax (a "select" statement can be optimized just like a "switch"). Apart from that, an "if"-"elsif"-statement can be optimized into a jump table too.

Bad syntax is often subjective.

Not all if-elsif-else statements can be optimized this way (think side effectsbad practice, but still needs to be taken into account), but your statement is just referring to a trivial isomorphism between a switch and if-elsif-else blocks. By which I mean that all switches (that don't use fallthrough) can be trivially altered to be an if-elsif-else.

Matt

new topic     » goto parent     » topic index » view message » categorize

32. Re: switch statement

jeremy said...

Did you ignore everything else that was said in this thread?

Jeremy

No, I was trying to ensure people don't draw wrong conclusions about the speed argument - fallthrough does not enable the jump table optimization.

new topic     » goto parent     » topic index » view message » categorize

33. Re: switch statement

mattlewis said...

Not all if-elsif-else statements can be optimized this way (think side effectsbad practice, but still needs to be taken into account), but your statement is just referring to a trivial isomorphism between a switch and if-elsif-else blocks. By which I mean that all switches (that don't use fallthrough) can be trivially altered to be an if-elsif-else.

Well, if the compiler does common subexpression elimination, it is easy to optimize an if-elif-chain into a jump table. Speed is no justification for a switch/select statement nowadays, if you are going to have a proper optimizer anyway. But please get me right: I love "select"-statements. It's just that speed is no good argument to introduce them.

new topic     » goto parent     » topic index » view message » categorize

34. Re: switch statement

Critic said...

Well, if the compiler does common subexpression elimination, it is easy to optimize an if-elif-chain into a jump table. Speed is no justification for a switch/select statement nowadays, if you are going to have a proper optimizer anyway. But please get me right: I love "select"-statements. It's just that speed is no good argument to introduce them.

Um, speed was not at all the reason for implementing switch! In fact, when it was first introduced and decided on it was slower. I think in this thread you have had several examples of where a switch is less error prone than the current if/else syntax and more featureful due to fall-thru. Adding switch was never about speed nor optimizations. Many optimizations will be coming once we hit beta and further in 4.1.

I will say it again, because you might have missed it, but switch was decided to be added due to it being able to reduce the amount of work on the programmer. Fall thru was decided upon because it's the defacto standard for a switch statement, it's more powerful and we already have the capability of doing non-fall thru decisions.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

35. Re: switch statement

Critic said...
mattlewis said...

Not all if-elsif-else statements can be optimized this way (think side effectsbad practice, but still needs to be taken into account), but your statement is just referring to a trivial isomorphism between a switch and if-elsif-else blocks. By which I mean that all switches (that don't use fallthrough) can be trivially altered to be an if-elsif-else.

Well, if the compiler does common subexpression elimination, it is easy to optimize an if-elif-chain into a jump table. Speed is no justification for a switch/select statement nowadays, if you are going to have a proper optimizer anyway. But please get me right: I love "select"-statements. It's just that speed is no good argument to introduce them.

Yes, for certain if-elsif-else scenarios it's easy, which is exactly what I said (trivial isomorphism, etc, etc).

Speed is never a good reason to do anything, until you need it. And then it's a good thing.

Matt

new topic     » goto parent     » topic index » view message » categorize

36. Re: switch statement

jeremy said...

I will say it again, because you might have missed it, but switch was decided to be added due to it being able to reduce the amount of work on the programmer. Fall thru was decided upon because it's the defacto standard for a switch statement, it's more powerful and we already have the capability of doing non-fall thru decisions.

Well, firstly, "switch" is only standard for C-syntax based languages. EU is not one of them. Secondly, C's switch supports duff's device which I think EU's does not, so C's is still more powerful. Thirdly, I think of fall-through as a misfeature. But this is subjective, I aggree. Fourthly, Pascal's case supports ranges, "standard switch" does not, so one could argue that Pascal's case is more powerful.

new topic     » goto parent     » topic index » view message » categorize

37. Re: switch statement

Critic said...
jeremy said...

I will say it again, because you might have missed it, but switch was decided to be added due to it being able to reduce the amount of work on the programmer. Fall thru was decided upon because it's the defacto standard for a switch statement, it's more powerful and we already have the capability of doing non-fall thru decisions.

Well, firstly, "switch" is only standard for C-syntax based languages. EU is not one of them. Secondly, C's switch supports duff's device which I think EU's does not, so C's is still more powerful. Thirdly, I think of fall-through as a misfeature. But this is subjective, I aggree. Fourthly, Pascal's case supports ranges, "standard switch" does not, so one could argue that Pascal's case is more powerful.

I ask again, have you read any of this thread actually? Also, switch is only C based languages? how many have you used? Switch can be found all over, but who cares if it is from a C based language? I was not aware that we are bound by our lineage, that's a new rule to me in developing a language.

I'm going to suggest this again, please thread the thread. Any more silly questions/statements, I'm simply going to ignore, I have better things to do that to repeat what has already been said and demonstraighted.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

38. Re: switch statement

mattlewis said...

Speed is never a good reason to do anything, until you need it. And then it's a good thing.

Basically I aggree with your statement.

But I am quite fed up with the silly performance arguments in this forum. It seems to me that EU transforms O(1) operations into O(n) operations all the time for 16 years without anybody noticing. Sorry, I cannot believe anybody here considers performance seriously.

new topic     » goto parent     » topic index » view message » categorize

39. Re: switch statement

jeremy said...

I'm going to suggest this again, please thread the thread. Any more silly questions/statements, I'm simply going to ignore, I have better things to do that to repeat what has already been said and demonstraighted.

Read again. I said C syntax based languages. By which I basically meant curly braces. "Braces are the defacto standard, so lets introduce them." - Not a good argument, do you agree?

new topic     » goto parent     » topic index » view message » categorize

40. Re: switch statement

Critic said...
jeremy said...

I'm going to suggest this again, please thread the thread. Any more silly questions/statements, I'm simply going to ignore, I have better things to do that to repeat what has already been said and demonstraighted.

Read again. I said C syntax based languages. By which I basically meant curly braces. "Braces are the defacto standard, so lets introduce them." - Not a good argument, do you agree?

Um, switch is in all sorts of non { } languages. Also, I'd say that { } is a bad case for saying it's based on C (or, excuse me, syntax based on C).

Now, do I agree that we need to introduce { }, of course not that's even silly to draw a comparison to. Do I agree because C has an if statement (as do most other languages) that we should have an if statement? Sure, do you agree? Therefore, why say switch isn't valid in Euphoria!?!? I'm failing to see any logic in your reasoning.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

41. Re: switch statement

jeremy said...

Do I agree because C has an if statement (as do most other languages) that we should have an if statement? Sure, do you agree?

I say it's irrelevant what C has. Our objective is not to emulate or copy C, it's to make a language that is relatively easy to use for n00bs and yet has extremely powerful elements (no pun intended) that give experts lots of leeway when building programs.

If we have an if statement, it's because it's maximally functional and minimally inefficient.

Same with switch with fallthru. If we're going to have it, the positives have to outweigh the negatives. You say one of the positives is "many other languages use it that way," but consensus (or an appeal to numbers) is ultimately irrelevant when it comes to computer science. It is also easily countered with, "most instances of switch usage will use break, so break should be the default."

Anyway, in a battle of efficiency vs. tradition, efficiency always wins out in my book (unless the traditional method is the most efficient, of course smile).

new topic     » goto parent     » topic index » view message » categorize

42. Re: switch statement

euphoric said...

Same with switch with fallthru. If we're going to have it, the positives have to outweigh the negatives. You say one of the positives is "many other languages use it that way," but consensus (or an appeal to numbers) is ultimately irrelevant when it comes to computer science. It is also easily countered with, "most instances of switch usage will use break, so break should be the default."

The fact that many other languages have it is certainly a plus. There are many obscure languages that have some very nice features that are amazing when you learn to use them, but do they ever make it? No. Why? Because people don't want to learn something new, for the most part.

You can do all you want to make the perfect language. If it is too different or it doesn't have feature XYZ that 50 other languages have, you will fail.

The idea that other languages have it in masses is certainly a very valid reason. I don't want to be the only one using Euphoria. Nor do I want to be just a small group of people who are using Euphoria. I want Euphoria to appeal to the masses, how do you do that? You implement what the masses want and what the masses know.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

43. Re: switch statement

Critic: You seem to think you can compare "C" and Pascal's switch and select to Euphoria.

I thought that "C" and Pascal were compilers and Euphoria is an interpreter so how can you compare different optimization techniques that they use verses Euphoria.

new topic     » goto parent     » topic index » view message » categorize

44. Re: switch statement

Critic said...

Well, firstly, "switch" is only standard for C-syntax based languages. EU is not one of them. Secondly, C's switch supports duff's device which I think EU's does not, so C's is still more powerful.

Actually, euphoria's switch can do Duff's device. Here's the Stroustroup version from Wikipedia:

dsend(to, from, count) 
char *to, *from; 
int count; 
{ 
    int n = (count + 7) / 8; 
    switch (count % 8) { 
    case 0: do { *to++ = *from++; 
    case 7:      *to++ = *from++; 
    case 6:      *to++ = *from++; 
    case 5:      *to++ = *from++; 
    case 4:      *to++ = *from++; 
    case 3:      *to++ = *from++; 
    case 2:      *to++ = *from++; 
    case 1:      *to++ = *from++; 
               } while (--n > 0); 
    } 
} 
Here's a euphoria version (used the print operator instead of poking to memory, but demonstrates the interesting part of the device):

rocedure dprint( atom To, atom from, integer count ) 
    integer n = floor( (count+7) / 8 ) 
    switch remainder( count, 8 ) do 
	case 0:  
	loop do 
		? To & from To += 1 from += 1 
	case 7: 
		? To & from To += 1 from += 1 
	case 6: 
		? To & from To += 1 from += 1 
	case 5: 
		? To & from To += 1 from += 1 
	case 4: 
		? To & from To += 1 from += 1 
	case 3: 
		? To & from To += 1 from += 1 
	case 2: 
		? To & from To += 1 from += 1 
	case 1: 
		? To & from To += 1 from += 1 
	 
	n -= 1 
	until n <= 0 
    end switch 
end procedure 
Critic said...

Fourthly, Pascal's case supports ranges, "standard switch" does not, so one could argue that Pascal's case is more powerful.

Yes, though it could be merely syntactic sugar. With a large enough range, though, you probably need to (want to?) change from a simple jump table. We've talked about doing such a thing for euphoria.

Matt

new topic     » goto parent     » topic index » view message » categorize

45. Re: switch statement

Critic said...

But I am quite fed up with the silly performance arguments in this forum. It seems to me that EU transforms O(1) operations into O(n) operations all the time for 16 years without anybody noticing.

It seems that you are saying that every operation is transformed from a single action into multiple actions by Euphoria. If this is actually what you are saying, can you give me an example to help me understand your point of view?

new topic     » goto parent     » topic index » view message » categorize

46. Re: switch statement

mattlewis said...

Here's the Stroustroup version from Wikipedia:

dsend(to, from, count) 
char *to, *from; 
int count; 
{ 
    int n = (count + 7) / 8; 
    switch (count % 8) { 
    case 0: do { *to++ = *from++; 
    case 7:      *to++ = *from++; 
    case 6:      *to++ = *from++; 
    case 5:      *to++ = *from++; 
    case 4:      *to++ = *from++; 
    case 3:      *to++ = *from++; 
    case 2:      *to++ = *from++; 
    case 1:      *to++ = *from++; 
               } while (--n > 0); 
    } 
} 

That makes my head hurt. sad

-Greg

new topic     » goto parent     » topic index » view message » categorize

47. Re: switch statement

DerekParnell said...
achury said...

Will be great if the switch can process sequences.

The switch statement can do sequences...

  switch x do 
     case "first": 
          action1() 
          break 
     case "second": 
          action2() 
          break 
     case "another": 
          action3() 
          break 
     . . . 
 end switch 

I'd still like to see this construct
without "do" and ":" :

  switch x 
     case "first" 
          action1() 
          break 
     case "second" 
          action2() 
          break 
     case "another" 
          action3() 
          break 
     . . . 
 end switch 


Looks much better (on my ultra conservative taste) smile

Regards,
Igor Kachan
kinz@peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

48. Re: switch statement

kinz said...

I'd still like to see this construct without "do" and ":" :

  switch x 
     case "first" 
          action1() 
          break 
     case "second" 
          action2() 
          break 
     case "another" 
          action3() 
          break 
     . . . 
 end switch 

Looks much better (on my ultra conservative taste) smile

I can agree with this. We don't have "if/do" we have "if/then". And "switch" is not a loop construct like "for/do" or "while/do". I think "switch/case" is all we need.

-Greg

P.S. Igor, you do not need to insert line breaks manually in your messages. A single empty line will create a new paragraph.

new topic     » goto parent     » topic index » view message » categorize

49. Re: switch statement

kinz said...

I'd still like to see this construct without "do" and ":"

The colon is already optional. I'll think through the optional 'do' a bit more.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu