Sorry to come so late to the thread, but if I may play devil's advocate for a moment before I get serious?
If you add a IFF(cond, expr1, expr2) type of operator, can it be defined so that
let expr = null
let x = iff(expr, 10, 20)
yields null? it's only consistent, and I think more correct. If people want to avoid that, then of course the suggested NVL function will help them:
iff(nvl(expr, false), 10, 20)
So rewriting Reuben's IFF function, I would have written:
function IFF(cond, x, y)
case cond
when cond != false return x
when cond == false return y
otherwise return null
end case
end function
(I am using tests against false (aka zero) just so that cond can actually be any non-zero number for truth)
Also the point about both x and y being evaluated before the call is definitely a problem so I'm not a fan of this type of work-around function.
What's more curious to me is the apparent fear of NULL that is so common both in my company and around the world. I agree, the null-behaviour of || is kind-of annoying, but technically it's more correct, and I must confess that the annoyance factor is only because I'm so used to the polite but technically inappropriate behaviour of the comma concatenate operator.
I don't understand the need to "code around" the so-called null problem. I find that null's behaviour is great for REDUCING code. There are a few simple tricks that help:
if a >= b or a is null or b is null then DO_WORK end if
becomes
if a < b then else DO_WORK end if
This is a trivial trick for inverting the flow and reducing code when you need it. The sample CASE statement in my function above is also often surprising to many people but it's a great technique. A built-in NVL would be fantastic because it could return the real object with it's original data type instead of all being converted to a string. A built-in IFF() would be nice - how's about allowing more pairs too?
iff(c1, r1, c2, r2, c3, r3, e1)
for an elif effect.
There is one critical point I would like to make about the choice of operator: I do not like the suggestion that the keyword IF be used as a function. We are writing a lot of code-metric scripts, so having to cope with a STATEMENT keyword as a possible operator would play havoc with the parsers. I know that 4GL and SQL are not supposed to have keywords as such, but seriously, I'm sure we're not the only company on the planet writing ad-hoc parsers for 4GL. PLEASE do not use the IF keyword!
Why not use the world-standard ternary operator
?: from C? Neither
? nor
: are important tokens in 4GL
let x = cond ? a : b
call ftn(cond ? a : b, c, d)
looks fine to me. If you choose to go this way, could I also request that you resist the temptation to make it ass-backwards like Python's inline
a if cond else b rubbish? There's merit in copying the style of the familiar rather than trying to be too clever...
Finally, a built-in concat() operator would be very nice and would increase overall comfort.
Just my 2 pfennigs worth.