1. How to use switch with ranges?

Suppose I need to write something like:

switch age do 
     case 1..20 then msg = "No Beer!" 
     case 21..30 then msg = "check dress code" 
     case 31..50 then msg = "suggest they try the veal" 
     case 50.. 

You get the idea Is there a range or set or ? function to do this in eu 4.0?

new topic     » topic index » view message » categorize

2. Re: How to use switch with ranges?

This isn't really the point of the switch statement, as it is for selecting a known set of constant values (and is optimized to do this very fast). You would use the if statement instead for ranges.

If you have small ranges with multiple (discrete) values, you could use this syntax:

switch version do
	case 0,1 then 
	    msg="<1: Ancient"  
	case 2,3 then 
	    msg="2-3: Please upgrade"  
	case 4 then 
	    msg="4: You have the current version"  
	case else 
	    msg="Unsupported version"  
end switch 
new topic     » goto parent     » topic index » view message » categorize

3. Re: How to use switch with ranges?

irv said...

Suppose I need to write something like:

switch age do 
     case 1..20 then msg = "No Beer!" 
     case 21..30 then msg = "check dress code" 
     case 31..50 then msg = "suggest they try the veal" 
     case 50.. 

You get the idea Is there a range or set or ? function to do this in eu 4.0?

There is a proposal to enhance the switch syntax to cater for some common shorthand sets but it is not likely to make the initial v4 release. However for now you can use the longhand way of doing this, but with the number of cases you are suggesting, it might be slower than a simple 'if' statement ...

switch age do 
     case 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 then msg = "No Beer!" 


The proposed syntax enhancements are ...

  case x to y [by z] then -- Similar to the 'for' statement 
  case in s then -- where the target value is an element of the sequence 's' 


But remember that these are only proposals and are not certain to ever implemented. The purposes of the switch statement include being a faster if statement for non-trivial sets of values so if these proposals can't be implemented as being faster than the equivalent 'if' they might not make it into the language.

The current switch is sort of equivalent to this ...

procedure age_case_A() 
msg = "No Beer!"  
end procedure 
 
procedure age_case_B() 
msg = "check dress code"  
end procedure 
 
procedure age_case_C() 
msg = "suggest they try the veal"  
end procedure 
 
constant ages = {1,2,3,4,5,6,7,8,9,10,11 ... 50} 
constant ageproc = {routine_id("age_case_A"), ... routine_id("age_case_C")} 
res = find(age, ages) 
if res then 
   call_proc( ageproc[res], {}) 
else 
   -- do 'case else' stuff 
end if 


So you could do something similar for your situation, maybe using maps.

procedure age_case_A() 
msg = "No Beer!"  
end procedure 
 
procedure age_case_B() 
msg = "check dress code"  
end procedure 
 
procedure age_case_C() 
msg = "suggest they try the veal"  
end procedure 
 
procedure age_case_else() 
msg = "???"  
end procedure 
 
object agemap = map:new() 
procedure init_age_map() 
 -- Only run once at application start up. 
 for i = 1 to 20 do 
   map:put(agemap, i, routine_id("age_case_A")) 
 end for 
 for i = 21 to 30 do 
   map:put(agemap, i, routine_id("age_case_B")) 
 end for 
 for i = 31 to 50 do 
   map:put(agemap, i, routine_id("age_case_C")) 
 end for 
end procedure 
 
... 
-- When you need to test the 'age' var. 
res = map:get(agemap, age, routine_id("age_case_else")) 
call_proc( res, {}) 


But if I were coding this today I'd use an 'if' ...

if age < 1 then 
   msg = "???" 
elsif age < 21 then 
   msg = "No beer" 
elsif age < 31 then 
   msg = "check dress code" 
elsif age < 51 then 
   msg = "suggest they try the veal" 
else 
   msg = "???" 
end if 
new topic     » goto parent     » topic index » view message » categorize

4. Re: How to use switch with ranges?

DerekParnell said...
irv said...

Suppose I need to write something like:

switch age do 
     case 1..20 then msg = "No Beer!" 
     case 21..30 then msg = "check dress code" 
     case 31..50 then msg = "suggest they try the veal" 
     case 50.. 

You get the idea Is there a range or set or ? function to do this in eu 4.0?

There is a proposal to enhance the switch syntax to cater for some common shorthand sets but it is not likely to make the initial v4 release. However for now you can use the longhand way of doing this, but with the number of cases you are suggesting, it might be slower than a simple 'if' statement ...

I doubt that it would be slower (at least, probably not enough to notice). With integers, the switch is really fast, since it uses a jump table (there's a subtraction operation to adjust for the minimum value, too). The super optimized version will work for integers whose max and min are no more than 1024 apart. An optimized if statement, where most of the cases end up in the first clause may beat this, but again, probably not by a noticeable amount.

If you mix in doubles or sequences, or a wide range of integers, you basically are left with using find() to determine the correct jump offset. When translated, the optimized version uses a native C switch statement, and the non-optimized version uses a combination of find() plus a switch statement.

Matt

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

Search



Quick Links

User menu

Not signed in.

Misc Menu