Note: This post was originally written to use REFINEMENT! for the predicates. However, generalized TUPLE! has seemed more favorable, so that's what's used when talking about it now...even though generalized tuples do not exist at time of writing.
It's a bummer that all the Rebol functions like SWITCH or FIND use some kind of internal magic operator to decide if things are equal. We'd like that operator to be less opaque and more clearly documented and understandable, and it's in the long to-do-list... to try and figure out how it ties into IS-ness or MATCH-ness or whatever it is.
Still, no matter what the default is, we know we need a way to override it. Ren-C had added a /STRICT refinement to SWITCH to deal with this case:
>> switch 0.01 [1% [<pretty lax...>] 0.01 [<stricter>]] <pretty lax...> >> switch/strict 0.01 [1% [<pretty lax...>] 0.01 [<stricter>]] <stricter>
But the name "strict" wasn't something super agreed upon. And it's just the tip of the iceberg, you kind of want to pass in more functions. That seems kind of ugly.
>> switch/compare 0.01 [1% [<pretty lax...>] 0.01 [<stricter>]] :== <stricter>
Fancy New Experiment: Skippable Refinements that ARE the compare!
Dig this (and it will look even better when EQUAL? and = are strict by default, and IS is the lax operator...)
>> switch 0.01 [1% [<pretty lax...>] 0.01 [<stricter>]] <pretty lax...> >> switch 0.01 /strict-equal? [1% [<pretty lax...>] 0.01 [<stricter>]] <stricter> >> switch 0.01 /== [1% [<pretty lax...>] 0.01 [<stricter>]] <stricter>
There's a skippable slot for a "refinement" (blank-headed PATH!) between the thing you're switching on and the cases block. And it looks up to an ACTION!.
It also accepts literal ACTION!s. You won't/can't type that in by hand...but that means if you're doing an APPLY there's a normal frame slot for your compare to go into. (It's one of the nice things about skippable parameters being knownst to the system in a way that variadic parameters are not.) If you need a SWITCH variation with a different interface you can make one out of this one.
Notice that the interpretation puts the switched-on expression on the left or in the first argument.
>> x: 10 == 10 >> switch x /greater? [20 [<nope>] 5 [<yep>]] == <yep>
Before we go propagating the idea all over the system, why not give this a spin. Kick the tires a bit. Write some tests!
>> x: 10 >> switch x /(reduce pick [:greater? :lesser?] 1) [20 [<a>] 5 [<b>]] == <b> >> switch x /(reduce pick [:greater? :lesser?] 2) [20 [<a>] 5 [<b>]] == <a>