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 · 38 comments

Comments

Projects
None yet
@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

This comment has been minimized.

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

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 ;-)

@gaelduplessix

This comment has been minimized.

Copy link

gaelduplessix commented Jan 10, 2017

@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

This comment has been minimized.

Copy link
Member

jlongster commented Jan 10, 2017

@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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

munificent commented Jan 10, 2017

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

This comment has been minimized.

Copy link
Member

jlongster commented Jan 10, 2017

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

This comment has been minimized.

Copy link

robertknight commented Jan 10, 2017

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

This comment has been minimized.

Copy link
Member

jlongster commented Jan 10, 2017

@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

This comment has been minimized.

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

This comment has been minimized.

Copy link

swansontec commented Jan 10, 2017

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

This comment has been minimized.

Copy link

matthewp commented Jan 10, 2017

@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

This comment has been minimized.

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?

@timbur

This comment has been minimized.

Copy link

timbur 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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

bernharduw commented Jan 11, 2017

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

This comment has been minimized.

Copy link

jefffriesen commented Jan 11, 2017

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

This comment has been minimized.

Copy link

rafayepes commented Jan 11, 2017

@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

This comment has been minimized.

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

munificent commented Jan 11, 2017

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...

@rattrayalex-stripe

This comment has been minimized.

Copy link

rattrayalex-stripe commented Sep 23, 2017

Prettier now has a configuration file.

Docs: https://github.com/prettier/prettier/blob/master/README.md#configuration-file
Release notes: https://github.com/prettier/prettier/releases/tag/1.6.0

The ethos of prettier very much remains "resist adding configuration wherever possible" and it is very unlikely that further configuration will be added in the future.

@j-f1

This comment has been minimized.

Copy link
Member

j-f1 commented Feb 2, 2018

There is a new page on the website that sums up our option philosophy, which is pretty similar to @gaearon’s original comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment