A lot of the same issues you point out could also apply to if statements in general, not just the ternary operator. It's an interesting thought, because in other languages there are alternatives to using if statements. SmallTalk booleans were objects which exposed the messages ifTrue and ifFalse, rather than requiring a special if statement. The FP equivalent would be pattern matching, which maps data patterns to functions/values. Assembly has conditional jumps. All of these are conceptually similar in usage -- run this code when this condition is present.
Could it be that the deeper problem here is the if statement itself? (Since ternary is just an expression + operator form of this.) This is an honest question for discussion, since I use if at times and it is considered a staple programming construct.
I think if statements are something separate, assuming the ternary isn't being abused to introduce logic flow into a program.
if statements are about flow, adn there's simply no way to get rid of them. Sure, in many cases we have higher level things, like select, or even dynamic dispatch, but the essential conditional logic persists.
Most languages use if for flow control so they encourage you to write boolean reductions for your data and to think of your decisions in terms of booleans. Whereas my human brain doesn't tend to actually think in Discrete Logic. Sometimes I even draw truth tables to make sure it will produce the expected result. The problem isn't really with the language feature provided by if, but perhaps with our overuse of the construct.
So I guess the fundamental question is: does using if reduce the expressiveness of your solution? And if so, what are the alternatives?
When I am writing a guard clause, if's expressiveness is probably fine. But when I am making business decisions, using if for flow can feel pretty bad at times. As far as the 2nd question, I think really the only alternative to using if is to write higher level code so it is not needed. Those implementations will vary based on the problem and paradigm. Examples I've used: union types or shallow inheritance to make discrete data states.
As far as the relationship, ternary is just an expression + operator version of if. Being an operator makes it more cryptic, but I consider it being an expression to be a good thing. I tend to write in expression-based languages, so in my mind it is the exact same capability as if. (In F#, if is an expression and no ternary operator exists.) From that perspective, putting "too much" in the ternary operator feels appropriately bad because it is highlighting problems with expressing solutions in terms of booleans. Whereas the same code with a statement-based if may feel more comfortable than it should. Not that I am in favor of ternary. I think your alternative is better. I guess I was just isolating a problem that most people easily identify with ternary, but is less obvious with if. That being the lack of human legibility of boolean-based flow control.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.