I like to solve interesting problems, and concentrate on crafting high quality software. Manual code formatting contributes to neither of these disciplines. Code formatting is BORING robot work, not human work. Total pointless drudgery. Toiling away because you like your bracket with a different spacing is IDIOTIC. Run the formatter and move on.
Not arguing about style is nice, but having to resort to this brutalist architecture style of code formatting doesn't seem great to me. "Its just holding people, who CARES what the building looks like!"
"Pretty", yes, but we're literally talking about using language to communicate. Consistency taken to extremes is harmful to communication.
I don't understand the worship that people have for consistency. STUPID inconsistencies are bad, yes, and yes, there are certainly arguments that about subjective matters that are a waste of time. But distilling everything down to the lowest common denominator of grunt-talking is very consistent and terrible communication. (Does that feel like a strawman? I'd love for it to be! Once people stop talking about consistency uber-alles we'll be discussing the things that I consider important.) Right now, the most common reaction is to dismiss any idea of communication through language as irrelevant, subjective, and a waste of time."
Unless you are enforcing weird autoformat choices, everything should look pretty enough.
Working in a team with 15 people on the same code base I disagree with this. Count the computer as one teammate
Fwiw, i use an auto formatter but its got problems with certain rules so i switch them off.
The reason we dont have it turned on in ci is because these rules break code.
This is the same for programming. Each dev have their own taste in term of code style and code formatting preferences. I was an early employee in a startup, and at some point I was able to tell who wrote a chunk of code just from the code style, it was fun :) but as company grown, and team got bigger, it got more "professional", now we have prettier which erases a big part of our code personality. If you believe like me that coders are artists you might find that a bit sad, but the truth is that most Enterprise software building is wall painting, and art doesn't have its place there. That doesn't prevent us from painting Mona Lisa at home though :)
One simple example is when you're parsing text and you have a long list of simple one-line if statements. I personally think it's wasteful and harder to read that block of code if you impose curly braces and new lines on that list of conditionals. This kind of formatting convention has been around for at least 40 years, and it makes the code more readable. I have yet to see an auto-formatter that doesn't turn that kind of code section into an unreadable mess.
There's also plenty of room for art in the choice of materials and colours as well as the shapes of buildings. Likewise, with code, if you limit yourself to only what one person can do, you'll end up with a very constrained view of what "art" means.
There's a beauty that comes from simplicity, and code for matters, at least for me, are good of reminding me of that.
I also think formatting should be separate from linting but because they both require a parser people seem to think theyre the same thing.
If youre adding more attributes to a jsx component later and know it you might format to multiline early. It decides to undo your work and slow you down, because some arbitrary line length.
Similarly, if you go over that line length, on something you want single line for readability of structure, it just straight up does what it wants.
Im 100% on the auto format train but it has to go the gofmt route and only apply rules that are actually important and incredibly uncontroversial.
What you're missing here is that you're supposed to be using it all along, all the time. Format on save. Format on commit. Format on server pipelines. Format all the time. It can never 'undo' anything if it's what's providing the formatting in the first place.
https://prettier.io/docs/en/rationale.html#multi-line-object...
My two cents: Write the comment's purpose inside it. "// Comment inserted to force prettier line break until more attributes are added"
If the rule never works for you, turn that one off.
If the rule is what you want 99% of the time but it made this one line look dumb, mark that one block #ignore and let the team decide in CR if that was the right call.
Anyway, my point still stands, drop rules about line length and rules that care about inter line break positions and most of these problems go away.
If your contributor is changing thousands of lines in a diff to fix a typo, ask them not to do that :)
Now the code is formatted and additions won’t trigger reformatting the line or the file.
Of course, a lot of tooling simply isn't there for that, unfortunately, but that's what I see as the ideal solution.
I also believe that formatters should be "light-touch" and not have an opinion about every last thing. At that point I start thinking, "if you so smart, why don't you write the bloody code!"
There was a good quote from Rob Pike in his Go proverbs talk: "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite."
rubocop -a
For the win.Some of its defaults? Fine, whatever. Others? They’re just _wrong_.
BUT
I'm tired of seeing diff chunks on github where 95% of the chunk is because black/gofmt decided to change the formatting / indentation / grouping / whatever. I want language-agnostic, AST-aware diffing, that de-emphasizes the part of a chunk that is irrelevant-in-the-world-of-auto-matic-code-formatting.
The challenge is that version control on text files (list of lines) is fairly straight forward and language agnostic, while OTOH the VCS would have to run after the language parser processes on the text file, and then be able to interface with the AST generated by the parser (for multiple languages). I presume this would become easy if different languages have the same parsing setup, or we have language/project-specific VCS tools. While the answers are not obvious (to me, at least) this definitely seems like the right direction to move in, instead of getting hung up on plain text and formatting issues.
But yeah, otherwise everyone could just have their own preferred formatter/settings and we could commit whatever representation is most optimal for diffing to version control (e.x. multi-line object literals, trailing commas in arrays/args, etc).
You could use something more compact like a binary AST but for compatibility with "legacy" tools that deal with text I think it would be better to use a more verbose text-based representation.
Python 2.7.15 (default, Feb 14 2019, 16:26:56)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> ast.dump(ast.parse('print "foo"'))
"Module(body=[Print(dest=None, values=[Str(s='foo')], nl=True)])"
but in python 3.7: Python 3.7.2 (default, Feb 14 2019, 16:12:42)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> ast.parse('print "foo"')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/philsnow/.pyenv/versions/3.7.2/lib/python3.7/ast.py", line 35, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File "<unknown>", line 1
print "foo"
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("foo")?
nothing changed in the text, but the AST is different. What should get committed to this hypothetical "git-ast"?The answer probably lies in creating a different abstraction , different building blocks. In git we have bytes -> blobs -> trees -> commits, where the bytes of a given file get annotated with a file name (and mode bits etc etc, gross posix things) by the tree object.
In git-ast, maybe the abstraction is bytes -> lexemes (which annotates the bytes with a language version, and thus lexer version) -> tree? I haven't gone down the thought experiment that far.
I tried to make an example with `with`, because that was introduced between 2.4 and 2.5 IIRC, and 2.4 and 2.5 aren't nearly as far apart as 2.* and 3.*, but I didn't find an easy way to install a 2.4 python (it didn't compile in pyenv on my mac, and I looked at a couple docker images before giving up).
The worst case is that you export it with the old version of the converter, and then the code changes meaning. You have silent corruption. But if you stored raw text this would always happen.
The good case is that you export it with the new version of the converter. It will notice that a variable name matches a keyword, and alert you to fix it.
Of course that doesn't help if you're setting up the formatter for the first time, or want to upgrade to a new version.
Some tools like GitHub's diff do try to deemphasize whitespace but it's pretty limited.
1. Use a tracked directory for Git hooks: `git config --local core.hooksPath 'git-hooks'`.
2. Create format.bash and lint.bash.
2.1. Run `black` and `isort` in format.bash.
2.2. Run `flake8`, `mypy`, `black` and `isort` in lint.bash.
2.3. Run lint.bash in the pre-commit hook.
2.4. By default, lint/format only files which are different from origin/master to save time: `git diff --diff-filter=d --name-only -z origin/master "[asterisk].py"`.
3. In CI, run lint.bash with `--all` or some other keyword to verify formatting on every file: `git ls-files -z -- "[asterisk].py"`.
After more than a year with this setup I absolutely adore it.
I've found git hooks to be more trouble than they're worth.
But as long as it's enforced in CI you can leave it up to individual team members how they want to do it.
You can do a format run over the whole codebase then ignore the commit in blame.
https://www.moxio.com/blog/43/ignoring-bulk-change-commits-w...
This could be the case if you have extreme confidence in the formatter, but I have def seen some very funky black outputs. It seems like when writing people will likely do so with a model of how black will yield the final code in mind. (Eg "if I add more characters to this one line list statement, it will get exploded across 5 lines", and affect readability, etc..)
You don't have to deal with anything as long as you're using the same formatter everyone else is using.
[blame]
ignoreRevsFile = ".git-ignore-revs-file"
markIgnoredLines
markUnblamableLinesThe simplest and safest would be to apply the formatter to both the old and the new copy before diffing it. It ceases to be the actual difference at that point, but there are definitely two distinct use cases for diffs - one for humans to read and one for the machine to apply.
The other case that would be amazing but even more of a stretch would be to rewrite the entire history. It seems like there is a spot for "different views of history" and you could do a no-difference merge to join the to histories as of now so that the actual history did not get lost. As I write this, it starts to sound like just a caching system for the idea above.
This needs a highly reliable formatter of course... I have on occasion had code broken when formatting.
Looking at this another way, formatters are designed to "frustrate" devs into working only 1 way. If you think it's more helpful to have a codebase with mixed spaces/tabs with commits that express each developer's unique flair, then a formatter is not for your team.
What are some other great formatters out there?
[0]: https://prettier.io [1]: https://github.com/apple/swift-format [2]: https://github.com/rust-lang/rustfmt
edit: seems https://github.com/dotnet/format is the closest thing
Resharper has a free command line tool that supports wrapping long lines. https://www.jetbrains.com/help/resharper/CleanupCode.html
I made a wrapper for it to try and make it easier to use. https://github.com/sethreno/ReGitLint#regitlint
For public code I do not recommend changing the defaults since it may make PRs a mess.
Apostrophes occur so often in English that it makes it easier to type strings like "I'm a dog". With single quoting you have to go 'I\'m a dog'.
If I hit double quotes in a string, I just triple-quote.
"""He said "hah" sarcastically""".
I know Guido (van Rossum) prefers single quotes -- I'm not sure why exactly -- so it's become a default Python style. I tried to adopting it but always ended up reverting to double quotes.
Might be ease of typing? Eg: `foo = 'bar'` doesn't require any shift chords, whereas `foo = "bar"` requires two. Though then I'd expect similar preference for kebab-case in identifies, for similar reason.
'The class of \'72 didn\'t think much of Sam\'s speech'
vs
"The class of '72 didn't think much of Sam's speech"
To me, the shift chord is an almost negligible price to pay for more aesthetically pleasing strings, especially since on a QWERTY keyboard, the shift key is literally right next to the ' key. For emacs users who are used to complex key chords, it's even more negligible.
I do use single quotes for strings frequently in interpolated f-strings though:
f"The date is {result['year']}"
rubyfmt for Ruby
I don't care about the specific formatting/linting rules as much as I care about consistency. Auto formatting is great to reduce friction for those on the team who can't/won't convert change how they write code locally.
We spent a lot of time on making the code look like it at least came from the same company. And weeks of my life has been wasted trying to get people to agree on code formatting and coding style.
Fast forward a few years and we start using Go. I didn't agree with some of the formatting choices or code conventions. And pretty much everyone on the team had at least one thing that would grind their gears.
But we agreed that we'd use the gofmt tool to format the code. As everyone now does: by ensuring whatever IDE or editor we use pipes the code through that.
It took less than a week for everyone to adapt and I have hardly heard anyone complain since. There are still things I think could have been different, but for me, that's a very low price to pay for not needing to have these discussions.
The serialisation should be normalised automatically, preferably in a way that minimises line-based diffs.
The way code is formatted for display should be distinct, and can usually be more of a personal preference. Most people seem to be happy for their editor to use syntax highlighting to make things more readable, but not much else. Indentation, line length, aligning sub-expressions, etc. can also help readability, but showing those things differently from the bytes on disk is usually avoided.
Perhaps this is due to a conflation of meaning for certain bytes. For example, \n can mean "token separator" to the language, "long line splitter" or "intent separator" to the developer, "unit of comparison separator" to version control, etc.
If you find formatting discussions with your teammates painful, Maybe some fraction of your team are stubborn jerks?
I've worked where formatting discussions were always friendly and constructive. It can be done.
It also really democratizes the language, because even folks brand new to Python or who are inexperienced with programming in general end up with code that is well-formatted and consistent with everything else.
Things like changing names to affect line breaks, inlining or outlining expressions etc.
Small things can turn 1 line into 8, and vice versa.
Now, to be clear, I’m sure it’s possible to find some examples where most programmers would come together and agree that black made the wrong decision. But my experience using it across entire teams is that this is surprisingly rare.
I aim higher than that.
I think there are few subjective style choices that are so egregious that a robot would have done a better job. Where I want enforcement is likely correctness and safety mistakes.
In general, I tend not to care a whole lot about style, except to try and match whatever is pre-existing, as long as it’s vaguely readable. Otherwise, it’s basically whatever python-mode on emacs does, subject to a reasonable line length. Formatting nitpicks in code review bug me enough that I always just give in and do what they suggest.
Enforcing a code style where adding a single byte can result in an unlimited-number-of-lines block in a diff is pure idiocy.
It's bad enough having to review someone's changes when they're polluted with this garbage, but it also makes merges fail more often and pollutes `git blame`.
The idea that people will put up with this crap because they can't just unclench about a few spaces here and there I will never understand.
"But it minimizes diffs because it stops people committing simple spacing changes" - people shouldn't be adding those hunks to their commits in the first place and such changes need to be pulled out in review. This will also get people out of the habit of just blindly doing a `git add`.
edit: I'm certain that if slightly non-uniform formatting really sets off your OCD then this should be solvable to some degree at the editor level, but please keep your obsessions out of my repository. In return I'll keep mine out of yours.
This seems like a cool tool, but I don't know if I would use it at this point. I would _pay_ for having autoformatters from Github -- it was a pain to set it up and would love to just enable on new projects.
So not like prettier/black/goftm.
You get to choose. It's more of a way to group things.
Which make sense. I don't mind being dictated code formatting, but linters will complain about branching, number of arguments, comments and so on. I change the settings of my linter for each project.
Those should not be fixed.
I personally find ESLint to be a nightmare of configurability and silly defaults.
But totally agree on forced lining.
Stopping things like reassign function parameters, no unused variables and the like really makes code far nicer.
I also love auto formatting in vscode saves a lot of time.
After using Prettier for a few years I'm firmly in the camp of mandatory/enforced code formatters. As long as it's a half decent formatter like Prettier I believe my personal opinions on the specific formatting choices are much less important than essentially never having to think about formatting again, in particular having to ask people to fix formatting in code reviews (or fix it myself).
I also love just banging out code, saving, and having my editor clean up the formatting for me.