Variation of C's inline conditional

The C language has an inline conditional statement, in the form:
condition ? exprA : exprB
Now, many times exprA is a component of the condition, for example:
(somebigexpression) != 0 ? (somebigexpression) : (defaultexpression)

I'm looking for a form of the inline conditional that doesn't repeat the "somebigexpression" in the above situation, without assigning it to an intermediate variable. I was thinking something along the lines of this syntax:
(somebigexpression) !=? 0 : (defaultexpression)
where if the "?" follows a comparison operator, then if true it will return the left side of the comparison; else it returns the right side of the ":".

So two questions... 1) Would this be useful enough in practice to bother adding it to a language (i.e., does it make the code more clear v.s. assigning the original expression to a temp variable)? and 2) Does another language already have a syntax that accomplishes the same thing that I can borrow from?


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Scheme's cond form allows something like this, defined here

Your example could be compared to

(cond ((somebigexpression)  => id)
      (else defaultexpression))

Really, though, if somebigexpression is textually big, it should be broken up and stored in a variable or name binding for the sake of legibility.


By "somebigexpression", I was referring to a possibly long-running expression, maybe a function call with possible side effects. But even then, it may be better to store the result in a temp variable... I'll have to run through a few code samples to see what looks best.
Now I need to figure out how this would look in an infix-style language.



(or some-big-expression default-expression)

if your are testing for #f.

Scheme has something like that

Scheme's COND is essentially a sequence of predicate-consequent pairs with an optional else at the end. But in place of a simple pair you can use predicate => consequent instead. In that case, rather than just returning the value of the consquent, that value (which must be a procedure) is applied to the value of the predicate (any value other than false is accounted true in Scheme), and the result of the procedure call is returned instead.

An example is where the predicate is a call to ASSOC (a Scheme function that searches a list of key-value pairs for a given key, and returns the first matching key-value pair, or false if there is none). A useful consequent-predicate in that case is CDR, which retrieves the value from the pair.

C# has something like that too

Just for checking for null, not zero. Syntax is:

 (somebigexpr) ?? (default)

meaning, the result of (somebigexpr) unless it is null, in which case the result of (default).

?? looks like I'm in trouble

In 2e, I'm using the ?? symbol as an iterative inline conditional, so it looks like I already have a token conflict...
condition ?? trueloop : false_expr
where trueloop executes as long as condition is true, and false_expr gets executed only if the condition wasn't initially true (the final value trueloop expression value (or false_expr) gets returned as the entire expression's return value).
Hopefully I won't get too may complaints, otherwise I'll have to figure out a different symbol to use for my iterative conditional.


It looks like your specific example can be phrased:

(somebigexpression) || (defaultexpression)

.. abuse of logical operators? Probably. Common idiom in every programming language? As far as I know.

I know that's not the whole story: sometimes a test for false isn't enough, sometimes you have a pipeline of functions to apply until the first one returns false .. perhaps there's an ideal basis to express all of this but I haven't found it yet.

Not standard C,

but GCC has (in both C++ and C) a nonstandard extension that has exactly the semantics you want:

A ternary conditional which omits the center expression, i.e.

expr1 ? : expr2

has the following semantics: The expression expr1 is evaluated; and if it converts to true ( is true, a nonzero number or char, a non-NULL pointer, or an object implementing operator bool which returns true); it is returned; otherwise the value of expr2 is returned.

Note that expr1 is evaluated exactly once, and expr2 is evaluated if and only if expr1 is false.

See this doc page for more information (this page is for 4.3.0, which just was released, but older versions of GCC have supported this extension for years. Certain compiler flags (such as -ansi) may disable this extension; consult the manual for details.

Don't know if any other C/C++ compilers (MS, etc) support this extension or not.

not beautiful but DRY.

isn't this the same?

#define IFF(x,y) x != 0 ? x : y

Ruby does this and a little more using || and ||=, (and others)
I have found that it is clearer to use these operators than to expand them.

Not the same

That macro causes x to be evaluated twice, if true.

I'm not aware of any way to write an abstraction with the required semantics in standard C/C++; you want the first argument (x) to be strict, but the second argument (y) to be lazy. Arguments to functions are always strict in C/C++, so you can't use a function (including a class member function). Laziness is possible with C/C++ macros; but since they use call-by-name they don't memoize--and in general, macros which introduce a new scope cannot return values.

Would this work better?

#define IFF(x,y) { int _x = x; _x ? _x : y; }

I'm not sure if there return value of a C block is the always the value of last statement of the block, but this solves the multiple evaluation of x problem the original definition had...

I'd test it but my cygwin is broken right now. Correct me if I'm wrong.

[correction: I was wrong ;-) or at least you can't 'return' a block statement like that...unfortunate. I'm getting too used to lisp. ]

This expression form would

This expression form would work only in GCC compilers:

#define IFF(x,y) { int _x = x, _x ? _x : y }

It's a GNU extension.


I think D exposed c?:b, meaning "c? c: b". In C++, you could also redefine "a||b" to mean "a? a: b", which agrees with the existing bool operator||(bool,bool), but naturally extends to any type that has a conversion to bool. Also, see Icon, which does some even more interesting stuff separating conditional failure from boolean values.

Overloading operator || does not work here.

Overloaded versions of operator && and ||, like any other overloaded binary operators in C++, are eager in all their arguments (whereas the default versions of || and &&, applied to booleans, are both lazy operators.

Quite a few writers on C++ topics suggest avoiding the overloading of && and || for this reason.

Now, if strictness is OK, then overloading || will suffice. But often times, the point of these conditionals is that they are lazy.

Groovy also

Groovy also has ?:, with a ?: b equivalent to a ? a : b. (In fact, early mailing list remarks left me with the impression that it actually was implemented in a way that evaluated a twice.)

Trivia: Groovy folk refer to this as the Elvis operator.