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

Space after function keyword - MOVED to #3847! #1139

Closed
sparty02 opened this Issue Apr 6, 2017 · 95 comments

Comments

Projects
None yet
@sparty02
Copy link

sparty02 commented Apr 6, 2017

I apologize in advance if this has been discussed before (I did a quick search and didn't find it). One of the things that popped out when running prettier over our codebase was spacing on anonymous functions.

For example, prettier converts this:

function foo() {
  this.bar = function () {
    console.log('baz');
  }
}

into this:

function foo() {
  this.bar = function() {
    console.log('baz');
  }
}

While this pattern is becoming less common for us (we'd probably use an arrow function here now), we still have several cases of this. The lack of space after the function keyword just doesn't read right for me. It probably has to do with one or more of the following:

  1. It looks more like a function invocation than a declaration.
  2. The lack of space after a keyword is odd.

For prior art:

Are there strong feelings on this one?

@hawkrives

This comment has been minimized.

Copy link
Contributor

hawkrives commented Apr 6, 2017

Personally, I prefer to omit the space when I make an anonymous function?

Now that I'm thinking about it, though, I don't know when I last wrote an anonymous function() (I've moved pretty thoroughly to ES6 and using arrows as my anonymous funcs), so I could likely adapt to having a space there.

@sparty02

This comment has been minimized.

Copy link
Author

sparty02 commented Apr 6, 2017

FWIW, here's a diff of the change in a potential PR (at least me taking a crack at it!).

@pakastin

This comment has been minimized.

Copy link

pakastin commented Apr 11, 2017

I'd also write function foo () {

@trevorgerhardt

This comment has been minimized.

Copy link

trevorgerhardt commented Apr 14, 2017

This also appears to be the only rule that conflicts with standard after the 1.0 release.

@adonis-work

This comment has been minimized.

Copy link

adonis-work commented Apr 16, 2017

It also conflicts with standards jsq-quotes rule, but that might be a bug in forcing double quotes to overwrite single quotes in jsx while singleQuotes:true is in config.

@jlongster

This comment has been minimized.

Copy link
Member

jlongster commented Apr 17, 2017

We're not going to change this. It's a very bike-sheddy debate and doesn't really matter. You might be used to seeing it the other way, but prettier has already made a choice and this and we're not going to change it. If you want to add a space there, you can run your code through prettier and than through an eslint config that adds it with eslint --fix. It's comment for prettier/eslint integrations to do this (see prettier-standard-formatter).

@jlongster jlongster closed this Apr 17, 2017

@bhanuc

This comment has been minimized.

Copy link

bhanuc commented May 19, 2017

Any chance of making this configurable ? This issue possibly breaks space-before-function-paren and generator-star-spacing for my eslint checker.

@lydell

This comment has been minimized.

Copy link
Collaborator

lydell commented May 19, 2017

@bhanuc What not just disable those rules? What do they gain you when using prettier? :)

@rhengles

This comment has been minimized.

Copy link
Contributor

rhengles commented May 19, 2017

@bhanuc I would accept a PR for this in arijs/prettier-miscellaneous

@chanlito

This comment has been minimized.

Copy link

chanlito commented Jun 2, 2017

Many people are using standard with prettier i think this should be an option with prettier.

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jun 8, 2017

The space before a function parentheses is a minor visual cue that the author is declaring a function, and not calling one - aiding readability.

At the very least, as others have suggested, it should be an option.

@jlongster

This comment has been minimized.

Copy link
Member

jlongster commented Jun 8, 2017

We strongly recommend disabling any formatting rules with eslint-config-prettier (just list it after standard and it'll turn them all of). We aren't going to add options for such small changes, as if we did, we'd have to add options for a lot of other things. It's good for the JS community to stabilize on a general style (and as far as I'm concerned the majority of JS does not use a space). It doesn't really help readability in my opinion, you just might need to retrain how you see that pattern.

@srhise

This comment has been minimized.

Copy link

srhise commented Jun 13, 2017

This causes linting issues on any project using vue-cli

@chanlito

This comment has been minimized.

Copy link

chanlito commented Jun 13, 2017

@srhise i think prettier was created with react in mind.

@srhise

This comment has been minimized.

Copy link

srhise commented Jun 16, 2017

Yeah, i'm not a huge fan of the default linting rules used in vue-cli. Very strict.

@matthewmueller

This comment has been minimized.

Copy link

matthewmueller commented Jun 18, 2017

This decision doesn't make a lot of sense to me. If the goal is to be opinionated with no bike-shedding, why are there any options at all? Seems like if there is even 1 option (ex. single vs double quotes) then other options should be up for discussion.

Most people were using standard to fix their code before prettier came along. Though I don't care much which way we head (spaces or no spaces before parens), I'd like to see a consensus reached between the two projects.

I think a nice separation would be to use prettier to format your code and standard to lint your code. Right now they're conflicting with each other and therefore need either double parsing and fixing (e.g. prettier-standard) or custom eslint configuration for each project, both of which aren't ideal.

@chanlito

This comment has been minimized.

Copy link

chanlito commented Jun 18, 2017

Now that u mentioned single vs double quotes option, i think something like space_before_function_paren options: boolean seems a good choice. unless it's hard to implement.

josephfrazier added a commit to josephfrazier/prettier that referenced this issue Jun 20, 2017

Add --space-before-function-paren option
This corresponds to ESLint's `space-before-function-paren` "always"
option: http://eslint.org/docs/rules/space-before-function-paren#always

See prettier#1139

rhengles added a commit to arijs/prettier-miscellaneous that referenced this issue Jun 20, 2017

Add --space-before-function-paren option (#22)
* Add test demonstrating behavior on eslint space-before-function-paren sample code

* Add --space-before-function-paren option

This corresponds to ESLint's `space-before-function-paren` "always"
option: http://eslint.org/docs/rules/space-before-function-paren#always

See prettier#1139

* Document --space-before-function-paren option
@josephfrazier

This comment has been minimized.

Copy link
Collaborator

josephfrazier commented Jun 20, 2017

I just added --space-before-function-paren to prettier-miscellaneous, if anyone wants to use that instead. See arijs#22 for details.

@austinkelleher

This comment has been minimized.

Copy link

austinkelleher commented Jul 18, 2017

tl;dr

Providing an option for a space before function parens can improve project search quality.

Argument

So I read through this thread and I understand both sides of the argument, but I want to throw out an additional note regarding spaces after functions that hasn't been mentioned. For me, the space after a function name is particularly useful for searching projects. In large projects with potentially hundreds of function calls to the same function, searching for a function definition can be challenging. Having a space after a function name can help narrow (and often point exactly to) the function definition:

Helpful scenarios

class Person {
  sayName () {

  }
}
function sayName () {

}
module.exports = function sayName () {

}

Less helpful scenarios

// say-name.js
module.exports = function () {
  // Say the name
}
const sayName = function () {

}
let sayName

sayName = function () {

}

Conclusion

Many functions are defined like the top 3 scenarios. I've found a space before function parens very useful to quickly find function definitions in a project, or at least narrow the search results to something that is more manageable. As shown above, there are several scenarios where this isn't as helpful, but ultimately I think that having an option in prettier would prove to not only be helpful to those who are coming from Standard, but also improving search quality.

@aboyton

This comment has been minimized.

Copy link
Contributor

aboyton commented Jul 18, 2017

And to think I've been searching for n sayName() anytime I want to find a function. Personally I don't really care what one you pick (personally I think sayName() is prettier to read, and finding the definition of a function should be a feature of your editor IMO), but either way, less options the better. The whole point of prettier is that code is consistent and to not have bike shedding.

@joseluisq

This comment has been minimized.

Copy link

joseluisq commented Sep 3, 2017

VS Code Tip:
If someone uses VS Code could try prettier-now-vscode extension for to take advantage of space-before-function-paren via prettier-miscellaneous.

For example: Here my default settings for prettier-now-vscode :

    "prettier.singleQuote": true,
    "prettier.trailingComma": "none",
    "prettier.semi": false,
    "prettier.useTabs": false,
    "prettier.tabWidth": 2,
    "prettier.spaceBeforeFunctionParen": true
@lmk123

This comment has been minimized.

Copy link

lmk123 commented Oct 19, 2017

I'm using VS Code + TypeScript + Vue.js + Prettier Plugin + JavaScript Standard Style in my project, and I experience this issue.

Prettier format my code without space before function parenthesis, I know there is prettier-eslint can auto fix it, but it doesn't support tslint. And, typescript-eslint-parser is not stable yet.

So I run tslint --fix from CLI every time before I push my files, but tslint doesn't support *.vue so it can't fix code in *.vue file.

After that I installed Vetur, an VS Code plugin from Vue.js team, it use Prettier to format script in *.vue, but because of Prettier doesn't support space before function parenthesis, it also delete the space before function parenthesis.

Finally, I disabled space-before-function-paren rule.

Maybe I'm selfish —— I apologize in advance if I'm wrong —— if Prettier support this rule, I think it's easy to avoid upon problems for people who use TypeScript, Vue.js and JavaScript Standard Style just like me.

@lydell

This comment has been minimized.

Copy link
Collaborator

lydell commented Oct 19, 2017

Current instruction:

Disable the space-before-function-paren ESLint rule.

If Prettier adds support for printing that space:

Use the --space-before-function-paren Prettier option.

That’s no easier, is it?

@austinkelleher

This comment has been minimized.

Copy link

austinkelleher commented Jan 30, 2018

@lydell I completely agree. There is clearly a huge demand for this to be supported as an option. I recognize that there are inherent issues with supporting options and that Prettier intends to be opinionated.

With that being said, I too believe that this should have been the default behavior. As you've stated, it has an actual practical use case (as well has interoperability with one of the most popular JavaScript style guides, Standard). I firmly believe that this should be supported as an option and should be considered in Prettier 2.0 (#3503). It's very disappointing that it has been constantly considered as impractical.

@srhise

This comment has been minimized.

Copy link

srhise commented Jan 30, 2018

@lydell It can. It doesn't work out of the box though, which can be a bad experience for developers who are having their first go with vue from something like react where they are using prettier just fine.

@Aanhane

This comment has been minimized.

Copy link

Aanhane commented Jan 30, 2018

They give you the following options:

Pick an ESLint preset (Use arrow keys)

> Standard (https://github.com/standard/standard)
  Airbnb (https://github.com/airbnb/javascript)
  none (configure it yourself)

And since standard conflicts with prettier, lot's of people run into problems. I think people want the same thing: just set up linting without having to bother with it's configuration.

@lydell

This comment has been minimized.

Copy link
Collaborator

lydell commented Jan 30, 2018

Interesting question: Where does the space go when using TypeScript or Flow generics?

function identity<T>(value: T): T {
  return value;
}
@j-f1

This comment has been minimized.

Copy link
Member

j-f1 commented Jan 30, 2018

I’d say before:

function identity <T>(value: T): T {
  return value;
}
type Identity = <T>(value: T) => T

// but:
type Identity<T> = (value: T) => T

\o/ TS highlighting is back

because the <T> is one of the parameters to identity, but I don’t really like how it looks.

@suchipi

This comment has been minimized.

Copy link
Member

suchipi commented Jan 30, 2018

Would anyone be offended if I made a PR adding an option for this so that I stop getting notifications about it? (tongue in cheek)

@j-f1

This comment has been minimized.

Copy link
Member

j-f1 commented Jan 30, 2018

Seems like a good case for an option. At least until 2.0. :shipit:

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 30, 2018

Haven't considered Typescript generics. Looking at the Typescript docs, and also the C# code I have, there is no space at all (but also no space for method declaration, which does annoy me).

For visual comparison:

Space Before

function identity <T>(value: T): T {
  return value;
}
type Identity = <T>(value: T) => T

// but:
type Identity<T> = (value: T) => T

Space After

function identity<T> (value: T): T {
  return value;
}
type Identity<T> = (value: T) => T

// but:
type Identity = <T>(value: T) => T

(╯°□°)╯︵ ┻━┻

I haven't got a reasoned position on this one 😞

@lydell

This comment has been minimized.

Copy link
Collaborator

lydell commented Jan 30, 2018

Hmm, it has to be before, right?

function identity <T>(value: T): T {
  return value;
}

Because then you can still search for [function name][space].

@atomiks

This comment has been minimized.

Copy link

atomiks commented Jan 30, 2018

Spaces should go between the function keyword and parens because of names

https://github.com/airbnb/javascript/#functions--signature-spacing

const fn = function () {}

But not for method shorthand etc

const o = {
  fn() {}
}
@azz

This comment has been minimized.

Copy link
Member

azz commented Jan 31, 2018

We need to be careful interpreting the 👍s on the OP. I suspect most are asking for space before anonymous function paren, as that is what OP describes. I don't think adding a space before all function parens will be a popular change.

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

@azz

as that is what OP describes

Read it again, it isn't.

The request is for a space before function declaration parens.

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

@atomiks

But not for method shorthand etc

Why not? The whole argument is to determine the difference between declaration and invocation.

So, method shorthand should absolutely include a space. It must be consistent, otherwise it's not worth doing at all.

@azz

This comment has been minimized.

Copy link
Member

azz commented Jan 31, 2018

@justrhysism Yes it does.

was spacing on anonymous functions.

function foo() {
            ^ no space here
 this.bar = function () {
                    ^ space here
   console.log('baz');
 }
}

When I say all, I mean:

function foo () {
            ^ space here
}
@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

@azz

That was the example of existing functionality. An example of requested functionality wasn't provided, but was described.

@azz

This comment has been minimized.

Copy link
Member

azz commented Jan 31, 2018

It is the input, and the expected output. The rest of the post describes anonymous functions and issues such as no spaces after keywords.

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

@azz

It is the input, and the expected output.

No, it's an example of the existing behaviour.

For example, prettier converts this:

function foo() {
 this.bar = function () {
   console.log('baz');
 }
}

into this:

function foo() {
 this.bar = function() {
   console.log('baz');
 }
}

The words "For example, prettier converts this ... into this: ..." indicate that the OP is describing the current behaviour. I'm really not sure how to make this any clearer.

@azz

This comment has been minimized.

Copy link
Member

azz commented Jan 31, 2018

It is stated several times in OP that the issue is raised for anonymous functions only.

  1. One of the things that popped out when running prettier over our codebase was spacing on anonymous functions.

  2. For example, prettier converts this:
    code with spaces before function parens only with anonymous function

  3. While this pattern is becoming less common for us (we'd probably use an arrow function here now), we still have several cases of this. The lack of space after the function keyword just doesn't read right for me.

  4. The lack of space after a keyword is odd.

  5. https://github.com/airbnb/javascript#functions--signature-spacing

    // good
    const x = function () {};
                      ^ space here
    const y = function a() {};
                        ^ no space here
  6. http://eslint.org/docs/rules/space-after-keywords

@sparty02

This comment has been minimized.

Copy link
Author

sparty02 commented Jan 31, 2018

OP here.... 😄 @azz is totally right on my intention. I even reference a potential PR diff in where the current code only adds a space after the function keyword in the event that an id exists on that particular AST node. This seems goofy and reflects what I think is the biggest sticking point with this whole style; which is that there should always be a space after a keyword. In this case, it's the function keyword, but I think this rule can be applied to every keyword consistently as a general rule of thumb......hence the "prior art" I linked to, including the eslint rule and airbnb style guide which state it pretty clearly.

By the way, for what it's worth, I also personally prefer no space after a function name. e.g. the style reflected in point 5 in @azz's previous comment.

Lastly, I personally do not necessarily think this should be a configurable option. I originally opened this just before the 1.0 release, hoping that given enough feedback, it would become the default style (space after the function keyword). It would have been interesting to know how much code in the wild uses/used function() vs function (), but those results will at least partially be tainted now by, ironically, usage of prettier.

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

there should always be a space after a keyword

@sparty02 fair enough.

Since you've been fairly absent from the thread, it appears to have run away without your input and the waters muddied. I suspect the vague issue title may have contributed to the confusion. Do you feel that a separate issue should be opened for a space after a function name declaration?

@sparty02

This comment has been minimized.

Copy link
Author

sparty02 commented Jan 31, 2018

@justrhysism Yeah, given my clarification, if there are strong feelings about the space after the function name declaration, I think a separate issue would be appropriate to address that.

To be clear, I'm going to change the title of this from space before function paren to space after function keyword

@sparty02 sparty02 changed the title space before function paren space after function keyword Jan 31, 2018

@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

Okay, so I've created a separate issue (#3845) for the discussion on space after function name declaration.

I believe both space after function (or indeed, any) keyword and space after function name declaration should be the default - or, at the very least, configurable.

@atomiks

This comment has been minimized.

Copy link

atomiks commented Jan 31, 2018

@justrhysism

Why not? The whole argument is to determine the difference between declaration and invocation.

So, method shorthand should absolutely include a space. It must be consistent, otherwise it's not worth doing at all.

It's not the same thing.

const fn = function() {}
const fn = functionname() {} // error, no space between keywords is a bad idea
const fn = function () {}
const fn = function name() {} // all good
const o = {
  fn() {} // this is logically equivalent to `function name() {}` (no space between name and parens)
}
@justrhysism

This comment has been minimized.

Copy link

justrhysism commented Jan 31, 2018

@atomiks that's not at all what I was saying.

Anyhow, the original title of this issue was space before function parens (since changed for clarification), which I believe is the source of much of the confusion. I'm not going to comment on this issue any further as that discussion should now take place over on #3845.

@lydell lydell changed the title space after function keyword Space after function keyword - MOVED to #3847! Jan 31, 2018

@lydell

This comment has been minimized.

Copy link
Collaborator

lydell commented Jan 31, 2018

PSA: I'm moving this issue into #3847 to reset the 👍s.

#3847 is about space in anonymous functions: f = function () {}.

#3845 is about space after the name: function f () {}.

To anyone who have voted for this issue: Please vote on the other two issues! Thanks!

@prettier prettier locked and limited conversation to collaborators Jan 31, 2018

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