How will comparison operators (spaceship operator) be handled in ternary operators - ternary-operator

This question is a little preemptive, as php 7 is not even released yet. I'm curious how the spaceship operator will be handled in the context of ternary operators.
so if I have a pre-spaceship ternary expression such as:
$foo = 1;
$bar = 0;
echo 'foo is ' . ( ($foo > $bar) ? 'greater than' : ( ($foo < $bar ) ? 'less than' : 'equal to' ) ) . ' bar.';
what would be the equivalent ternary operator using a comparison operator? Are ternaries going to have some means of handling this scenario? I use ternary operators quite a lot and am curious if there is some way to streamline the code in various instances where a comparison operator would be relevant.

The spaceship operator, as you can see from the documentation of its RFC, was though mainly to be used when having to deal with orderings.
I don't think it could be of help in shortening the code that you posted, mainly beacuse the ternary operator expects a boolean value and the ternary operator returns a "true" value (1 and -1) in both cases when the the values are different. In other words, when you cast its return value to a boolean, the spaceship operator is equivalent to the != operator.
Anyway, you could experiment with it on 3v4l.org, like I did here

Related

To ternary or not to ternary? [closed]

I'm personally an advocate of the ternary operator: () ? : ; I do realize that it has its place, but I have come across many programmers that are completely against ever using it, and some that use it too often.
What are your feelings on it? What interesting code have you seen using it?
Use it for simple expressions only:
int a = (b > 10) ? c : d;
Don't chain or nest ternary operators as it hard to read and confusing:
int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;
Moreover, when using ternary operator, consider formatting the code in a way that improve readability:
int a = (b > 10) ? some_value
: another_value;
It makes debugging slightly more difficult since you can not place breakpoints on each of the sub expressions. I use it rarely.
I love them, especially in type-safe languages.
I don't see how this:
int count = (condition) ? 1 : 0;
is any harder than this:
int count;
if (condition)
{
count = 1;
}
else
{
count = 0;
}
edit -
I'd argue that ternary operators make everything less complex and more neat than the alternative.
Chained I'm fine with - nested, not so much.
I tend to use them more in C simply b/c they're an if statement that has value, so it cuts down on unnecessary repetition or variables:
x = (y < 100) ? "dog" :
(y < 150) ? "cat" :
(y < 300) ? "bar" : "baz";
rather than
if (y < 100) { x = "dog"; }
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; }
else { x = "baz"; }
In assignments like this, I find it's less to refactor, and clearer.
When I'm working in ruby on the other hand, I'm more likely to use if...else...end because it's an expression too.
x = if (y < 100) then "dog"
elif (y < 150) then "cat"
elif (y < 300) then "bar"
else "baz"
end
(although, admittedly, for something this simple, I might just use the ternary operator anyway).
The Ternary ?: operator is merely a functional equivalent of the procedural if construct. So as long as you are not using nested ?: expressions, the arguments for/against the functional representation of any operation applies here. But nesting ternary operations can result in code that is downright confusing (exercise for the reader: try writing a parser that will handle nested ternary conditionals and you will appreciate their complexity).
But there are plenty of situations where conservative use of the ?: operator can result in code that is actually easier to read than otherwise. For example:
int compareTo(Object object) {
if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
return 1;
if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
return -1;
else
return 0;
}
Now compare that with this:
int compareTo(Object object) {
if(isLessThan(object))
return reverseOrder ? 1 : -1;
else(isGreaterThan(object))
return reverseOrder ? -1 : 1;
else
return 0;
}
As the code is more compact it there is less syntactic noise, and by using the ternary operator judiciously (that is only in relation with the reverseOrder property) the end result isn't particularly terse.
It's a question of style, really; the subconscious rules I tend to follow are:
Only evaluate 1 expression - so foo = (bar > baz) ? true : false, but NOT foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
If I'm using it for display logic, e.g. <%= (foo) ? "Yes" : "No" %>
Only really use it for assignment; never flow logic (so never (foo) ? FooIsTrue(foo) : FooIsALie(foo) ) Flow logic in ternary is itself a lie, ignore that last point.
I like it because it's concise and elegant for simple assignment operations.
Like so many opinion questions, the answer is inevitably: it depends
For something like:
return x ? "Yes" : "No";
I think that is much more concise (and quicker for me to parse) than:
if (x) {
return "Yes";
} else {
return "No";
}
Now if your conditional expression is complex, then the ternary operation is not a good choice. Something like:
x && y && z >= 10 && s.Length == 0 || !foo
is not a good candidate for the ternary operator.
As an aside, if you are a C programmer, GCC actually has an extension that allows you to exclude the if-true portion of the ternary, like this:
/* 'y' is a char * */
const char *x = y ? : "Not set";
Which will set x to y assuming y is not NULL. Good stuff.
In my mind, it only makes sense to use the ternary operator in cases where an expression is needed.
In other cases, it seems like the ternary operator decreases clarity.
By the measure of cyclomatic complexity, the use of if statements or the ternary operator are equivalent. So by that measure, the answer is no, the complexity would be exactly the same as before.
By other measures such as readability, maintainability, and DRY (Don't-Repeat-Yourself), either choice may prove better than the other.
I use it quite often in places where I'm constrained to work in a constructor - for example, the new .NET 3.5 LINQ to XML constructs - to define default values when an optional parameter is null.
Contrived example:
var e = new XElement("Something",
param == null ? new XElement("Value", "Default")
: new XElement("Value", param.ToString())
);
or (thanks asterite)
var e = new XElement("Something",
new XElement("Value",
param == null ? "Default"
: param.ToString()
)
);
No matter whether you use the ternary operator or not, making sure your code is readable is the important thing. Any construct can be made unreadable.
I use the ternary operator where ever I can, unless it makes the code extremely hard to read, but then that's usually just an indication that my code could use a little refactoring.
It always puzzles me how some people think the ternary operator is a "hidden" feature or is somewhat mysterious. It's one of the first things I learnt when I start programming in C, and I don't think it decreases readability at all. It's a natural part of the language.
I agree with jmulder: it shouldn't be used in place of a if, but it has its place for return expression or inside an expression:
echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;
The former is just an example, a better i18n support of plural should be used!
If you're using the ternary operator for a simple conditional assignment I think it's fine. I've seen it (ab)used to control program flow without even making an assignment, and I think that should be avoided. Use an if statement in these cases.
(Hack of the day)
#define IF(x) x ?
#define ELSE :
Then you can do if-then-else as expression:
int b = IF(condition1) res1
ELSE IF(condition2) res2
ELSE IF(conditions3) res3
ELSE res4;
I think the ternary operator should be used when needed. It is obviously a very subjective choice, but I find that a simple expression (specially as a return expression) is much clearer than a full test. Example in C/C++:
return (a>0)?a:0;
Compared to:
if(a>0) return a;
else return 0;
You also have the case where the solution is between the ternary operator and creating a function. For example in Python:
l = [ i if i > 0 else 0 for i in lst ]
The alternative is:
def cap(value):
if value > 0:
return value
return 0
l = [ cap(i) for i in lst ]
It is needed enough that in Python (as an example), such an idiom could be seen regularly:
l = [ ((i>0 and [i]) or [0])[0] for i in lst ]
this line uses properties of the logical operators in Python: they are lazy and returns the last value computed if it is equal to the final state.
I like 'em. I don't know why, but I feel very cool when I use the ternary expression.
I've seen such beasts like (it was actually much worse since it was isValidDate and checked month and day as well, but I couldn't be bothered trying to remember the whole thing):
isLeapYear =
((yyyy % 400) == 0)
? 1
: ((yyyy % 100) == 0)
? 0
: ((yyyy % 4) == 0)
? 1
: 0;
where, plainly, a series of if-statements would have been better (although this one's still better than the macro version I once saw).
I don't mind it for small things like:
reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;
or even slightly tricky things like:
printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");
I like using the operator in debug code to print error values so I don't have to look them up all the time. Usually I do this for debug prints that aren't going to remain once I'm done developing.
int result = do_something();
if( result != 0 )
{
debug_printf("Error while doing something, code %x (%s)\n", result,
result == 7 ? "ERROR_YES" :
result == 8 ? "ERROR_NO" :
result == 9 ? "ERROR_FILE_NOT_FOUND" :
"Unknown");
}
I almost never use the ternary operator because whenever I DO use it, it always makes me think a lot more than I have to later when I try to maintain it.
I like to avoid verbosity, but when it makes the code a lot easier to pick up, I will go for the verbosity.
Consider:
String name = firstName;
if (middleName != null) {
name += " " + middleName;
}
name += " " + lastName;
Now, that is a bit verbose, but I find it a lot more readable than:
String name = firstName + (middleName == null ? "" : " " + middleName)
+ " " + lastName;
or:
String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;
It just seems to compress too much information into too little space, without making it clear what's going on. Everytime I see ternary operator used, I have always found an alternative that seemed much easier to read... then again, that is an extremely subjective opinion, so if you and your colleagues find ternary very readable, go for it.
Well, the syntax for it is horrid. I find functional ifs very useful, and often makes code more readable.
I would suggest making a macro to make it more readable, but I'm sure someone can come up with a horrible edge case (as there always is with CPP).
Only when:
$var = (simple > test ? simple_result_1 : simple_result_2);
KISS.
As others have pointed out they are nice for short simple conditions. I especially like them for defaults (kind of like the || and or usage in javascript and python), e.g.
int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;
Another common use is to initialize a reference in C++. Since references have to be declared and initialized in the same statement you can't use an if statement.
SomeType& ref = pInput ? *pInput : somethingElse;
I treat ternary operators a lot like GOTO. They have their place, but they are something which you should usually avoid to make the code easier to understand.
I recently saw a variation on ternary operators (well, sort of) that make the standard "() ? :" variant seem to be a paragon of clarity:
var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]
or, to give a more tangible example:
var Name = ['Jane', 'John'][Gender == 'm'];
Mind you, this is Javascript, so things like that might not be possible in other languages (thankfully).
For simple if cases, I like to use it. Actually it's much easier to read/code for instance as parameters for functions or things like that. Also to avoid the new line I like to keep with all my if/else.
Neseting it would be a big NO-NO in my book.
So, resuming, for a single if/else I'll use the ternary operator. For other cases a regular if/else if/else (or switch)
I typically use in things like this:
before:
if(isheader)
drawtext(x,y,WHITE,string);
else
drawtext(x,y,BLUE,string);
after:
drawtext(x,y,isheader==true?WHITE:BLUE,string);
I like Groovy's special case of the ternary operator, called the Elvis operator: ?:
expr ?: default
This code evaluates to expr if it's not null, and default if it is. Technically it's not really a ternary operator, but it's definitely related to it and saves a lot of time/typing.
For simple tasks like assigning a different value depending on a condition they're great. I wouldn't use them when there are longer expressions depending on the condition tho.
A so many answers have said, it depends. I find that if the ternary comparison is not visible in a quick scan down the code, then it should not be used.
As a side issue, I might also note that its very existence is actually a bit of an anomoly due to the fact that in C, comparison testing is a statement. In Icon, the if construct (like most of Icon) is actually an expression. So you can do things like:
x[if y > 5 then 5 else y] := "Y"
... which I find much more readable than a ternery comparison operator. :-)
There was a discussion recently about the possibility of adding the ?: operator to Icon, but several people correctly pointed out that there was absolutely no need because of the way if works.
Which means that if you could do that in C (or any of the other languages that have the ternery operator), then you wouldn't, in fact, need the ternery operator at all.
If you and your workmates understand what they do and they aren't created in massive groups I think they make the code less complex and easier to read because there is simply less code.
The only time i think ternary operators make code harder to understand is when you have more than 3 or 4 in one line. Most people don't remember that they are right based precedence and when you have a stack of them it makes reading the code a nightmare.

