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 }