Additional formatting options for multi-line ternary expressions, e.g. always enclose in parentheses
I consider these to be acceptable options for writing a ternary expression:
// Single line (for shorter expressions)
let x = condition ? trueOperand : falseOperand;
// Multiple line (first acceptable option, use either 1 or 2 but use the same one consistently)
let x = (condition ?
trueOperand :
falseOperand
);
// Multiple line (second acceptable option, use either 1 or 2 but use the same one consistently)
let x = (
condition ?
trueOperand :
falseOperand
);
// Imitate a match expression (nice to have)
let x = (
firstCondition ? firstResult :
secondCondition ? secondResult :
thirdCondition ? thirdResult :
defaultResult
);
But currently dprint seems insistent on formatting ternary expressions like this below. This violates the consistent principle of indented blocks always being enclosed in parens, brackets, or braces, and I think that inconsistency harms readability. I strongly dislike this formatting style (with "operatorPosition": "sameLine"):
let x = condition ?
trueOperand :
falseOperand;
I would like to have an option to not enforce this formatting, and ideally to enforce formatting like the above examples instead.
Interesting, to me these forms are all equally unreadable. 😅
I don't want to spend brain calories trying to figure out the evaluation order of any of these.
Of course, I know they're right-associative - but personally I have no intuition for reading any of these forms of nested ternaries, it takes real work for me. For context, I have 40 years of programming experience, so this is not a "skill issue" - it's a personality trait, which (from my experience) many people have.
Some can read these, some can't, simple as that.
In favor of keeping code accessible to as many people as possible, I personally know many developers who swear off nested ternaries entirely - and if that's the standard of the codebase, I will follow suit as well.
But personally, I find that the only readable forms of nested ternaries are either this:
let x = firstCondition
? firstResult
: (secondCondition
? secondResult
: thirdCondition);
Or this:
let x = firstCondition
? firstResult
: secondCondition
? secondResult
: thirdCondition;
Those are the only ternary formattings I know of where the indentation indicates evaluation order.
Thus, in dprint, I would prefer an option to simply enforce parens around nested ternaries - which would "automatically" give you the formatting in my first example. Parens or not, I don't feel strongly about this - the indentation is what makes it readable for me. I might suspect the extra parens are helpful to some people who might read/parse code differently than me, and I don't mind them.
Of course, I wouldn't oppose having more options for ternary formatting.
But you might want to take it to heart that some people literally can't read this code - as a result, when working with that code, they will introduce subtle bugs, and other developers will have a hard time spotting those bugs.
Choices like these are honestly less about personal preferences, and more about empathy and accessibility.
Indentation is pretty universally and intuitively understood, and so that would always be my first choice.
My second choice would be linting against nested ternaries.
In case it was unclear, I am interested in formatting options, not necessarily making any of what I described a default.
Ternary operators are not the only operators that affect control flow. There's also short-circuiting &&, ||, and ?? binary operators as well as the safe access operators ?., ?.(), and ?.[]. As far as I'm aware, nobody asks for such special indentation formatting for these other operators. So I prefer that ternary operators do not have special indentation rules that other similar operators do not.
I personally feel that my example of a series of ternary expressions is much more readable than increasing levels of indentation, since it follows the same pattern as a series of if, else if, and else statements, and also strongly resembles a match expression as written in most languages that support them. I'm aware that this is not an especially common way to use the ternary expression, but I think that it is very comfortable and readable once you know the pattern exists.
Though mainly, I just strongly prefer that every indented block always be enclosed within parentheses, brackets, or braces. I think that mixing indented blocks with and without enclosing parens, etc. significantly harms readability regardless of how one indents their ternary expressions.
@mindplay-dk I believe that it's quite rude to lecture me on empathy and accessibility as I simply ask for an option to format code in a way that is more accessible for me. Maybe you should not trust an LLM to write your comments for you, as it appears you must have done. (Unless you wrote that bolded comment yourself. In which case, oof.)
Maybe you should not trust an LLM to write your comments for you
never.
I highlighted those statements in bold because my response went long, as those were the two most important points.
I know this is a sensitive subject, but I promise I'm not trying to be rude - I'm just trying to make sure we design things to be as inclusive and accessible as possible. I'm trying to be considerate of everyone. For me, that's the one goal of using a source code formatter.
When you say this ternary layout is "more accessible to you", do you mean you have difficulty reading the indented/parenthesised version? Or do you mean you just prefer your style?
If it's more an issue of personal taste, I would ask you to read my response again with a more open mind.
If you difficulty reading the indented/parenthesised version, then you'd be the first I've met - and if so, that's completely fair, and maybe I'm wrong about this. I was certain everyone would be able to read that, but hey... 🤷♂️🙂
I'm sorry @mindplay-dk, but you are not making sense.
To anyone else coming across this issue, to try to cut through whatever that all was:
Basically, my request is for an added option to not enforce the current formatting for ternary expressions. Currently, the plugin strips parentheses around ternary expressions when they span multiple lines. In my opinion, this significantly harms readability, and I want dprint to not do that. Also, it would be nice to have some additional options to enforce alternative ways of formatting ternary expressions, as illustrated with code examples in the original issue.
By the way, here's another issue where someone demonstrated using the nested multi-line ternary expression format mentioned in the original issue description (for conditional types, in this case):
https://github.com/dprint/dprint-plugin-typescript/issues/478