What does ?: do in Kotlin?

I can't figure out what ?: does in for example this case
val list = mutableList ?: mutableListOf()
and why can it be modified to this
val list = if (mutableList != null) mutableList else mutableListOf()
In addition to the other good answers:
The Elvis operator is part of many programming languages, e.g. Kotlin but also Groovy or C#.
I find the Wikipedia definition pretty accurate:
In certain computer programming languages, the Elvis operator ?: is a binary operator that returns its first operand if that operand is true, and otherwise evaluates and returns its second operand. It is a variant of the ternary conditional operator, ? :, found in those languages (and many others): the Elvis operator is the ternary operator with its second operand omitted.
The following is especially true for Kotlin:
Some computer programming languages have different semantics for this operator. Instead of the first operand having to result in a boolean, it must result in an object reference. If the resulting object reference is not null, it is returned. Otherwise the value of the second operand (which may be null) is returned.
This is called the Elvis operator and it does... Exactly what you've described in your question. If its left hand side is a null value, it returns the right side instead, sort of as a fallback. Otherwise it just returns the value on the left hand side.
a ?: b is just shorthand for if (a != null) a else b.
Some more examples with types:
val x: String? = "foo"
val y: String = x ?: "bar" // "foo", because x was non-null
val a: String? = null
val b: String = a ?: "bar" // "bar", because a was null
The Elvis Operator is represented by a question mark followed by a colon: ?: and it can be used with this syntax:
first operand ?: second operand
It enables you to write a consise code, and works as such:
If first operand isn't null, then it will be returned. If it is null, then the second operand will be returned. This can be used to guarantee that an expression won't return a null value, as you'll provide a non-nullable value if the provided value is null.
For example(in Kotlin):
fun retrieveString(): String { //Notice that this type isn't nullable
var nullableVariable: String? = getPotentialNull() //This variable may be null
return nullableVariable ?: "Secondary Not-Null String"
}
In this case, if the computed value of getPotentialNull is not null, it will be returned by retrieveString; If it is null, the second expression "Secondary Not-Null String" will be returned instead.
Also note that the right-hand side expression is evaluated only if the left-hand side is null.
In Kotlin, you could use any expression as second operand, such as a throw Exception expression
return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")
The name Elvis Operator comes from the famous American singer Elvis Presley. His hairstyle resembles a Question Mark
Let's take a look at the defintion:
When we have a nullable reference r, we can say "if r is not null, use
it, otherwise use some non-null value x":
The ?: (Elvis) operator avoids verbosity and makes your code really concise.
For example, a lot of collection extension functions return null as fallback.
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?: gives you a way to handle the fallback case elgantely even if you have multiple layers of fallback. If so, you can simply chain multiply Elvis operators, like here:
val l = listOf(1, 2, 3)
val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")
If you would express the same with if else it would be a lot more code which is harder to read.

