Historically Rebol used ? as a synonym for HELP.
I type the unshifted sequence h-e-l-p as fast (maybe faster) than the combined sequence shift-/ to get the ?. Not only that, a console dialect could just as easily take H for help as it could take Q for QUIT, while keeping these abbreviations out of the language itself.
So considering the rare number of single-character sequences and symbols available, it seemed a waste to steal ? away from some purpose you would actually find common use for in user code.
My first idea was that since we use things suffixed with a ? to mean a logical test for something, why not make a lone question mark some very common existential test? My first idea was to make it a quoting operator testing variables for void, so that ? var could mean set? 'var.
if ? var [
print "var is set"
] else [
print "var is not set"
]
One thing that worried me is that if? var [...] is different, meaning "give me back a LOGIC! of whether you ran the branch or not, don't give me the branch-result-or-a-void". But, that's hardly the only space-significance issue out there, and one of the least surprising. Also, I doubt people will be using IF? all that often. I really haven't needed to use it yet. :-/
UPDATE circa 2018: The IF?, CASE?, SWITCH? etc. variants no longer exist, due to better ideas.
I still think this operator choice is a pretty good idea. I've tried other things, like seeing what could be done with it as a postfix operator, like it was punctuating with a question mark. But never felt like using that. However, I would certainly use ? var a lot... every day.
But how do other languages use it? C-inspired languages make it a ternary operator, which when combined with a : becomes more-or-less an EITHER. So:
x = condition ? expr1 : expr2;
Is basically equivalent to:
x: either condition [expr1] [expr2]
x: if condition [expr1] else [expr2]
While we can do some magic with variadics these days, Rebol doesn't encourage constructs that scan ahead for other delimiters. (Notably, that is not how THEN or ELSE work, which is part of what makes them awesome.)
So I don't know if doing a ternary operator would be very good. However, with the recent advances in left-hand-non-tight-enfix--and the death of the old meaning of IF/ONLY as "block means block", we might consider an infix binary operator to take its place.
>> x: 1 < 2 ? [data]
== [data]
>> x: 1 > 2 ? [data]
; no result
It would then share heritage with the ternary operator in the sense of being conditional, but bring something to the table that IF does not with the "return the right hand side as-is" property.
spaced ["(CONSOLE" (unless proto-skin/updated? {not}) "updated)"]
=>
spaced ["(CONSOLE" (not proto-skin/updated? ? {not}) "updated)"]
Well, maybe. It does run up against that question of whether 0-arity things should end in ?. If they do, this will create a bit of visual unhappiness with postfix operators called ?. But what if it wasn't like that?
spaced ["(CONSOLE" (not proto-skin/updated ? {not}) "updated)"]
Something to think about.
Digging around in other languages, Haskell leaves it a legal operator for you to define how you wish (so does Rebol, you could still override it if you want). Rust calls it a "unary suffix operator which can be placed on an expression to unwrap the value on the left hand side of ? while propagating any error through an early return", or at least proposed to be one. That doesn't have a parallel in Rebol's world exactly.
What do people think? I definitely don't think this should be wasted on a help synonym, at the detriment to all code everywhere...