Rogue 'select' (AKA Decision/Ternary Operator)
One thing that's been missing in Slag/Bard/Rogue over the years is an equivalent to the decision operator AKA ternary operator, e.g.
// C++
printf( "The switch is %s.\n", setting ? "ON" : "OFF" );
Today I finally added something comparable to Rogue. It's called the select
operator and in its most basic form it looks like this:
# Rogue
println "The switch is $." (select{setting:"ON","OFF"})
The way to read it is "if setting then ON, for any other condition OFF."
When there are three or more possible values to choose between, select
has a distinct advantage over its counterpart in terms of clarity:
// C++
int sign = ((value==0) ? 0 : ((value>0) ? 1 : -1));
# Rogue
local sign = select{ (value==0):0, (value>0):1, -1 }
The default value for "no other match" is always at the end of the set. It cannot have a general condition and all other values must have a condition.
The default value can have a special condition prefix of others:
, in the style of Rogue's which-case-others:
local sign = select{ (value==0):0, (value>0):1, others:-1 }
Note that the select
command is using a syntax reminiscent of JSON table {key:value,...}
syntax.
select
can also operate in a style similar to a which
(AKA switch).
// C++
printf( "%s\n", (people==1) ? "One's no fun"
: ((people==2) ? "Two's company" : "Three's a crowd" ) );
# Rogue
println select(people){ 1:"One's no fun", 2:"Two's company",
others:"Three's a crowd" }
select
lets you list several comma-separated conditions per value:
# Rogue
forEach (ch in "now is the time")
println "$ is a $" (ch, select(ch){ 'a','e','i','o','u':"vowel",
' ':"space", others:"consonant"})
endForEach
There's nothing preventing the parameter-based select
from working with string comparisons etc., so as a final step we can now achieve the effect of making little lookup-tables on the fly without actually allocating any additional objects:
# Rogue
local color_index = select(color){ "red":0, "yellow":1,
others:2 }