1. How to use switch with ranges?
- Posted by irv Sep 21, 2010
- 1302 views
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?
2. Re: How to use switch with ranges?
- Posted by CoJaBo Sep 21, 2010
- 1212 views
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
3. Re: How to use switch with ranges?
- Posted by DerekParnell (admin) Sep 21, 2010
- 1216 views
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
4. Re: How to use switch with ranges?
- Posted by mattlewis (admin) Sep 21, 2010
- 1245 views
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