[REBOL] Re: [SELECT SWITCH CASE] SELECT-CASE
From: lmecir::mbox::vol::cz at: 8-Sep-2006 9:22
Gregg Irwin napsal(a):
> LM> OK, here is the improved version, which I am proposing to Carl too:
>
> LM> REBOL [
> LM> Author: ["Ladislav Mecir" "Gabriele Santilli"]
> LM> Purpose: "A SWITCH alternative, see example"
> LM> ]
>
> LM> switch1: func [
> LM> "Selects a choice and evaluates the first block that follows it."
> LM> [throw]
> LM> value "Value to search for."
> LM> cases [block!] "Block of cases to search."
> LM> /default case [block!] "Default case if no others are found."
> LM> ][
> LM> if value: find cases value [value: find next value block!]
> LM> do either value [first value] [case]
> LM> ]
>
> LM> example: [
> LM> switch1 1 [2 4 6 ['even] 1 3 5 ['odd]]
> LM> ]
>
> My only concern is that it's a significant semantic change from the
> current behavior, so it could break code. That said, I know *my* brain
> always wants to think of SWITCH and SELECT as working against an
> implied "/SKIP 2" refinement, which is not the case.
>
> I don't think it will break much, if any, code, but the potential is
> there. Ignoring compatibility, I think it's a much more powerful
> model, and clearer in intent. That is, it makes it obvious that the
> distinction is between non-block values (tests) and blocks (actions).
>
> I would vote for this change, because we also have the CASE function
> (a recent addition); that *does* support the condition-action model.
>
> Let me add another thought to the mix. Coming from BASIC dialects, I
> can tell you that the SELECT CASE statement was very useful (IMO). I
> mention it because it supports the same concept of testing multiple
> values as SWITCH1 that Ladislav posted.
>
> Here is an example for those not familiar with it:
>
> SELECT CASE string_expression
> CASE > b$ ' relational; is expression > b$?
> ' <action>
> CASE "X" ' equality (= is assumed); is expression equal
> ' to "X"?
> ' <action>
> CASE "A" TO "C" ' range; is expression between "A" and "C"
> ' (inclusive)?
> ' <action>
> CASE "Y", b$ ' two equality tests; is expression equal to
> ' "Y" or equal to b$?
> ' <action>
> CASE "A" TO "C","Q" ' combination range and equality; is
> ' expression between "A" and "C" (inclusive)
> ' or equal to "Q"?
> ' <action>
> CASE ELSE
> ' <action>
> END SELECT
>
> In REBOL, tests might look like this:
>
> select-case expr [
> :negative? value [] ; value ref's 'expr
> < 3 []
> case is < 5 []
> 6 to 10 []
> between 11 and 15 []
> from 16 to 20 []
> 21 23 25 []
> [find [22 24] value] [] ; value ref's 'expr
> 26 to 100 or 175 []
> case is > 1000 []
> case else []
> ]
>
> The implementation won't be as concise as the current SWITCH approach,
> but the idea is that a small dialect can save us a lot of work and
> make our application code more readable. How to reference the value
> (expr) is something to think about, where it's always implied in
> BASIC.
>
> The other concept this ties into is ranges and bounds. I've mentioned
> that a few times before, so I won't go into it here again, but I think
> that's another powerful model worth considering in REBOL.
>
> -- Gregg
>
Thanks for your ideas! Anybody knowing his code would suffer when using
the new SWITCH version speak now or remain silent forever ;-).
-L