Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] [SELECT SWITCH CASE] SELECT-CASE (was: The best shortcut word for "not none?")

From: greggirwin::mindspring::com at: 6-Sep-2006 11:49

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