Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resist adding configuration #40

Closed
gaearon opened this issue Jan 10, 2017 · 41 comments
Closed

Resist adding configuration #40

gaearon opened this issue Jan 10, 2017 · 41 comments

Comments

@gaearon
Copy link

gaearon commented Jan 10, 2017

You’re going to be under a lot of pressure to make X, Y, and Z, configurable.
Configuration is a perfect example of tragedy of the commons.

Everybody wants to add just a tiny piece of configuration to satisfy their use case. As a result we end up with inconsistently designed tools, with unexpected combinations that don’t work correctly, with bugs and regressions that, when fixed in one configuration, break something else with another configuration.

The requests for configuration are vocal. The requests to stay simple are often silent.

I just wanted to take a moment to say there are some of us who actually appreciate tools with limited scope that don’t attempt to solve everybody’s use case, and instead do a specific thing well.

@sapegin
Copy link
Contributor

sapegin commented Jan 10, 2017

If we as a community could find the most common JavaScript code style, I’d try to adopt it in my projects. I see a lot of benefits in that for me as a maintainer and for contributors of my projects.

@gaearon
Copy link
Author

gaearon commented Jan 10, 2017

The thing is, I don’t even care about “most common” here as much. I’m fine with @jlongster making common sense decisions as long as it’s something consistent and as bug-free as possible. These style differences don’t really matter, people care way too much about them.

@sapegin
Copy link
Contributor

sapegin commented Jan 10, 2017

The only reason for the most common style is to make less people adapt to a new one ;-)

@gaelollivier
Copy link

@gaearon Agree that style differences don't really matter and any crazy style that has auto-format support is better than one without.

However, for a project that is about formatting I think style questions should be taken seriously. If it's about defining a "standard" that would be used by many people, would be better to chose one that looks nice (to as many people as possible) :)

@jlongster
Copy link
Member

@gaearon I totally agree. Thanks for opening this issue because we need to discuss here what the real goal of the project is (and put it in the readme). I see three different goals:

  1. Converge on generally a single style (with very few basic options to help align with existing projects, like single/double quotes)
  2. Cater to a few large demographics (support tabs or spaces, semi or no-semis)
  3. Make it completely configurable/pluggable, possibly reading in eslint config and trying to adhere to that

I definitely don't want to do #3. There's just too much complexity already in making sure everything is consistent and I guarantee I will burn out (probably others too) if we attempt that and this project won't work.

I'm not sure about #2. The two most divisive issues in JS are tabs/spaces and semis/no-semis. There are already issues about them: #12 #34. I'm tempted to try to support those two options as a way to bring everyone together. Heck, if you wanted to turn on semis or switch to tabs it's a simple config switch. And like you, I just don't really care anymore which ones people use.

As I noted in the issues though, there are real problems trying to support those styles. Trying to emit semicolon-less JS means we need to detect where we have to emit a semicolon to avoid collapsing code where it shouldn't. Things like that.

When it comes to how function calls, object expression, etc are formatted, yes, I don't think we are going to change anything from how it already is. I'm not going to sit around and argue about specific styles. I'll change something if the majority of the community is asking for it, but otherwise, people don't need to worry so much about the minutiae of syntax.

For the time being, I think we should focus on #1. I'd love any advice for the tabs/spaces & semicolons issues though. I don't think we should do it until this project is clearly succeeding and a large group of people feel like they're missing out. My preference is to let projects evolve slowly so I'll resist until we feel it's right to make those decisions.

@natew
Copy link

natew commented Jan 10, 2017

Well, to speak for the commons, I'll throw in my 2c.

First, thank you very much for this project, it's exactly what we should be working on, well done, and will be extraordinarily useful for devs everywhere.

My vote is for at least implementing #2, and generally for making it as configurable as is tolerable for maintainers.

Why? Well, simply this: we are all different, and have different use cases. The more configurable it is (towards real-world desires, see issues + reactions for a good guage), the more helpful it is.

Second: the whole point of formatting is to allow people to have their code look how they want. If you make it look how you want, then you're not really serving the purposes of a community formatter very well, you're serving the purpose of the loudest/most well known/your desired formatter.

To me, luckily, this is not a big issue. We have a great system for tracking desires, we can debate them as they come up.

I also appreciate @gaearon for opening this, because it's good to know that some people desire to limit configurability. I can see one upside for that use case: the global look of JS becomes more similar. But, to me, that is not big enough to warrant subjugating the desires of every user to potentially help beginners, perhaps, though I doubt semis/no-semis and other similar ones make a big difference. Plus, if we're allowing line-length and other config, it's already making decisions on configurability, so drawing lines autocratically seems like a pretty unfriendly decision.

