12 ms·
I couldn't disagree more. Nested ternarys are NEVER okay. They are confusing and misleading to anyone new to your code base.
by Random_Person 7y ago
I couldn't disagree more. Nested ternarys are NEVER okay. They are confusing and misleading to anyone new to your code base.
- _bxg1 7y agoI would make the exception that if you judiciously indent then across multiple lines, to reflect the nested structure the way the if/else equivalent would, then they're fine. But yeah, nested ternaries on one line are impossible to follow.
- demo123 7y agoIf you even need to indent them then why you don't write a full if else statement instead? Nested ternaries shouldn't be used at all.
- _bxg1 7y agoFor languages in which if/else is unfortunately only imperative, not an expression
- _bxg1 7y agoIMO if if/else can be used as an expression, your language shouldn't have a ternary operator at all
- josephg 7y agoIf/else chains are worse because they allow problems like this: if (cond) { var1 = x; } else if (cond2) { var2 = y; } else { var1 = z; } Did you notice the second block assigned to var2 instead of var1? Best case it’s a gotcha for anyone reading the code later. It might be a bug by the original author; we can’t tell at a glance if this behaviour was intentional. Ternaries remove this problem. The intent of the author is clearer, and (with proper formatting) there’s no gotchas for anyone reading the code later.
- _bxg1 7y agoIf I understand correctly, what you're really advocating isn't ternary vs if/else, but expressive conditionals vs imperative conditionals. A statement that is something vs a statement that does something. Using expressions instead of imperative code that mutates state is a staple of functional programming, and is basically always preferred where possible. In some languages you can do this: var1 = if cond { x } else if cond2 { y } else { z } Which in my opinion is strictly better than using a ternary, if the language supports it.
- josephg 7y agoYes exactly. I mentioned in another comment that rust allows this, and having used it I think the best of all worlds. My favorite part is that its easy to add extra statements into the conditional blocks if you want. Doing that with ternaries requires either using the comma operator, repeating the condition on another line or refactoring the whole expression back out into if-else chains. All of those options are bad.
- macspoofing 7y agoTrue. When in Java, I've gotten into the habit of using the final initializer to mitigate these kinds of issues, like this: final T var1; if (cond) { var1 = x; } else if (cond2) { var2 = y; } else { var1 = z; } In this specific case, the compiler will catch the lack of initialization in the second block. It's also very helpful with a complicated/nested conditionals to guarantee that you initialize the variable through every code path.
- jlokier 7y agoI wouldn't call that example nested; I'd call it sequentially chained, and I think that pattern is quite clear even with many conditions in the sequence. That pattern is the expression equivalent of if..; elsif..; elsif..; elsif... Writing it out in long form using actual if statements doesn't add much clarity, and costs in verbosity, as the OP says, macro-clarity versus micro-clarity. I agree with the sibling to this comment, though, that a ternary is more readable with newlines and indentation: return (a < b ? -1 : a > b ? 1 : 0); That's the style I use, except for extremely short and ternaries where the verbosity adds nothing, like (A > B ? A : B). In my view it becomes more complex to understand when there's a ternary inside the first branch, because then it's equivalent to if...(if...else...)...else... At that point I'd consider using if statements, if there is no reason to stay with an expression.
- candiodari 7y agoThis is a natural point of disagreement. The question is what you're trying to do. Is this the lowest level of decision making in something like a large drawing application, or some CAD or financial package, then for the love of God, take the concise approach ! If you consistently take the longer approach, may God provide mercy on your soul (and a very large monitor) when you get to vector multiplication or matrix math. If you're writing 3 business rules in something that's important and needs reliability and therefore should not have complexity ? Then it might be better to write it out. (in both cases, because of the potential for stupid mistakes, I'd add tests) But there's no single solution for all situations. High complexity software ? Concise will help out more. Low complexity software ? Write it out for clarity.
- jlokier 7y ago> If you're writing 3 business rules in something that's important and needs reliability and therefore should not have complexity ? Then it might be better to write it out. I'd give you multiple upvotes if I could for this. Absolutely agree with all your points. I'd add further, that if it's 3 important business rules, then sometimes expanding it further to have well-named functions and well-named variables is well worth doing, even if the business rules are trivial logic: // This rule was recommended by the accountant on 2019-05-06 // and must be reviewed by the CFO before release. function receipt_needs_itemised_tax_record(amount: Money): bool { return amount >= 1.00; } // Show itemised tax records on receipts that need it. if (receipt_needs_itemised_tax_record(receipt.total_paid)) { ... } Versus: // Writing this and other low-level code in 25 lines per function // does not make the 10kloc rendering library easier to understand. function transform_pixel(bg: RGB, fg: RGB, opacity): RGB { opacity = clamp(opacity, 0.0, 1.0); let blend_bg = 1.0 - opacity, blend_fg = opacity; return RGB { r: clamp_rgb(bg.r * blend_bg + fg.r * blend_fg), g: clamp_rgb(bg.g * blend_bg + fg.g * blend_fg), b: clamp_rgb(bg.b * blend_bg + fg.b * blend_fg) }; }
- jodrellblank 7y agoThey are confusing and misleading to anyone new to your code base. But why should that be the main thing to be concerned about and prioritise? In what way are they "misleading"? Is it really the state of the industry where a new person cannot learn a codebase, has no time or effort, and cannot read a single line of the language they were hired to work on, and that's the person we should build everything for? Does it work like that in any other industry?
- Random_Person 7y agoBecause you can already read your own code. Writing for yourself is bad code. Write for the next person that has to figure it out.
- 5trokerac3 7y ago> Does it work like that in any other industry? Yes, it does. Imagine you were a new underwriter at an insurance company and your predecessor used the shorthand nomenclature for every detail on the accounts you're taking over, and failed to write out any of the detailed reasoning behind why they chose to approve or deny claims. How much longer would it take for you to be able to fill their shoes than if they had been just a little bit more descriptive in their documents? > "Programs must be written for people to read, and only incidentally for machines to execute." - Harold Abelson
- jodrellblank 7y agoDid you see that it was me quoting that exact quote as something to argue against? I don't know what shorthand nomenclature of insurance underwriting is, but if it's a standard part of insurance underwriting then I would expect a new hire to be familiar with it, or need time to become familiar with it. If it's something separate like actual Gregg or Pitman shorthand English which the one underwriter used personally, unrelated to underwriting skills, then I wouldn't compare that to a programming language's built-in ternary operators.
- 5trokerac3 7y ago
- davnicwil 7y agoThis I think is obviously personal preference, but to me nested ternarys are pretty readable as long as they're wrapped and indented. When they are, you basically get something that looks visually like a decision tree. This can read really nicely in situations where declarative style code fits better - for example embedding nested ternarys in JSX is quite a popular pattern for this reason. The caveat is, you have to be 'used to' reading the ? and : symbols and instantly mapping them to if/else, but I certainly don't think getting used to this in a short time frame is beyond expectation for someone who's not already, i.e. new team members etc.
- Random_Person 7y agoWriting for yourself is a fallacy. We can all read our own code. Write for the next guy who has to look at it and figure out what is going on.
- davnicwil 7y agoI completely agree with you :-) But as I say above, I think in certain situations they can be more readable for everyone.
- piaste 7y ago> We can all read our own code Six-months-ago-myself thought so as well. Turns out six-months-ago-myself is a goddamn moron.
- yiyus 7y agoIt's also a fallacy that a ternary operator is some impossible to understand concept that will make the code totally unreadable for everyone but you. C programmers should be fine with the use of ternary operators for something like the example shown here.
- wtetzner 7y agoWho should you be writing for? Everyone is different. What's clearer for one person might be harder to read for someone else.
- LandR 7y agoIf someone is hired to work on your code base, presumably they know the language. They know ternarys work... If they don't then they need to learn. You can't say don't use specific language features because some devs can't be bothered to learn them.
- maxxxxx 7y agoI know ternary operators very well but I still have to think twice when I see them nested “You can't say don't use specific language features because some devs can't be bothered to learn them.” Would you say the same about C++? In my view it’s a good practice to use only a subset of a language consistently and not use all features. I have seen JavaScript code where I had to do research for half an hour before I could figure out what it really meant.
- josephg 7y ago> I have seen JavaScript code where I had to do research for half an hour before I could figure out what it really meant. My view on this has flip flopped several times during my career. I think every spec has some dusty corners that most people don’t know about, but when a situation calls for it knowing about some obscure features can make your code far more readable. Sometimes it’s better in the long run to train your team about a feature they might not know about rather than code for the lowest common denominator. This thread is a great example - I spent my first decade of programming scared of chained terneries. One day I spent a couple of hours goofing around with them, playing with different ways I could write my code and internalising their semantics. Now they seem fine. I wish I’d taken the time to do that years ago. Ten years being afraid saved me 2 hours of time learning. One of the best programmers I worked with reads the specs of tools he uses for fun. He says specs seem daunting but you can read them in far less time than you think and there’s always some fascinating stuff in there. My HTML knowledge got way better working with him - and its funny seeing how many tools struggle with correct HTML because the authors didn’t bother actually learning it. Some more examples: html void elements, html/body tag auto insertion, JS tagged break/continue, C/JS/etc’s comma operator.
- 7y ago
- bobbylarrybobby 7y agoNested ternary is fine as long as it’s written on multiple lines because then it exactly mirrors the if/else-if/else structure. return ( a < b ? -1 : a > b ? 1 : 0)
- macspoofing 7y ago>then it exactly mirrors the if/else-if/else structure. But it doesn't mirror the if/else-if/else structure. Rather the mirrored semantics looks as follows: if(a < b) return -1; else if(a > b) return 1; else return 0; It's interesting that for all the claims in this thread about how obvious the ternary operator is, almost every single person got it wrong. Is there a functional difference in this example? No. There isn't. Is there a functional difference in any example? I don't think so, but I'm not 100% sure. And the nice thing about not being clever, I don't have to worry about it.
- TomMahle 7y agoAs someone that would be new to his code base, I neither find that confusing nor am I mislead by it. Here's a blog post I'm becoming more and more persuaded by as time goes on: https://medium.com/javascript-scene/nested-ternaries-are-great-361bddd0f340 https://medium.com/javascript-scene/nested-ternaries-are-gre...