Relationship between SWITCH and CASE


#1

Over time, the code for SWITCH and CASE has become more similar...notably when evaluative SWITCH was introduced.

One thing that's not similar about them is that case works in pairs, while SWITCH seeks out BLOCK! specifically to execute. This permits writing things like:

switch type of value [
    word! [print "Word"]
    binary! text! [print "Either binary or text"]
    ...
]

switch port/verb [
    'closed [print "closed"]
    'wrote 'read [print "data transferred..."]
    ...
]

It's nice and kind of C inspired, where case labels in a switch can fall through to each other. But it becomes a bit inconsistent...you can't use ACTION! or QUOTED! branches as you can in other conditionals. And CASE and SWITCH can't share (much) code.

As a thought experiment, though...if we went with strict pairing with predicates, we might have another way of saying this:

 switch value .matches [
     word! [print "Word"]     
     [binary! integer!] [print "Binary or integer"]
     ...
]

That would imply that SWITCH and CASE could be powered by the same native. It's just that SWITCH would be taking a predicate with two arguments and specializing it down to a function with just one argument to run as the CASE's predicate.

Problem 1 (generally of MATCH with SWITCH): DEFAULT

Unfortunately this tampers with the DEFAULT trick. Right now, MATCHES quotes its right hand side literally...it wants to see the number of lit marks on a type so that 'word! matches quoted words, so match 'word! first ['x] is true. But if it quotes the cases inside the switch, it would quote DEFAULT also.

This might suggest that MATCH is getting too carried away with its quoting shenanigans, and you should have to say match ['word!] first ['x] or match quote word! first x (or match ''word! first x if you are sure your readers would know what you're doing). And maybe quote-word! or q-word! should be a type for good measure. (I've explained why LIT is a bad name.)

Problem 2: no operator for "in block or standalone"

We don't really have an operator like is-member-of where 5 is-member-of [5 6] is true, and 5 is-member-of 5 is also true. Such a thing would be needed for that second case:

 switch port/verb .is-member-of [
    'closed [print "closed"]
    [wrote read] [print "data transferred..."]
    ...
]

It's a need that comes up fairly often, and when it does people usually make a block out of single items and then search the block.

So not going to replace SWITCH, but a useful pattern

Seeing that specialization and predicates on CASE can make a switch-like thing is important to note.