Finally: I hope that we can standardize on a lot of them, avoiding a lot of work for maintainers, & this is a very legit concern to balance.

Sincerely,
Someone who really hates semis 😛

Best of luck!

@dangoor
Copy link

dangoor commented Jan 10, 2017

Golang got around this question entirely by shipping gofmt early on. In JavaScript-land, we've got a long history now of people doing a wide variety of things.

Not implementing options for spaces/tabs and semis/no semis is a good thing to pushing toward a consistent standard across JS projects. The downside is that leaving those options out could hinder adoption among people who feel strongly about the opposing choices and open the door for a fork.

If I was leading this project: I would leave the options out and see where it goes, attempting to achieve for JS what gofmt brings to golang. JS isn't golang, so it's possible that's not the right choice for JavaScript, but I feel like there's little benefit to arguments over styling.

@munificent
Copy link

There is a very pragmatic concern around configuration: if you support, say 10 boolean config flags, then your test suite needs to be 2^10 bigger to cover all of the cases where those configurations interact. And they will, absolutely, interact, in nasty subtle ways.

Even when the formatter isn't configurable at all, there is already a long bug tail just with how different language features interact in the formatter.

Whether it's better for users or not (I personally lean on the side of not), configurability is a nightmare for the maintainer of the formatter itself.

@jlongster
Copy link
Member

Thanks you @dangoor, that is good insight and I agree. Right now let's focus on making this solid for the demographic of people who use spaces and semicolons at least. We can go from there.

@munificent that's a fantastic point. I've already run into that with the current options, because I use Jest snapshot testing, but they are all generated only with the default options. If someone makes PR, I don't see how it affects the code if the options are turned on. And I'm definitely not going to have a 2^N number of tests folder where N is the number of flags.

@robertknight
Copy link

I can see only one upside for that use case: the global look of JS becomes more similar.

Speaking from what I've seen of the Elm, Go, Rust and Python communities, where style is highly standardized, this is a big upside and a desirable outcome. It means that when reading someone else's code you can focus on the more important higher level aspects and not get distracted by unimportant differences.

There are I think significant social benefits as well - it eliminates a source of confusion for beginners (how do I format this to align with this project's conventions?), a source of tension for new contributors to a project (your PR is fine but it doesn't matching the coding style conventions of this project) and it general it gives the whole community a more cohesive feel.

@jlongster
Copy link
Member

@natew I empathize with your point at well. I don't think we need to do everything at once. If we try to do too much, there's a real chance this project will die, so all of our efforts are nullified. Right now I want to constrain the scope to make sure we make this robust, and we can go from there.

@matb33
Copy link

matb33 commented Jan 10, 2017

Allowing configuration is a tough call at this stage because this tool today offers two things: a better formatter (parsing into an AST) and an enforced style. I believe many users seeing this project are more interested in the benefits that the parser brings than the enforced style, since we all bring our style baggage with us.

So what it comes down to is to clearly identify what this project is. Is it primarily a great parser with configuration to allow other styles, or is it a specific style with a great parser?

It sounds like it's the latter. I think it's the correct choice to start. Bang out the bugs and edge cases. Someone else can always stand on this project's shoulders and build the former.

@swansontec
Copy link

I would like to point out the standard.js project, which provides a style guide and a no-configuration linter. Their idea exactly mirrors this thread - we should all just pick something and go with it, even if some people get annoyed. The benefits of tabs vs. spaces or whatever just aren't worth the bike-shedding and general confusion.

Of course, this attitude does no good if all the opinionated tools disagree. Prettier is pretty close to the standard.js style already, and wouldn't take too much work to become 100% compatible. At 10k daily downloads on NPM, standard already has a lot of users who are ready for no-bikeshed, just-works style tools. From testing on my own codebase, which uses standard already, I see the following differences with prettier:

Single quotes are already supported, but as an non-default option, so that's OK.

@matthewp
Copy link

@swansontec People who argue "you shouldn't have an opinion on style" are always the people who themselves have an opinion on style.

Opinionated tools are great and I agree with the less configuration the better. Choose the style you like for your own tool. Just don't try and pretend like you're really doing everyone else a favor by making their decisions for them.

@swansontec
Copy link

swansontec commented Jan 10, 2017

@matthewp I hear what you are saying, but regardless of where you fall on the configurable vs. opinionated spectrum, isn't it better when tools can work together?

@ghost
Copy link

ghost commented Jan 11, 2017

I'm not really adding much to the discussion when I say this, but I love this project because it already matches my style of coding almost exactly, and it seems like a great way to get some junior devs I'm training on the same page as well. I agree 100% with the lack of support for configuration. The more people throughout the JS community on the same page, the better, I think.