How do the OCaml operators < and > work with non-integer types?

I'm curious how the greater than (>) and less than (<) operators work with types that are not int, float, or double in OCaml.
For instance, I was able to discover that string "a" > "b" but is there some reference that lists the conventions for all non-numerical data types. Furthermore, how do these operators work across types? e.g. Is "a" > true or is "a" < true?
Finally, how would these work across a user-defined data type?
Thanks!
The OCaml <, >, <=, >= operators only work with two values of the same type, so the expression "a" > true is invalid. However, they work for all types (with caveats below). You can find the definitions of these operators in the Pervasives module.
The order for these operators is defined only for simple values (integers, characters, strings, byte sequences, and floating). In these cases the documentation says they give "the usual ordering".
The usual ordering for strings and byte sequences is lexicographic order. For strings, case is significant.
For compound values the order is only guaranteed to be consistent with = and to be a consistent ordering.
As far as I can see, order is not defined for simple user-defined types like type abc = A | B | C. I didn't expect this to be the case, but that's what I see in the documentation. In practice, the values of constant constructors like A, B, C, will be ordered in the order of declaration with the first value the smallest.
I also don't see a definition of the order between false and true. Again, this is surprising. In practice, false is less than true.
It is worth noting that comparisons between cyclic values is not guaranteed to terminate. Also, comparison between values that contain functions may raise an exception. These can cause unexpected problems, sometimes serious ones.
$ ocaml
OCaml version 4.02.1
# (+) < (+);;
Exception: Invalid_argument "equal: functional value".
# let rec cycle = 1 :: cycle;;
val cycle : int list = [1; <cycle>]
# cycle < cycle;;
(( Does not terminate ))

