You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This post attempts to apply objective reasoning to subjective code formatting opinions, so all the caveats of that endeavor apply, and critical feedback and disagreement are welcome.
tsv is non-configurable to avoid behavior that depends on hidden state in the directory/context where it's run like Prettier & friends -- that choice is fixed. The simplicity and predictability reasons are clear wins for my goals with the tool. This means tsv must choose one canonical format that can't please everyone. The current behavior aligns with my taste, but I'm open to hearing contrary arguments and potentially changing things. Forking the tool is always an encouraged option (currently would be slightly unwieldy because there's no simple flag, but it's not a difficult change).
The rationale for bracketSpacing: false -- {foo} over { foo } -- goes like this: when reading code, disambiguating constructs is part of comprehension. Many patterns in code are repeated with different meaning, like ( and { and = and +, and the surrounding context is what informs the specific meaning. Context clues that don't tip into verbosity or useless noise quicken comprehension when reading code, is my claim here.
Consider the closing curly brace:
}
A lone closing curly can indicate one of many constructs. Is it closing a function? An object in a function call's args? An object or function in an assigment? A block like if or for or while?
A semicolon disambiguates:
};
In formatted code, that's definitely closing an object or function assignment (or some other cases I can't think of atm, but it's not the other constructs listed above). Viewed one way, it may look like a sad grumbling winking face, but it's useful signal for readability, not noise.
TypeScript/JS is full of closing curlies, and semicolons are punctuation that reveal structure explicitly, like periods and commas in prose. I'll assert the eye doesn't lose time processing ;, it loses time when they're omitted. After years of enjoying semicolons, when I read semicolon-less JS/TS it has an undifferentiated soupy feel to it. Even if you're accustomed to it, I'm claiming omitting the signal puts more burden on the brain and slows scanning - the argument that omitting the semicolon is "cleaner" is an aesthetic argument for increasing ambiguity, and as stated in the post's premise, ambiguity is the enemy of quick comprehension.
For bracketSpacing: false:
{a
The presence of a space here diambiguates object declarations and destructuring from blocks and function bodies. With bracketSpacing: true (the Prettier/Svelte defaults), you lose that signal. I think this is a weaker case than the semicolon, Svelte's tight expressions further complicate matters, but that's my current position.
Oddly, Prettier doesn't even have the option to pad arrays, which seems to have the same aesthetic argument as bracketSpacing but carries less ambiguity baggage. (mainly index signatures overlap, much less common than the curly brace) The bracketSpacing: false choice makes objects consistent with Prettier's non-configurable arrays -- so object+array literals+destructuring have uniform whitespace rules, another point for reducing ambiguity. Said the other way around, Prettier's default bracketSpacing: true forces two different whitespace patterns on destructuring and literals, one for objects and one for arrays. That seems pretty off to me. (tsv however could fix that inconsistency by adding spacing to arrays, though I'd still consider the object form more ambiguous than it ought to be)
The ambiguity argument applies to other options, including:
trailingComma: 'all' - regardless of position, it's a listitem-like when you can consistently expect a , or not
singleQuote: true - largely aesthetic preference in TS/JS, but in Svelte and HTML, disambiguates from attribute "
semiColon: true - as described above, semicolons are useful information
arrowParens: 'always' - function args consistently get wrapped in parens (both a readability and writability concern)
tsv tries to consistently apply the ambiguity principle in its choices. There's wiggle room here -- like I'm not advocating for adding , at the end of single-line lists, and I prefer implicit function returns lacking { return * }, even though these two cases technically increase ambiguity. tsv is still very early and now is a good time to change course.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This post attempts to apply objective reasoning to subjective code formatting opinions, so all the caveats of that endeavor apply, and critical feedback and disagreement are welcome.
tsv is non-configurable to avoid behavior that depends on hidden state in the directory/context where it's run like Prettier & friends -- that choice is fixed. The simplicity and predictability reasons are clear wins for my goals with the tool. This means tsv must choose one canonical format that can't please everyone. The current behavior aligns with my taste, but I'm open to hearing contrary arguments and potentially changing things. Forking the tool is always an encouraged option (currently would be slightly unwieldy because there's no simple flag, but it's not a difficult change).
The rationale for
bracketSpacing: false--{foo}over{ foo }-- goes like this: when reading code, disambiguating constructs is part of comprehension. Many patterns in code are repeated with different meaning, like(and{and=and+, and the surrounding context is what informs the specific meaning. Context clues that don't tip into verbosity or useless noise quicken comprehension when reading code, is my claim here.Consider the closing curly brace:
}A lone closing curly can indicate one of many constructs. Is it closing a function? An object in a function call's args? An object or function in an assigment? A block like
iforfororwhile?A semicolon disambiguates:
In formatted code, that's definitely closing an object or function assignment (or some other cases I can't think of atm, but it's not the other constructs listed above). Viewed one way, it may look like a sad grumbling winking face, but it's useful signal for readability, not noise.
TypeScript/JS is full of closing curlies, and semicolons are punctuation that reveal structure explicitly, like periods and commas in prose. I'll assert the eye doesn't lose time processing
;, it loses time when they're omitted. After years of enjoying semicolons, when I read semicolon-less JS/TS it has an undifferentiated soupy feel to it. Even if you're accustomed to it, I'm claiming omitting the signal puts more burden on the brain and slows scanning - the argument that omitting the semicolon is "cleaner" is an aesthetic argument for increasing ambiguity, and as stated in the post's premise, ambiguity is the enemy of quick comprehension.For
bracketSpacing: false:The presence of a space here diambiguates object declarations and destructuring from blocks and function bodies. With
bracketSpacing: true(the Prettier/Svelte defaults), you lose that signal. I think this is a weaker case than the semicolon, Svelte's tight expressions further complicate matters, but that's my current position.Oddly, Prettier doesn't even have the option to pad arrays, which seems to have the same aesthetic argument as
bracketSpacingbut carries less ambiguity baggage. (mainly index signatures overlap, much less common than the curly brace) ThebracketSpacing: falsechoice makes objects consistent with Prettier's non-configurable arrays -- so object+array literals+destructuring have uniform whitespace rules, another point for reducing ambiguity. Said the other way around, Prettier's defaultbracketSpacing: trueforces two different whitespace patterns on destructuring and literals, one for objects and one for arrays. That seems pretty off to me. (tsv however could fix that inconsistency by adding spacing to arrays, though I'd still consider the object form more ambiguous than it ought to be)The ambiguity argument applies to other options, including:
trailingComma: 'all'- regardless of position, it's a listitem-like when you can consistently expect a,or notsingleQuote: true- largely aesthetic preference in TS/JS, but in Svelte and HTML, disambiguates from attribute"semiColon: true- as described above, semicolons are useful informationarrowParens: 'always'- function args consistently get wrapped in parens (both a readability and writability concern)tsv tries to consistently apply the ambiguity principle in its choices. There's wiggle room here -- like I'm not advocating for adding
,at the end of single-line lists, and I prefer implicit function returns lacking{ return * }, even though these two cases technically increase ambiguity. tsv is still very early and now is a good time to change course.Beta Was this translation helpful? Give feedback.
All reactions