@msegado
Copy link

msegado commented Jan 11, 2017

Re. "we should all just pick something and go with it": I respect what standard.js did here, but one problem I see is that the "something" picked wasn't (to the best of my knowledge) the "something" already in use by any major JS projects like jQuery, Node, lodash, etc. If unifying the community around a common style is truly an important goal, I think it's worth trying to garner consensus among maintainers of the biggest/most-popular JS projects before setting anything in stone. The idea would be for several major players to agree on a reasonable solution which they would be willing to adopt in their own projects for the benefit of the community... it might be that such a consensus is only possible with a few flags for things like tabs/spaces and semi/no-semi, but given the experience that such maintainers have with large software projects, I expect they would be some of the most qualified people out there to find a reasonable compromise between flexibility/configurability and testability/maintainability.

tl;dr: if we want a standardized community style, i think we need to involve maintainers of existing large projects, both to gain critical mass and to make better-informed decisions.

@gsklee
Copy link

gsklee commented Jan 11, 2017

Hi @jlongster, just would like to chime in and let you know that your project has hit the jackpot and solved something that even (the self-proclaimed) Standard and Semi-Standard couldn't solve for me:

Easy team-wide style enforcement that's based on an unbiased 3rd party algorithm to produce a one and only definitive way to indent absolutely each line of code

Such a great feat! Please stick to it no matter how hard someone tries to lobby you into doing something that's against this value. Oh, and no, you don't need to "serve for the purposes of the community" - that's exactly how mobs killed the passion of the Babel team. Just stick to your gut feeling! 😉

@gilbox
Copy link

gilbox commented Jan 11, 2017

Pedants of the world fear that a student of economics will, in the course of his due studies, search Google for "a prettier and perfect example of tragedy of the commons" and happen across this post. Unfortunately, there is nothing perfect about this example. For such a common tragedy should involve some shared, limited resource. But what is the resource in this case? Time? Configuration? Code? No, dear student, look elsewhere for your pretty perfect examples. And besides, adding the phrase prettier to your search engine query was pretty silly to begin with--don't you think, pretty boy?

@bernharduw
Copy link

My 2ct: Embrace forking instead of adding configuration. It keeps this repo and maintaining the tests much simpler, and Github stars or npm installs are a much better way to track the popularity of a styling preference. Once you throw in a config option, you'll basically have to maintain it forever – even if only a single user needs it (and you wouldn't even know).

At least from a user's perspective, this works very well for the standard package. Over time a small ecosystem of forks has evolved (semistandard, uber-standard, happiness etc.). Instead of having to configure a do-it-all-standard package, it's much easier to just npm install semistandard if you prefer. Numerous times I considered forking semistandard to throw in dangling-commas, but the pain of maintaining my own fork outweighed the benefits of using my preferred style.

If someone feels the strong urge to use no-semicolons-style, they are free to create a prettiest fork. If anyone prefers tabs, please fork to a pretty-tabs repo. We'll see which forks gain significantly more traction over others. And maybe eventually it might also make sense to create a common, unopinionated pretty-basic module which all the forks will share - who knows? ;-)

So: no configuration, but happy coexistence of forks.

@jefffriesen
Copy link

Having a single standard helps with PRs on open-source projects. It's easier for a maintainer to specify the style to be prettier than prettier with a list of option settings.

I am very opinionated about semicolons, quotes and spaces/vs tabs, but I would gladly concede if we could standardize on something.

@rafayepes
Copy link

@jlongster do we even need point 1? I'll suggest delaying config options as much as possible. If the tool works excellently without many problems it might start to get traction enough to convert people :)

@wmertens
Copy link

wmertens commented Jan 11, 2017

How about making the AST rewriting pluggable, much like Babel makes AST parsing pluggable? You can ship a default config much like babel-preset-latest that does what prettier does by default, and people can go crazy inventing good rewrites that are too specific for general use, like enforcing camelcase.

I mean, there is a bunch of machinery required for doing the rewriting, and it is great if there is only one place to go to maintain all that, but for individual rules there is just too much variation to make a set of configuration options that will even only please 80%.

Also, this is exactly what Redux does :). Its simple and elegant API allows very powerful configuration.

@gaearon
Copy link
Author

gaearon commented Jan 11, 2017

But what is the resource in this case? Time? Configuration? Code?

Maintainers’ time and energy. That’s what runs open source projects, not code.
Increasing bug surface area through configuration burns maintainers’ time and energy.

Ask any maintainer with the experience of adding configuration options.
I think #40 (comment) is a good explanation of this, too.