How to Implement the Ternary Operator in the DLR

I am implementing a language interpreter in C# using the DLR, and I'm having some troubles with the ternary operator. At this point, I have basic function declarations/calls implemented, like so:
F := (x) -> x + 1
F(1) # returns 2
I've not had a problem with a function body being a sequence of expressions -- the value of the last expression is always returned, and I've made sure all cases in the interpreter return at least something as a side effect. I'm now trying to implement the ternary operator (? :). The Expression tree I'm rendering looks like this:
work = Expression.IfThenElse(
Expression.IsTrue(Expression.Convert(work, typeof(Boolean))),
trueExp,
falseExp);
where trueExp and falseExp are both valid expressions.
The problem seems to be that the IfThenElse expression does not return a value, so basically even though trueExp and falseExp are building expression trees, the end result of the IfThenElse expression is always null. Short of making a Runtime function and explicitly calling it, is there a way to implement the ternary operator using the DLR? (ie: an Expression. that does the IfThenElse and returns the actual values in the true and false clauses?)
What I hope to parse is something like:
F := (x) -> (x = 1) ? 4 : 5
F(1) #4
F(2) #5
But right now this always returns null when compiled into a program, because of the problem outlined above.
I'd appreciate any help, this is quite vexing!
Expression.IfThenElse is an if (...) ... else ...; construct, not the ternary operator.
The ternary operator is Expression.Condition

When and where to use ternary operator? [closed]

I often read ternary operator(? : ) in books,but I am not clear the best practice of it.
What is the advantages and disadvantages or best practice of it?
The ternary operator ? : represents an if-then-else construct, except that it actually returns a value. So instead of:
if ( condition )
x = expression1;
else
x = expression2;
You can write:
x = (condition) ? (expression1) : (expression2);
In C, C++, Java, etc., you cannot write:
x = if (condition) (expression1) else (expression2);
Some languages, like Ruby, do allow a form like that, however, since statements in Ruby always return a value, and the value of a block is the value returned by the last statement in a block.
You may use the operator as
int nNum1 = 10, nNum2 = 20, nMax = ( nNum1 > nNum2 ) ? nNum1 : nNum2
It is shorthand for simple if-else comparisons, where a variable is assigned based on the result of the comparison.

Resources