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

Call for a unified metastyle #216

Closed
timdp opened this issue Aug 2, 2015 · 21 comments

Comments

@timdp
Copy link

commented Aug 2, 2015

For me personally, Standard immediately made a lot of sense and all I had to do to adopt is was basically drop my semicolons, so I did. More broadly speaking though, it seems to me like the community will forever be on the fence about at least two things:

  • tabs vs. spaces (and how many of them) and
  • semicolons

and that's perfectly okay! Choice is good.

However, with forks like Semi-Standard and Happiness emerging, as well as the more independent XO, it (again) feels like people are going through the same thought process over and over, and subsequently setting up a software architecture for the result of that thought process.

Even if the end result isn't the exact same, they're always configuring linters and style checkers, building additional tools that scan your project structure, documenting their styles and APIs, integrating them with your IDEs and editors, and discussing them on social and other media. It might not seem like that much work initially, but to me, it sounds a lot like those repetitive steps could be avoided. Moreover, if there was a single entry point for them, and for the styles themselves, the community as a whole would benefit from the added discoverability and reusability.

Therefore, I call upon @feross, @Flet, @JedWatson, @sindresorhus, and many, many others to consider devising not one monolithic style to rule them all, but a metastyle that enforces sensible defaults and leaves just enough choice to the developer or organization using it. The difference from using "Just run ESLint" (and/or JSCS, and/or standard-engine) as a mantra would still be significant: I feel that there's a lot of stuff that we all agree on, and a handful of things that's making us reinvent the wheel over and over, and needlessly making people choose between wheels that are all perfectly good. Consider this my pamphlet for a single, community-approved code style.

XO already takes the concept a little bit further by making tabs configurable, and naturally, an issue appeared asking to make semicolons configurable as well. I think that actually proves my point: people are 99% satisfied, and naturally, they want that additional 1%, which always turns out to be about the same handful of things. Sindre replied that his intent was to be opinionated, and I do see his point, but I think it's safe to say that this issue is eventually going to result in another fork. There must be a better way.

JavaScript has grown and matured immensely over the past couple of years. As part of that process, we've seen numerous style guides, dotfiles, and tools crop up, dedicating valuable resources to often repetitive work. Standard and friends paved the way yet a bit further, and I do think they're all absolutely great, but the overlap is unnecessary. If we can find enough middle ground here, and come up with a config that works for (nearly) everyone, then we can greatly reduce the technical complexity of setting up ESLint just right, build the tooling to go with it, and grow a community that actively documents and maintains a real standard. Let's put our heads together and save everyone a lot of time, so they can spend it on building more and better JavaScript projects.

I realize that an effort like this could result in yet another style guide that would at best complement the many great ones out there. I'd hate to undermine Crockford, Airbnb, NPM, jQuery, Idiomatic.js, and many others because, and I can't stress this enough, they've all done such tremendous work. At the same time though, it all feels so tedious that in the year 2015, surely there must be a more efficient way.

I don't have any authority in the JavaScript community and I'm not expecting anyone to take my word for gospel. I'm just a lowly software engineer who loves writing JavaScript and building upon others' amazing work, a sentiment which we all share, I'm sure. I'm trying to convey an observation here that will hopefully further the language, and evoke some input on the subject. I'll absolutely welcome anyone's thoughts. If you think it's a dumb idea, just say so. In the meantime, thanks for making it all the way to the end.

(Note: I'm posting this as an issue under Standard because it feels to me like that's the one that started this new wave of style checkers. It might as well have been an issue under any of the other tools that I mentioned, or a post on Medium, for example.)

@sindresorhus

This comment has been minimized.

Copy link

commented Aug 3, 2015

Obligatory ⬇️ :p

image

XO already takes the concept a little bit further by making tabs configurable, and naturally, an issue appeared asking to make semicolons configurable as well.

In XO 0.5.0, it's now possible to override any rule, including semicolons.

@timdp

This comment has been minimized.

Copy link
Author

commented Aug 3, 2015

@sindresorhus Thanks for weighing in!

I was reminded of that xkcd myself actually, which is why I wrote the paragraph about "yet another style guide". Even so, it's something that can be avoided, I think.

I'm not sure how to feel about being able to override any rule. Basically, you've turned XO into a facade for ESLint now. I'm not saying that's a bad thing—again, choice is good—but if there's a need for a tool that makes ESLint usable, maybe the issue lies with ESLint.

