惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

Prettier Blog

Prettier 3.8: Support for Angular v21.1 Prettier 3.7: Improved formatting consistency and new plugin features! Prettier 3.6: Experimental fast CLI and new OXC and Hermes plugins! Prettier 3.5: New objectWrap option, experimentalOperatorPosition option and TS config file support! Prettier 3.4: A lot of bug fixes Prettier 3.3: New Flow features and a lot of bug fixes Prettier 3.2: Support JSONC and Angular’s ICU expression Prettier's CLI: A Performance Deep Dive $20k Bounty was Claimed! Prettier 3.1: New experimental ternaries formatting and Angular control flow syntax! Prettier 3.0: Hello, ECMAScript Modules! Prettier 2.8: improve --cache CLI option and TypeScript 4.9 satisfies operator! Prettier 2.7: new --cache CLI option and TypeScript 4.7 syntax! Prettier 2.6: new singleAttributePerLine option and new JavaScript features! Prettier begins paying maintainers Prettier 2.5: TypeScript 4.5 and MDX v2 comment syntax! Prettier 2.4: new bracketSameLine option and TypeScript 4.4 support! Prettier 2.3. In which assignments are consistent, short keys non-breaking, and Handlebars official Prettier for Ruby goes v1.0 🎉
A curious case of the ternaries
Alex Rattray · 2023-11-13 · via Prettier Blog

Ternary formatting has always been a challenge, and we're finally addressing it in v3.1.0 with the introduction of a novel formatting style.

Read on for our journey and the motivation behind this change, along with early developer feedback and an overview of the "curious ternaries" style.

Please give the --experimental-ternaries option a try and let us know what you think!

For a quick tl;dr, see the release post.

Introduction

Formatting nested ternaries nicely in a wide variety of scenarios is a surprisingly tricky challenge.

Developers have long found them so confusing to read that they end up just refactoring their code to an ugly series of if-else statements, often with a let declaration, an iife, or a separate function entirely.

According to beta testers, the new formatting style we've developed can take some getting used to, but ultimately allows ternaries to be practically used as a concise form of if-else-expressions in modern codebases.

Historical background

Prettier's original, naïve approach – just add indentation to each level of a nested ternary – worked fine in simple cases, but obviously doesn't scale to long chains of nested ternaries and had other problems.

So in 2018, we replaced that with flat ternaries, which seemed like a good idea at the time, but was not received well – the issue asking it to be reverted had well over 500 upvotes.

While we did ultimately revert back to indented ternaries, we wanted to find a better way.

Over the last few years, we explored and experimented with many, many possible solutions which would be as readable as indented ternaries in common cases, but also scale to work well in a wider variety of situations.

Challenging criteria

Ideally, we'd find one scheme that would meet our criteria:

  1. In all cases, it should be easy to follow "what's the if", "what's the then", and "what's the else" – and what they map to.
  2. The code should fluidly flow from a single ternary, to a chain of 2, to a long chain of simple cases, to something more complex with a few nested conditions. (Most alternatives we explored failed this test).
  3. The syntax in JSX, TypeScript conditional expressions (which cannot be expressed with if), and normal JS should all look and feel the same.
  4. It should scale to nested ternary chains of arbitrary length (imagine a TypeScript conditional type with dozens of alternative cases).

Indented ternaries clearly failed (4), arguably (1), and even (3) – we have almost always printed JSX ternaries in a flat-but-readable format that unfortunately felt unnatural outside of JSX.

Many people in the community were excited about a "case-style", drawing inspiration from the match syntax from languages like Rust or OCaml, but it did not meet (2) and other goals.

A surprising solution

The good news is that we found a formatting algorithm that met our criteria. The bad news is that it's novel, and thus unfamiliar to most developers.

In beta testing this feature, we found developers were quite skeptical when they first saw it:

"I'm not convinced the new version is simpler to read here."

But then, after using it for a bit, they didn't want to go back:

"I'm liking the ternaries! I think it makes sense to have them formatted like this. I also got used to them quite quickly as well. \nI agree with this, it takes a very short time to get used to it."

Another developer had this to say:

My first hour with the rule on, it felt a little odd. But by hour two, I’d used it a few times to solve problems that otherwise would have been ugly refactors to if statements. I’m not going back.

I used to hate nested ternaries, but I also hate restructuring a nice line of code into if-else statements. The new rule adds an understandable, linear if-else, if-else expression to the language and is much nicer than multiple ternaries as nested branches.

So we felt we had a winning formula, but we knew it could be a jarring introduction to the community.

As a result, we decided to put this new formatting behind a temporary --experimental-ternaries option for a few months, and in the meantime go ahead and ship what the community has been clamoring for: indented ternaries.

Styling Overview

So what does this new style look like, anyway?

Here's a quick, contrived example to show the thinking behind "curious" ternaries:

const animalName =

pet.canBark() ?

pet.isScary() ?

'wolf'

: 'dog'

: pet.canMeow() ? 'cat'

: 'probably a bunny';

  1. Every line that ends with a question mark is an "if".
    • If you see foo ? it's like asking a question about foo – "if foo? then, …".
  2. Every line that starts with a : is an "else".
    • If you see : foo that means, "else, foo".
    • If you see : foo ? that means "else, if foo?".
  3. Every line without : or ? is a "then".
    • If you just see foo, that means, "then foo".

And here's the code rewritten to demonstrate "case-style" ternaries:

const animalName =

pet.isScary() ? 'wolf'

: pet.canBark() ? 'dog'

: pet.canMeow() ? 'cat'

: 'probably a bunny';

You can see this is a nice concise way to get something approaching match-style syntax in JavaScript, with just the humble ternary operator (albeit missing several features).

Our new formatting is a fluid blend of "curious" ternaries (where the question mark is always at the end of the line), and "case-style" ternaries, where the question mark is in the middle of the line.

For example:

const animalName =

pet.canSqueak() ? 'mouse'

: pet.canBark() ?

pet.isScary() ?

'wolf'

: 'dog'

: pet.canMeow() ? 'cat'

: pet.canSqueak() ? 'mouse'

: 'probably a bunny';

Give us your feedback!

We hope you like the more readable new default, and we really hope you give the new --experimental-ternaries option a try for a few weeks and let us know what you think.

Please give us feedback via Google Forms: https://forms.gle/vwEuboCobTVhEkt66