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

Document code style guidelines #1243

Closed
brendanashworth opened this issue Mar 23, 2015 · 18 comments
Closed

Document code style guidelines #1243

brendanashworth opened this issue Mar 23, 2015 · 18 comments
Labels
discuss Issues opened for discussions and feedbacks. doc Issues and PRs related to the documentations.

Comments

@brendanashworth
Copy link
Contributor

After #1220, the need for meta-documentation seems prevalent, and the lack of it leads to unproductive discussions, as in #1241. If only we had a good, solid answer. This should also reduce the amount of unproductive discussion related to style nits in PRs - I'd say a large majority of edits a new contributor has to do, primarily deals with style.

Here's my proposal for the guidelines with what I could scrounge up from code as is. We can also discuss sharing a style guide with another project, like airbnb, but I think the core style is different from any others, as is.

When in doubt, make lint. This style guide doesn't cover stuff that fails lint (I think).

JavaScript

Variables

  • const should always be used over var for variables that never change, such as require'd modules
  • let should not be used [until v8 speed against var increases]
  • variable names should be camelCase, unless they are a FunctionConstructor

Conditionals

  • when using a conditional such as if {} else if {} else {}, it must all have braces or it must all not have braces, no mixing of braces
  • for simple if conditionals, do not use braces (ref)

Equality

  • whenever possible, use strict equality (===) rather than loose equality (==), unless you are dependent on type coercion

Lines

  • as the closure linter insists on 80 character lines, splitting up conditionals and strings must be done with the operand at the end of the previous line (ref)
  • indentations are two spaces

Comments

  • // Comments should start with a capital, include correct punctuation, and have a period.
  • todo format: TODO(username): More text here. Can also use FIXME(username).
  • // XXX(username) for hacks - however very few should exist if possible

Modules

  • modules should be split into separate, smaller modules (such as _stream_x and _http_x) when they are too large to fit into one concisely
  • module import statements should be done permanently, at the top of each module

util

  • we love you util, but in core, your util.isXXX functions are not to be used and should be replaced with their respective inline equivalents

et cetera

  • do not introduce style-only changes in a commit that deals with another feature or fix; each commit should relate to only one change

C++

I don't know C++, anyone want to jump in?

Other notes:

  • I think that the new errors document would be a subset of this, unless we decided to put them into separate markdown files
  • I have no idea where this file would go
@brendanashworth brendanashworth added doc Issues and PRs related to the documentations. discuss Issues opened for discussions and feedbacks. labels Mar 23, 2015
@mscdex
Copy link
Contributor

mscdex commented Mar 23, 2015

XXX(username) denotes a comment by username describing the following code as a "hack"

@chrisdickinson
Copy link
Contributor

I worry a bit about encoding items like the following into the style guide:

  • let should not be used [until v8 speed against var increases]
  • whenever possible, avoid splicing arguments - moreover, avoid arguments if possible
  • do not store the result of typeof variable, instead check directly each time (ref)

V8 will move faster than this document; we risk codifying some amount of superstition into our style guide, which is never good. Knowledge of these optimizations should be treated like a keep-alive'd cache of information, not as permanent truth.

WRT:

This should also reduce the amount of unproductive discussion related to style nits in PRs

We should err towards avoiding style nit comments in PRs unless they are egregious errors – in which case we should probably ask if they've run the linter! If the linter does not pick up the problems we wish it would, we should fix it. Humans will inconsistently apply rules from a style doc, and inconsistency coming from a reviewer is a surefire way to increase friction / frustration for new contributors.

@brendanashworth
Copy link
Contributor Author

@mscdex thanks, I've fixed that.

@chrisdickinson I suppose it would be a better idea to remove all speed / optimization things from it entirely, that makes a lot of sense. I'll do that.

We should err towards avoiding style nit comments in PRs unless they are egregious errors

Style nits are very, very common in PRs -- I'd say I'm a culprit of that, but I'm not the only one. Also, I'd say very many nitpicks aren't caught by the linter, like braces and equality. I'd like to reduce the friction for new contributors with this, but if you think it wouldn't help, then that'd nullify this proposal.

@silverwind
Copy link
Contributor

Not too familiar with ClosureLinter options, but if we need more fine-grained rule control we could use a combination of these for JS:

I think all of the above have plugins for the common editors, so errors would show right up in the editor. The downside is we'd have to add .*rc files to the project root.

@chrisdickinson
Copy link
Contributor

@silverwind I have an branch that implements eslint support. The problem I've run into is that moving to eslint involves balancing a lot of style churn against the usefulness of eslint's warnings. Not saying that this is insurmountable, but it may end up being more work than it seems at first!

@silverwind
Copy link
Contributor

Yeah I use in-editor jshint, and there's a quite a few "warnings" about binary operators and such which need to be disabled for io.js.

edit: I think I'll experiment with eslint a bit, it looks suitable (as it includes style rules).