That got me thinking again about how much of a pain it can be to fully set up and tweak an array of code quality tools for your new project while all you really want to do is get coding. Maybe I'm just missing a good bootstrapping tool, a better boilerplate repository, some Atom packages, or a full-blown IDE. Maybe I should just start using Yeoman more. I don't know.

What I do know is that it all feels too complicated to me, and that's what prompted all this. I still stand behind that. It could be that I'm trying to fix the wrong problem, but something needs fixing.

@feross feross added the question label Aug 3, 2015

@ATouhou

This comment has been minimized.

Copy link

commented Aug 4, 2015

I couldn't agree more.
No developer in his right mind, would argue that there should'nt be ONE unified style, but but but -> The hard part is getting everybody to obeying by your rules ( like seriously
I will neeeever get used to doing this:
"Space after keywords if (condition) { ... }
Space after function name function name (arg) { ... }"
).

So why not CHANGE the way we want to handle this problem??

Instead of linting and forcing everyone to use one certain style, why not let them code in whatever style they want, but make a plugin for all texteditors/IDE that on the click of a button, will format the code to a certain style that you yourself like? Then there could be standard "styles", hence, it is easy to switch in between all the styles, at the click of a button...

What do you think about this approach?

@LinusU

This comment has been minimized.

Copy link
Member

commented Aug 4, 2015

@ATouhou That would be a mess in git thought. Could you imagine the whole file being changed just for a small typo fix?

The extreme of that path is to commit the AST in git and let everyone check it out in there own style. But what happens when I place empty lines to group different part of a function body?

I think it's just really hard to do right, not to mention that there will always be a lot of tooling required.


Standard has ~100 rules and I'm pretty sure that most of these are shared between standard, semistandard, happiness and xo.

I think that what would be cool, and what I understood this issue to be about, is to identify which rules that we actually all agree on; and than maintain that together.

Then all other rules will be defined by each standard independent, and I can keep using standard because I feel semicolons is unnecessary.

It would also be cool to maintain some kind of "compatibility matrix", I can't figure out what rules, if any, are different between xo and happiness.

@ATouhou I have yet to seen a standard that allows if without a space (which is good because that's how you distinguish function calls from language constructs) so you'll have to create your own standard. This would be easier for you if we can all decide on a common set of rules since you won't have to write everything from scratch.

@LinusU

This comment has been minimized.

Copy link
Member

commented Aug 4, 2015

So I did some digging on standard and xo and it turns out that they have 79 identical rules.

Then there is 60 that differs:

Rule Standard XO
no-constant-condition undefined 2
no-extra-parens [2,"functions"] 2
no-extra-semi undefined 2
no-inner-declarations [2,"functions"] 2
block-scoped-var undefined 2
consistent-return undefined 2
curly [2,"multi-line"] 2
default-case undefined 2
dot-notation undefined 2
eqeqeq [2,"allow-null"] 2
guard-for-in undefined 2
no-alert undefined 2
no-div-regex undefined 2
no-else-return undefined 2
no-eq-null undefined 2
no-implicit-coercion undefined 2
no-invalid-this undefined 2
no-loop-func undefined 2
no-return-assign 2 [2,"always"]
no-script-url undefined 2
no-unused-expressions undefined 2
no-void undefined 2
no-warning-comments undefined 1
wrap-iife [2,"any"] [2,"inside"]
yoda [2,"never"] 2
strict undefined [2,"global"]
no-unused-vars [2,{"vars":"all","args":"none"}] 2
no-use-before-define undefined [2,"nofunc"]
callback-return undefined [1,["cb","callback","next","done"]]
handle-callback-err [2,"^(err error)$"]
no-mixed-requires undefined [2,true]
no-path-concat undefined 2
no-restricted-modules undefined [2,"domain","freelist","smalloc","sys"]
array-bracket-spacing undefined [2,"never"]
brace-style [2,"1tbs",{"allowSingleLine":true}] [2,"1tbs",{"allowSingleLine":false}]
camelcase undefined [2,{"properties":"always"}]
computed-property-spacing undefined [2,"never"]
consistent-this undefined [2,"self"]
indent [2,2,{"SwitchCase":1}] [2,"tab",{"SwitchCase":1}]
linebreak-style undefined [2,"unix"]
max-nested-callbacks undefined [1,4]
new-cap [2,{"newIsCap":true,"capIsNew":false}] [2,{"newIsCap":true,"capIsNew":true}]
no-inline-comments undefined 2
no-lonely-if undefined 2
no-nested-ternary undefined 2
object-curly-spacing undefined [2,"never"]
one-var [2,{"initialized":"never"}] [2,"never"]
operator-assignment undefined [2,"always"]
padded-blocks undefined [2,"never"]
quote-props undefined [2,"as-needed"]
quotes [2,"single","avoid-escape"] [2,"single"]
semi-spacing undefined [2,{"before":false,"after":true}]
semi [2,"never"] [2,"always"]
space-before-function-paren [2,"always"] [2,{"anonymous":"always","named":"never"}]
space-unary-ops [2,{"words":true,"nonwords":false}] 2
spaced-comment [2,"always",{"markers":["global","globals","eslint","eslint-disable","*package","!",","]}] [2,"always"]
generator-star-spacing [2,{"before":true,"after":true}] [2,"before"]
standard/object-curly-even-spacing [2,"either"] undefined
standard/array-bracket-even-spacing [2,"either"] undefined
standard/computed-property-even-spacing [2,"even"] undefined
This was referenced Aug 4, 2015
@timdp

This comment has been minimized.

Copy link
Author

commented Aug 4, 2015

Awesome work, @LinusU!

I somewhat agree with @ATouhou:

Then there could be standard "styles", hence, it is easy to switch in between all the styles, at the click of a button...

linter-js-standard by @ricardofbarros already takes this approach. The name "linter-js-standard" doesn't really apply anymore though.

Expanding upon this, my goal would be to have a set of community-approved default styles then, which all plug into linter-js-standard (or let's say "linter-js-sanity" or something) through a common format. That format could be just a combination of an ESLint and a JSCS config.

Even then, you'd have to pick a style, so there would ideally be a nice GUI with a previewer. A lot of IDEs do this already. And the question remains of course what the most sensible default for that choice would be.

Which brings me back to my original point: rather than writing a community-approved style and the associated tooling from scratch, it makes a lot of sense to have a single repository and format for all styles.

@markogresak

This comment has been minimized.

Copy link

commented Aug 4, 2015

@ATouhou that's beautify, I use it in atom and used it in sublime. There are also format code features in any IDE I had used to date.

@LinusU there wouldn't be such a big problem in git. You could do one special commit to fix all the styling and since every team member/contributor should follow the same guidelines, this wouldn't be an reoccurring issue.

@timdp I agree with your last point, I doubt there will ever be a style which will be approved and used by majority of the community, so it doesn't make sense to try doing the impossible over and over again.

@ATouhou

This comment has been minimized.

Copy link

commented Aug 4, 2015

@markogresak The difference between any beautifier/indent tool, and my proposal is that, the differences will somehow be saved (maybe just like github compares files and their differences).
So that user at any time can see his original version, or "compile" the code to the "fixed" version.
Or in reverse, when a person opens it, they can compile and work on the "fixed - standard styled" file -> and when done , only his changes would be in the "newer" format, but the other user, would see his file, in his style. Maybe even in the future, there could be developed some AI, that reads the users style and formats the file, to match his style. (By AI and not by configuring a rule set, which initialy would be the way to solve it).
@LinusU So with this method, changes could be stored in a single file, or multiple files in a subdirectory, leaving the files as "original style of the creator", hence not converting it and "ruining it" for the first creator , if he decides to do some more work on it.

To impose a ruleset in style upon people, where they have done something "another way" all their life, or "learned it the wrong way". Would be near impossible (just call me a realist :P )

@dcousens

This comment has been minimized.

Copy link
Member

commented Aug 5, 2015

The extreme of that path is to commit the AST in git and let everyone check it out in there own style

That sounds wonderful.

@timdp

This comment has been minimized.

Copy link
Author

commented Aug 6, 2015

The extreme of that path is to commit the AST in git and let everyone check it out in there own style

That sounds wonderful.

I've seen that idea being floated around a couple of times and I love it too. Not sure how realistic it is though.

One major impediment would be adoption in VCS front ends like GitHub. I guess a Chrome extension would work too, so it could be a community effort initially.

It would also be great if the serialized AST format were almost as readable as the code itself, although that seems even more utopic.

Assuming that this ever becomes a reality, that still wouldn't mean that standardized code style would suddenly become obsolete. There's still a clear need for easily recognizable and configurable code styles, because you'll want to configure your code formatter without hassle. The process of style checking and linting would become less important though.

@yoshuawuyts

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2015

-1 for storing source code in an AST; doing that is only be marginally better than storing it as a binary blob (which is a bad idea).

Actually I'm not sure there's a need to store it as an AST: esprima / acorn are pretty fast for creating ASTs on the fly. I think all that's needed is different formatters (like standard) and maybe some scripts to keep git diffs usable.

edit: to clarify why storing source code in an abstract format is a bad idea: you don't want to depend on tooling to interact with source files. If you require tooling to interact with code you create multiple barriers of entry to any given project. E.g. what if only a chrome extension exists and users use firefox? What if you don't have the right tooling setup to checkout projects and want to submit a patch? What if you're a beginner and finally have the courage to inspect the source of a project, and all you see is weird abstractions? I don't think storing source code in an abstract format will be ever worth it.

@timdp

This comment has been minimized.

Copy link
Author

commented Aug 9, 2015

@yoshuawuyts (Hi!) Isn't it more a matter of providing adequate tooling then? For that hypothetical Firefox user, you'd need to have a Firefox extension ready.

Most open source projects already require new contributors to get on with their tooling: you need to install dependencies, familiarize yourself with Grunt/Gulp/Broccoli/whatever, understand the testing framework(s) being used, get to know the documentation format, etc. The reason why the community copes with all those additional thresholds is not because they're easy to cross, but because they're understandable, well-documented, fairly commonplace, and community-approved.

Of course, that in itself doesn't warrant introducing another hurdle, but let's not throw the baby out with the bathwater.

@yoshuawuyts

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2015

(Hey!) The strength of unix lies in that everything is stored in human-readable, plain-text formats. For some things it makes sense to use binary (storing pixels, wire protocols, etc.) but it doesn't make sense to store source code in a non-human readable format.

Again: the difficulty of this problem isn't so much obtaining an AST (esprima is pretty good at that), but formatting it. Right now you can already do:

git clone -> source (standard fmt) -> AST -> source (semistandard fmt) -> AST -> source (standard fmt) -> git commit -> git push

I don't see a reason to store the AST in git and part with the unix philosophy.

@dcousens

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

@yoshuawuyts my understanding wasn't that it was stored as an AST, but committed as an AST. Much like how git checks out line endings in terms of your operating system.

@timdp

This comment has been minimized.

Copy link
Author

commented Aug 10, 2015

@yoshuawuyts I think you mainly need a way to represent the AST in a human-readable way then, but of course, the most human-readable way is the code itself. So that would shift the problem to coming up with a style that can be used as an AST representation in the repo then, which is pretty close to the original problem.

Also, come to think of it, there are still cases where automatic formatting won't work and you'll want to do some stuff manually. For example, an extra blank line might make sense in one style but not in the other. That can all be solved with even more style rules, but there's always going to be some leeway, I think.

@dcousens I'm not sure I get that last comment. Would you then make Git aware of the language? Or are you referring to the build process somehow?

@dcousens

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

Would you then make Git aware of the language? Or are you referring to the build process somehow?

I'm not sure of the reality of the idea, it was just a passing comment. I imagine it probably need to make git aware of it.

@stevemao

This comment has been minimized.

Copy link

commented Aug 18, 2015

I think this is a good concept. No wasting time configuring rules. But I definitely think the rules need to be very strict.

@feross

This comment has been minimized.

Copy link
Member

commented Aug 21, 2015

Committing the AST is way out of scope for standard. Feel free to explore this idea in another package.

@feross feross closed this Aug 21, 2015

@timdp

This comment has been minimized.

Copy link
Author

commented Aug 21, 2015

Originally, this issue wasn't about committing the AST, but about having more collaboration and avoiding repeating tedious configuration steps. I totally respect your decision to close the issue because it was obviously going off topic, but I'm struggling to find a better channel for this discussion, which I think is still worthwhile.

@feross

This comment has been minimized.

Copy link
Member

commented Aug 21, 2015

@timdp You seem earnest, but if you really wish to avoid spending time on configuration, you should just use standard (or one of the forks). That's the whole point of this package: avoiding configuration :)

If there's a rule that really bothers you, then extend eslint-config-standard, or make your own fork.

What else is there to discuss?

@timdp

This comment has been minimized.

Copy link
Author

commented Aug 21, 2015

Personally, I'm using standard already, but I can see why people would want to use one of the forks or an entirely new style such as xo. I don't want to repeat myself too much, but it seems like a waste to set up distinct packages that share so much common ground.

I think the modularity of standard helps a lot. That's why I originally mentioned standard-engine too. It feels like there's even more to gain though.

So there's a lot to discuss, I think. Whether it makes sense to spend resources on that discussion and whether the discussion should take place here are different matters.

@lock lock bot locked as resolved and limited conversation to collaborators May 11, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
9 participants
You can’t perform that action at this time.