Re: switch statement
- Posted by jeremy (admin) Mar 25, 2009
- 1373 views
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