@gaearon
Copy link
Author

gaearon commented Jan 11, 2017

On a practical note it means that it’s okay to add configuration that doesn’t cause exponential growth of bug surface area. A good example is string quotes. It’s fine for them to be configurable because they are unlikely to clash with other options and cause bugs. On the contrary, making semicolons configurable has a vast impact on all other cases.

@marcialca
Copy link

marcialca commented Jan 11, 2017

Following on @gaearon comment, an idea would be to make a list of all the possible configurations and decide if they produce clashes (like semicolons) or they don't (string quotes) and maybe analyse their introduction to the core, based on this point:

doesn’t cause exponential growth of bug surface area.

That would make a clear point and explanation on why something is not added or is made configurable and it would make a good pillar for the project and it feels like a good middle ground.

@munificent
Copy link

A good example is string quotes. It’s fine for them to be configurable because they are unlikely to clash with other options and cause bugs.

Well...

If you normalize all strings to use a single quote style, then you may need to add escapes to some existing strings. Normalizing to double quotes means you need to turn '"' into "\"". That in turn affects the length of the string, which impacts other formatting.

If you're going to do that, does that mean you normalize other escapes as well?

So, off the top of my head, I can imagine configurations for:

  • Don't touch my string literals.
  • Normalize all string literals to '.
  • Normalize all to ".
  • Normalize all to ' unless it contains ' in the string.
  • Normalize all to " unless it contains " in the string.
  • Normalize all to ' unless it contains ' in the string and it isn't already escaped.
  • Normalize all to " unless it contains " in the string and it isn't already escaped.
  • Normalize to the representation that requires the fewest escapes, with ' as the preferred default.
  • Normalize to the representation that requires the fewest escapes, with " as the preferred default.
  • Normalize to the representation that requires the fewest escapes, with the original delimiter as the preferred default.

I could go on...

@lock lock bot added the locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. label Jul 5, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Jul 5, 2018
@j-f1 j-f1 added keep-unlocked and removed locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. labels Aug 19, 2018
@prettier prettier unlocked this conversation Aug 19, 2018
jhnns added a commit to peerigon/eslint-config-peerigon that referenced this issue May 16, 2020
BREAKING CHANGE: Based on discussion #76 we decided to remove our Prettier configuration.
In order to avoid useless discussions, people should format their code with thatever style Prettier uses. Configuring Prettier ultimately defeats the purpose of Prettier, see prettier/prettier#40
github-actions bot pushed a commit to peerigon/eslint-config-peerigon that referenced this issue May 16, 2020
# [28.0.0](v27.8.0...v28.0.0) (2020-05-16)

### Features

* Remove Prettier configuration ([e6c0d39](e6c0d39))

### BREAKING CHANGES

* Based on discussion #76 we decided to remove our Prettier configuration.
In order to avoid useless discussions, people should format their code with thatever style Prettier uses. Configuring Prettier ultimately defeats the purpose of Prettier, see prettier/prettier#40
@ITenthusiasm
Copy link

TL;DR

I think some (few) options should be considered in the context of visual overload.


@j-f1 A million and one thanks for applying keep-unlocked! I was looking for somewhere to talk without opening a type of issue that's explicitly discouraged.