@chrisdickinson
Copy link
Contributor

@silverwind I'm a pretty big fan of AST-based linting in general, and eslint in particular. Also: here's the WIP branch I have for setting up eslint inside of io.js.

@nstepien
Copy link
Contributor

Have you considered using template strings instead of concatenation?

According to this, they can perform better. I assume this is because v8 doesn't have to guess whether we're doing an addition or a concatenation.

c = a + b; // addition or concatenation?
c = `${a}${b}`; // we're sure to not make any mistake, we know what's going on

// prettier and shorter
fn('name is: "' + name + '"');
fn(`name is: "${name}"`);

// fancier
new RegExp('\\[\\b' + str); // this can get really heavy in complex regexps
new RegExp(String.raw`\[\b${str}`);

// with syntax highlighting, it's easier to distinguish how many strings there are in one line
fn('test', 'hello' + str1 + str2 + 'word', 'string');
fn('test', `hello${str1}${str2}word`, 'string');

fn('test' + str0 + 'hello' + str1, str2 + 'word' + str3 + 'string');
fn(`test${str0}hello${str1}`, `${str2}word${str3}string`);

// can reduce complexity
a = (b + 'string' + c).trim();
a = `${b}string${c}`.trim(); // no need for parens

I believe template strings should become a good practice.

@silverwind
Copy link
Contributor

@chrisdickinson nice work so far on that branch. Can't say I'm really happy with per-file rules and the comments that skip the linter. Do you think they're unavoidable?

@skenqbx
Copy link
Contributor

skenqbx commented Mar 24, 2015

@silverwind We are currently migrating from jshint to eslint and defined rules like no-shadow as warning to allow a smooth transition without deployment errors. Concerning the comments; there are rules e.g. no-process-exit that are set to error but at times a process.exit(1) is necessary.

eslintrc example: https://gist.github.com/skenqbx/7a30d4c07cd6ec449555.

@brendanashworth
Copy link
Contributor Author

All in all, I would prefer a stricter, more stringent linter rather than a page of code guidelines; it'd be easier for both collaborators and maintainers. I don't have much experience with different linters so I can't comment much. Plus -- it'd be AMAZING if we could run a linter automatically for every single PR, the way that Travis-CI integrates with Github.

@MayhemYDG I can add template strings, but they codebase would have to already mimic that, which it doesn't. Also, I don't believe it would be used in the entire codebase; I do remember a PR (I forget, was it about debug()?) where the perf was better with whichever alternative we ended up using. I'd be in favor of template strings though.

@benjamingr
Copy link
Member

const should always be used over var for variables that never change, such as require'd modules

Isn't const absurdly slow right now?

For C++, I think RAII and avoiding pointers should be encouraged whenever applicable as an effort to modernize and idiomatize the code base where applicable.

@silverwind
Copy link
Contributor

Another point to add:

  • Top level functions should be seperated by two empty lines.

@vkurchatkin
Copy link
Contributor

Isn't const absurdly slow right now?

To set or to get? If only former it's fine for bindings, requires etc

@bnoordhuis
Copy link
Member

indentations are two spaces

Unless it's a continuation of a statement on the previous line, then it's four spaces.

modules should be split into separate, smaller modules (such as _stream_x and _http_x) when they are too large to fit into one concisely

Correct, but that's internal/stream/x and internal/http/x now thanks to 2db758c. \o/

module import statements should be done permanently, at the top of each module

...unless there's a very good reason not to.

In general, a style guide should probably make a distinction between rules (for things like formatting) and guidelines (for writing the most idiomatic code.)

I don't know C++, anyone want to jump in?

For now, we mostly follow the Google C++ style guide. Changes should not generate compiler warnings and make cpplint should be happy.

@bnoordhuis
Copy link
Member

I worry a bit about encoding items like the following into the style guide:

  • let should not be used [until v8 speed against var increases]
  • whenever possible, avoid splicing arguments - moreover, avoid arguments if possible
  • do not store the result of typeof variable, instead check directly each time (ref)

V8 will move faster than this document; we risk codifying some amount of superstition into our style guide, which is never good. Knowledge of these optimizations should be treated like a keep-alive'd cache of information, not as permanent truth.

Documents can be updated. If highlighting common performance pitfalls reduces the number of review rounds a pull request has to go through, I'm all for it.

@brendanashworth
Copy link
Contributor Author

Thanks for the help everyone, but now that the new (and strict!) linter is in place I'm not sure if this is that pertinent now, especially as most PRs don't touch C++. I'll close this for now.

@silverwind
Copy link
Contributor

Wouldn't call the current linter settings strict yet. Still need to enable a few more rules on which we hopefully can agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss Issues opened for discussions and feedbacks. doc Issues and PRs related to the documentations.
Projects
None yet
Development

No branches or pull requests

9 participants