6 ms·
I use the ternary operator all the time. result = boolean_flag ? do_this() : do_that(); I think it's less noisy and nicer to look at then an if-
by schindlabua 9y ago
I use the ternary operator all the time.
result = boolean_flag
? do_this()
: do_that();
I think it's less noisy and nicer to look at then an if-else, provided the statements aren't too long. God forbid multiple side effects though, even in languages with less complicated sequencing rules than C/C++.
- dfgdghdf 9y agoI think that the ternary operator should only be used for side-effect free code. So: auto result = boolean_flag ? compute_property() : compute_another_property(); if (boolean_flag) { do_this(); } else { do_that(); }
- schindlabua 9y agoYeah, I agree!
- Mithaldu 9y agoWhat is your justification for the restriction though? Personally i dislike the latter form because it requires me to spend extra time reading what is boilerplate that is functionally identical to a ternary. Edit: Not impressed by the down-voting of an earnest question of someone trying to learn more about how other people see things, HN.
- ProblemFactory 9y agoTernary is the only option if you are using "B ? X : Y" as an expression, want to get the value of X or Y. If-else is the only option if you want to have multiple statements in a {} block, instead of only one function call. So it seems more consistent to use ternary for expressions and if-else for statement control flow.
- Mithaldu 9y agoWhy are those the only options? I know languages where if/else blocks return values. (Rust, Julia, Python, Perl, R) I also know languages that allow easy ways to embed multi-line blocks into a ternary. (Rust, Perl) I'm sorry, but i really don't follow your logic, can you try to explain it more clearly?
- TeMPOraL 9y agoDoes Rust/Julia/Python/Perl/R feature ternary operators? The classic languages with ternary (C, C++, Java, PHP, JavaScript) all have the deficiency of distinction between statements and expressions. When everything in your language is an expression, the need for ternary disappears.
- Mithaldu 9y agoApparently Rust doesn't. Julia/Perl have it, Python has it with words, and R code can import it.
- tripzilch 9y agoIn Python the if/else block does not return a value. Python has a ternary operator, which does return a value. It just so happens this operator uses the tokens `if` and `else`. But it's the same thing what you'd write in C or Javascript as `C ? T : F`, would be written `T if C else F` in Python. Different order of arguments and tokens, but it's still the ternary operator and not an if/else block. You can't get a result from block statements in Python. Just because the ternary operator uses the same tokens as the if/else block, doesn't mean it's the same thing.
- steveklabnik 9y agoRust has "if is an expression" already anyway, so no ternary. let x = if true { 5 } else { 6 };
- ProblemFactory 9y agoMy comment, and the comments above it are all about C-style languages (C, C++, C#, Java). Languages with very different syntax like Python are of course going to have different style preferences. Eg. Python doesn't have a ?: operator at all, just an inline if-else expression, so the entire discussion of "should you use ?: for control flow" is meaningless for Python.
- emodendroket 9y agoWell for me it's the same reason I don't give functions names that suggest something different from what they do.
- Mithaldu 9y agoAre you saying this suggests it does something different from what it does? What does it suggest? boolean_flag ? do_this() : do_that(); It seems so terse as to be impossible to misinterpret. The only possibly feasible way i see for it doing something unexpected would be if it were the last statement in a function in a language that implicitly returns the value returned by the last statement in a function; but users of such languages usually are aware that can happen.
- emodendroket 9y agoTernaries strongly suggest "side effect-free statement being run for its return value." Perhaps a more apt analogy would be to say it's like writing a method called "getX" with side effects.
- Mithaldu 9y ago> Ternaries strongly suggest "side effect-free How do they suggest that? As far as i am aware ternaries put no restriction whatsoever on what kind of code you can put in its branches. I don't buy the comparison with getX either, since ternaries have no name, they're just some punctuation, and even if implemented as if/else word pairs are completely vague.
- TeMPOraL 9y ago> How do they suggest that? It might be a convention in some circles. I don't think it's a well-established one, though. For me, ternaries strongly suggest "expressions being run for its return value", but without any indication whether or not it's side effect-free. In practice, most of the time such expressions end up being side effect-free (getters, finders, etc.), but every now and then you do want to have a stateful expression (e.g. getting something from a map, and storing a default value there if the key is missing in the map). I believe such stateful expressions are fine to use with ternaries as well.
- maxxxxx 9y agoMe too. Ternary expressions are for getting a value, not for invoking an action.
- TeMPOraL 9y agoWhy not both?
- maxxxxx 9y agoI can't give you a hard reason. I guess when I learned C all examples were like c=yesno?1:2. So I guess I stuck to it and never thought about triggering an action with side effects that way.
- TeMPOraL 9y agoI see. So as an example of doing both, consider following Java pseudocode (simples example that comes to my mind now): Foo value = someCondition() ? map1.computeIfAbsent("key", defaultValueProvider) : map2.computeIfAbsent("key", defaultValueProvider); This both gets a value and changes state of the map; which map is queried/altered is determined by the condition. I personally don't mind such code, and prefer it to if/else version.
- Mithaldu 9y agoShouldn't that be: Foo value = ( someCondition() ? map1 : map2 ).computeIfAbsent("key", defaultValueProvider); Or some kind of moral equivalent?
- TeMPOraL 9y agoCould be, though this is an artifact of a simplified example that I didn't mean to be relevant here. For clarity, let's rewrite it as: Foo value = someCondition() ? map1.computeIfAbsent("key", defaultValueProvider) : list1.get(42);
- 9y ago
- TeMPOraL 9y agoSince everyone agrees, I'll disagree :). Seriously though, there's nothing in ternary operator that says it should only be used for side-effect free code. Especially in C++ (or Java), which doesn't even differentiate between stateless and stateful code on the language level. IMO ternary is a perfect solution for the case where you want to assign or return a different value based on a boolean condition. Whether or not the code in branches is side-effect free is irrelevant. Personally, where I try to avoid using ternary operator, is places where I don't care about returned value. So "yes" for: auto foo = [condition] ? possibly_stateful_then() : possibly_stateful_else(); no for: [condition] ? then_statement() : else_statement();
- Mithaldu 9y ago> Personally, where I try to avoid using ternary operator, is places where I don't care about returned value. As i asked below: Why though?
- TeMPOraL 9y agoNo solid reason, just a feeling. I feel that if-else block communicates intent more clearly when you're dealing with statements - because it can't return a value in languages we're discussing, it's specialized for that job. The same motivation makes ternary better when we care about a value.
- Mithaldu 9y agoTo be honest, with that explanation the decision you made has nothing to do with ternaries, and is entirely just the mirroring of the decision the if forced on you. Also, > in languages we're discussing Don't bury that lede. If you're restricting what you're saying to a specific language say that bold and as the very first thing, so people don't end up wasting their time parsing your post in a different context. Rude.
- TeMPOraL 9y ago> To be honest, with that explanation the decision you made has nothing to do with ternaries, and is entirely just the mirroring of the decision the if forced on you. I like to think of it as using the dedicated tool for a job it was designed for. In my mind, it's a good rule of thumb because it enhances readability (compare "the principle of least surprise"). > Don't bury that lede. If you're restricting what you're saying to a specific language say that bold and as the very first thing, so people don't end up wasting their time parsing your post in a different context. Rude. Why? Come on, at this point in the thread we'll still discussing C++ derivatives. I thought it was obvious. Also: if a lanuguage has an if/else as an expression and has a ternary operator, then IMO there's a problem with that language being cluttered with duplicate syntax for the same thing.
- reycharles 9y agoI find that the problem with the ternary operator isn't the operator itself per se, but the concrete syntax. If you could write it result = if boolean_flag then do_this() else do_that(); then I'm sure no one would find it as bad as they do now. The way you formatted the ternary with line-breaks helps a lot, too, I think!
- chrismorgan 9y agoBlock-oriented languages can do it; Rust, for example: let result = if boolean_flag { do_this() } else { do_that() }; Rust actually doesn’t have a ternary operator.
- lmm 9y agoWhat do you mean "block-oriented"? I'd say this is part of Rust's ML heritage, and comes of being expression-oriented: if is just an expression, and evaluates to a value like any other expression.
- nerdponx 9y agoMaybe "block oriented" is supposed to mean "has blocks that are expressions".
- deleted 9y ago[deleted]
- chrismorgan 9y agoSorry, “expression-oriented” was what I meant to write.
- 1wd 9y agoOr Python: result = do_this() if boolean_flag else do_that()
- jrkatz 9y ago
- raverbashing 9y agoAs others pointed out, it's not really better than an if (and actually worse in this case because you might not require the assignment) To me it works in short expressions that do return a value so number_of_things = some_type ? 5 : 1
- cooervo 9y agoI think the author meant that we was abusing it: x = x ? (n ? m : w) : (b ? c : x); This doesnt seem too bad with variables, but now imagine this. int killMe = Factory.Omg ? (isFuckedUpped ? Leet.YES : Leet.NO) : (youGetTheIdea ? yep : nope);
- nerdponx 9y agoHonestly that looks perfectly readable to me. Easier to scan all at once, as opposed to several lines of an if-else block.
- falcolas 9y agoIt's not perfectly readable to me, I'd have to spend time stepping through both of these to ensure correctness. Who wins?
- nerdponx 9y agoJust so I understand, "correct" in what sense? That I got the right variables in the right place, or that there are no side effects, etc.?
- falcolas 9y agoAll of the above. More specifically, correct meaning that it's doing what it's supposed to be doing (and figuring out what it's supposed to be doing will take a few brain cycles too), and nothing more. My opinion is that code should be written in a way that makes it possible for an intern to read and update. I work with interns and fresh-out-of-college grads, and I need them to be productive too.
- tripzilch 9y agoTo be honest, I think nested conditionals of that form are hard to read whether you write them as if/else blocks or ternary expressions :) I'd first look for a way to try and avoid the whole situation, if possible. After that, what I feel is more readable depends on what formatting the language allows, length of identifier names, what the subexpressions look like, etc. Then, after careful consideration, I'll just follow any style guide and thus prefer if/else blocks, especially if a ternary would silently discard its result.