Using a quick ctrl + f word search in Chrome, eyes, eye, and visual never appear (I didn't expand Hidden Items). Searching for read yields 20 results, but in all of the results, it appears as part of a larger word. In only 2 of those 20 results does the word have anything to do with reading. (In fact, both results are reading.) But neither of those results have anything to do with how easy it is to read code. For fun, cognitive never appears once. And load and mind never appear as individual words that are part of the conversation.

I imagine it's obvious where I'm going... I can generally respect the decision to refuse to add more options moving forward from what I've read. There are things that are minuscule that really shouldn't be a point of contention. However, my concern throughout this entire discussion is whether or not Prettier is considering the potential unintended side-effects on visual overload or cognitive load.

I'm asking this question in the context of #840. In general, I think Prettier itself considers this in certain situations... like printWidth. There's a lot of cognitive load that comes with repeatedly scrolling left and right to read code. And UI/UX folks have discovered that people respond much more negatively to horizontal scrolling. It's great if Prettier helps people write code that helps avoid cognitive load. If it stays hands off, that's also fine. But once it unchangeably enforces a rule that potentially adds cognitive load, there's a problem.


So... my question becomes... is the team considering cognitive load? (I'm sure they are to some extent if printWidth exists.) And would that help them reconsider certain options? (It could be difficult to identify those options.) I understand if a no is a no; but please consider the following:

From jlongster's comment and jefffriesen comment, semicolons, quotes, and spaces-vs-tabs seem to be examples of major points of contention. Semicolons might have their place (the brain being able to explicitly see where a statement is finished). But quotes and spaces-vs-tabs don't really have a significant impact on the eyes; they are primarily preference-based. One extra ' won't really add overload. Whether spaces or tabs are used, proper indentation is what spares visual overload, not so much the method. So if, in another world, those 2 options weren't available, it wouldn't be a huge deal.

Cluttered lines are an entirely different story, though. And they can cause visual overload. But Prettier can't [and shouldn't] make enforcements here because user cognitive overload is unpredictable. For instance, a collection of related variable declarations without any in-between spaces may help the brain separate and group together related blocks of code. In another circumstance, spaces might make more sense. All prettier can do (and does) is prevent the other problem of having too much in-between space -- which is easier to justify.

In the context of conditionals, Prettier forces

if (condition1) {
  // Do stuff
} else if (condition2) {
  // Do different stuff
} else {
  // Fallback stuff
}

This isn't a big deal if the condition is not complex. But if the condition is complex enough to extend a large width without causing a line break, and/or the final line in the previous block is long enough to do the same, then the eyes may start to have a harder time.

if (smallCondition) {
  // This time my last statement may extend like 40-70 chars
} else if (firstCondition && this_is_a_slightly_complex_condition) {
  // Oh boy. Is it time for another long statement
} else if (this_is_a_single_condition_but_still_kinda_large) {
  // At least my last line is small
} else {
  // Fallback stuff
}

If I'm trying to quickly scan the code, learn new code, or remember old code, this becomes a visual burden for me. I've felt it when developing locally. I've typically gotten around it by doing switch/case, where Prettier can't interfere with line breaks. Avoiding if/else by using return statements also helps. But not all conditional situations can be reduced to such structures. And in these cases it still bites. Comments don't help the problem. If your code is sufficiently self documenting, then comments are redundant at best and add additional visual overload at worst.

if (smallCondition) {
  // This time my last statement may extend like 40-70 chars
}
// The firstCondition && this_is_a_slightly_complex_condition yay more overload
else if (firstCondition && this_is_a_slightly_complex_condition) {
  // Oh boy. Is it time for another long statement
}
// This does that for this_is_a_single_condition_but_still_kinda_large yay more overload
else if (this_is_a_single_condition_but_still_kinda_large) {
  // At least my last line is small
}
// Redundant fallback statement
else {
  // Fallback stuff
}

Redundant comments are a problem because they suggest to the developer that something unapparent in the code needs to be given attention. But if it is redundant, the developer then has to train their brain to ignore the additional distracting text.

One can try to argue about optimizing if/else statements. But the reality is that sufficiently long final-lines or conditions are a real possibility. And honestly, the upcoming conditional and the last line of the preceding block don't even need to be long to be distracting. They can be sufficiently small, but still be distracting because they're approximately the same length. This is avoided by letting people add a newline:

if (smallCondition) {
  // This time my last statement may extend like 40-70 chars
}
else if (firstCondition && this_is_a_slightly_complex_condition) {
  // Oh boy. Is it time for another long statement
}
else if (this_is_a_single_condition_but_still_kinda_large) {
  // At least my last line is small
}
else {
  // Fallback stuff
}

This is why I think breaks before else would be a great option to add. The issue is not merely a preference issue. And I'm willing to bet that several people in #840 who were saying newlines are better are probably experiencing a similar problem. But because cognitive load can be subconscious, many of them probably just recalled the feeling they get when they see "ugly-formatted-code" and just left a basic complaint.

As a reminder, I'm talking visual overload. Not "That irks/annoys me" overload. The former is not something so easy to "get over" or control.

I know that was a lot, but I wanted to make a sufficient case. The code blocks added length too. Thoughts? I really hope the answer is an "okay". If the answer is no, that's fine. I'd just hope for a sufficient set of reasons on the topic of visual overload. And I hope it's at least obvious that something like this is significantly more impactful visually / mentally compared to many other options that can more easily be reduced to mere preference like tabs, quotes, jsx-quotes, trailing-comma, etc.

@ITenthusiasm
Copy link

As an added note:

If the consensus becomes that visual overload isn't a significant problem or consideration, it might be useful to add that to the philosophy page too.

@SephReed
Copy link

For anyone who believes in science, I'd like point out that the level of consensus in this thread is very likely contextual. People who don't like opinionated tools aren't likely to spend more than a few minutes looking at prettier... unless, there's no other options.

On that note, I've been searching around for a non-opinionated code formatter. Does anyone have any recommendations?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests