Custom indent options for dartfmt

3,788 views
Skip to first unread message

Danny Tuppeny

unread,
Aug 26, 2016, 8:43:56 AM8/26/16
to Dart Misc
I've been really trying, but the whole two space thing really bugs me ;(

I don't expect it will happen, but it seems (to me) a reasonable request, so I thought I'd ask!


We can configure line length already, so it's not like we're guaranteed consistency. This just allows users to have some more control over how their code looks without totally having to give up dartfmt!

Danny Tuppeny

unread,
Aug 26, 2016, 8:59:08 AM8/26/16
to Dart Misc
I guess these things are not equal... From the style guide:

AVOID lines longer than 80 characters.

DON’T use tabs.

I hope whoever made this decision feels really bad about it now! ;(

Bob Nystrom

unread,
Aug 26, 2016, 11:39:28 AM8/26/16
to General Dart Discussion
I really need a FAQ entry for this since it comes up often.

Configuring indentation is an entirely reasonable request for some kinds of formatters, but not for dartfmt. The priorities for dartfmt are in descending order:

  1. Produce consistently formatted code. Consistent style improves readability because you aren't distracted by differences in style between different parts of a program. It makes it easier to contribute to others' code because their style will already be familiar to you.

  2. End debates about style issues in code reviews. This consumes an astonishingly large quantity of very valuable engineering energy. Style debates are time-consuming, upset people, and rarely change anyone's mind. They make code reviews take longer and be more acrimonious.

  3. Free users from having to think about and apply formatting. When writing code, you don't have to try to figure out the best way to split a line and then painstakingly add in the line breaks. When you do a global refactor that changes the length of some identifier, you don't have to go back and rewrap all of the lines. When you're in the zone, you can just pump out code and let the formatter tidy it up for you as you go.

  4. Produce beautiful, readable output that helps users understand the code. We could solve all of the above goals with a formatter that just removed all whitespace, but that wouldn't be very human-friendly. So, finally, the formatter tries very hard to produce output that is not just consistent but readable to a human. It tries to use indentation and line breaks to highlight the structure and organization of the code.


Configurability goes directly against the first two priorities, and halfway against the third (you have to think about it, but not apply it).

This may be surprising, but the goal of dartfmt is not to automatically make your code look the way you like. It's to make everyone's Dart code look the same. The primary goal of dartfmt is to improve the quality of the Dart ecosystem. That transitively improves the live's of each Dart developer as well—you get more code to reuse, more consistent code, it's easier to read and contribute to each other's code, etc. But it does that at the expense of individual preference.

It requires you to buy in to the idea that a consistent ecosystem is more valuable than anyone's individual formatting preferences. Or, another way to say that is that no one's individual formatting style is measurably better enough than what dartfmt produces to compensate for the costs of inconsistency.

If you don't buy that, that's OK. It just means dartfmt probably isn't the right tool for you.

Cheers!

– bob



--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Samuel Rawlins

unread,
Aug 26, 2016, 11:48:52 AM8/26/16
to mi...@dartlang.org
I agree with everything you've said, Bob. But in terms of line length vs tab-and-indent length, is there a reason why you can configure one and not the other?

I would guess that it was just so dead simple to make 80 vs another integer configurable, that it was an easy concession. But tab-vs-indent requires a little more opinions and decisions (default is 2 in some cases, 4 in others, so if you "configure" to use a 4-space indent, then is it 4 and 8? if you use tabs, is it 1 tab and 2?)

In other words: line length is stupid simple, but indent options is an entire other ball of wax.

Danny Tuppeny

unread,
Aug 26, 2016, 11:51:54 AM8/26/16
to General Dart Discussion
I understand that, but it seems slightly inconsistent because:
  1. Line length is configurable
  2. Spaces have no advantages (alignment doesn't work with dartfmt) over tabs, tabs have advantages over spaces
(I guess (2) is an argument for using tabs instead of spaces, not an option).

I know it's not going to change, it's just a little frustrating that there doesn't seem to be any (good) logic behind the decision ;-(

tatumizer-v0.2

unread,
Aug 26, 2016, 12:32:24 PM8/26/16
to Dart Misc
FWIW, my experimental observation is: when line size is 80, indent=2 is the only valid choice (you have limited horizontal space, have to be frugal).
When line size is 120, indent=4 is the only valid choice (with indent=2, text is not readable)
Bottom line: these parameters are not as independent as Bob thinks. (IMO). We could easily have 2 settings: 80/indent=2 and 120/indent=4

As for tabs: they make it impossible to read the code outside of your own IDE Standard editors may show 8, 4, or 2 spaces depending on configuration. For many, 8 is the default. I have this problem very often while working with somebody else's code (to make things worse, the code may include combination of spaces and tabs, so you have a complete mess on your screen)




Filip Hracek

unread,
Aug 26, 2016, 12:36:34 PM8/26/16
to mi...@dartlang.org
As Bob says on the github issue, even the line length setting is there mainly for historical/testing reasons.

Non-configurability is a design decision of dartfmt and without it, the whole idea of this tool starts breaking apart.

FWIW, I love the fact that every code I look at (at least at Google) is more or less equivalent in terms of whitespace formatting. Yes, it hurts at first, especially if you have another preference. But in the end, it makes everyone's life less miserable. I think Bob's FAQ explains it nicely.

Bob Nystrom

unread,
Aug 26, 2016, 12:47:47 PM8/26/16
to General Dart Discussion
On Fri, Aug 26, 2016 at 8:48 AM, 'Samuel Rawlins' via Dart Misc <mi...@dartlang.org> wrote:
I agree with everything you've said, Bob. But in terms of line length vs tab-and-indent length, is there a reason why you can configure one and not the other?

dartfmt supported configurable line length from before the point in time that I started working on it. So removing that would have been a breaking change.

The tests for dartfmt also use it internally. It's a lot simpler to write tests of the various line-breaking choices if you only need to write 40 columns of code. :)
 

I would guess that it was just so dead simple to make 80 vs another integer configurable, that it was an easy concession.

It's actually a decent amount of effort to plumb it through the various layers of code, but it's still effectively a single constant value, so it doesn't affect the algorithms.
 
But tab-vs-indent requires a little more opinions and decisions (default is 2 in some cases, 4 in others, so if you "configure" to use a 4-space indent, then is it 4 and 8? if you use tabs, is it 1 tab and 2?)

Tab versus spaces is a nightmare. The original dartfmt did have some logic to try to handle those, but I tore all that out, which simplified a lot of things.

The formatter needs to deal with multiple kinds of leading indentation:
  • Block-level indentation (usually +2).
  • Wrapped continued expression indentation (usually +4).
  • Cascades, collections, etc. which are expressions but indent like they're blocks.
All of these can nest and compose arbitrarily. You can have a wrapped expression containing a lambda, which contains blocks, which indent, which contain a wrapped expression, etc. That in turn means you could conceivably have the beginning of your line contain a mixture of tabs and spaces if you use tabs for some indentation but not others.

dartfmt needs to know exactly how long a line is in actual columns so that it knows where to line-wrap, so even if it supported tabs, it would have to treat them as having a very explicit width in characters, so you get no flexibility from using tabs.

Cheers!

– bob

Samuel Rawlins

unread,
Aug 26, 2016, 12:57:01 PM8/26/16
to General Dart Discussion

Ah, good points, Bob. It does seem a nightmare to support tabs and consistency at the same time.

Thanks for the response!


Danny Tuppeny

unread,
Aug 26, 2016, 1:41:33 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 17:32 tatumizer-v0.2 <tatu...@gmail.com> wrote:
As for tabs: they make it impossible to read the code outside of your own IDE Standard editors may show 8, 4, or 2 spaces depending on configuration. For many, 8 is the default. I have this problem very often while working with somebody else's code (to make things worse, the code may include combination of spaces and tabs, so you have a complete mess on your screen)

This makes no sense to me. If you're reading in a tool that renders tabs as 8 characters and you want 2, that's a limitation of that tool (and far from makes it "impossible to read").

Danny Tuppeny

unread,
Aug 26, 2016, 1:45:36 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 17:48 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:
dartfmt needs to know exactly how long a line is in actual columns so that it knows where to line-wrap, so even if it supported tabs, it would have to treat them as having a very explicit width in characters, so you get no flexibility from using tabs.

That's not entirely true - if dartfmt wrapped with the assumption that a tab is 2 chars, you still have the flexibility to render them as 4 in your editor if you wish.

I genuinely can't see any negative from using tabs (except for tools that render tabs at a size you would not like; but how is that worse than my editor, the thing where I actually write the code, not rendering at a size I would like?) 

Again, I don't expect this to change (and don't want to dig up tabs vs spaces) but other than "it's too late to change", I just can't see how spaces is a better choice than tabs. Editors are where we write our code, and having our preference these seems far more useful than having them in an external tool (and tbh, if you're writing a tool for programmers and didn't make tab size customisable, maybe it's not a very good dev tool!).

Filip Hracek

unread,
Aug 26, 2016, 1:47:16 PM8/26/16
to mi...@dartlang.org
Of course you can change it in your IDE. But do you really want to manually switch this option every time you look at someone else's code? Or do you suggest the source file should have some machine-readable comment that would give it a hint what the tab size is (like "/* tabs=4 */)?

--

Joao Pedrosa

unread,
Aug 26, 2016, 1:56:52 PM8/26/16
to mi...@dartlang.org
Hi,

To this day, languages and projects that prefer tabs over spaces have problem when folks see their code rendered on GitHub or some other source code host that is not their preferred editor.

It is relatively easy to see how in projects that indent with both tabs + spaces, that the lines don't indent neatly all the time when the tab preferences are changed. If more than 1 person edits the code with different specifications, the code could have multiple formats.

Anyway as it's always apparent when discussing programming, some people are OK if the preference works for an individual, whereas others are ready to cast the problem as one that can affect a whole company or community. Dart is supposed to be a language for larger teams. Even if we know that many projects have just a couple of developers driving them.

Cheers,
Joao



--

Danny Tuppeny

unread,
Aug 26, 2016, 1:57:00 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 18:54 'Filip Hracek' via Dart Misc <mi...@dartlang.org> wrote:
Of course you can change it in your IDE. But do you really want to manually switch this option every time you look at someone else's code? Or do you suggest the source file should have some machine-readable comment that would give it a hint what the tab size is (like "/* tabs=4 */)?

I don't understand what you mean. No, you'd never changed it, nor would you need a hint. You set your editor to how *you* want it - eg. Google would set it to 2, and I would set it to 4. All code I open would be indenting by 4 characters for me, and all code Google open would be 2. Everyone is happy; nobody needs to mess with anything.

Bob Nystrom

unread,
Aug 26, 2016, 2:00:35 PM8/26/16
to General Dart Discussion
On Fri, Aug 26, 2016 at 10:45 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
That's not entirely true - if dartfmt wrapped with the assumption that a tab is 2 chars, you still have the flexibility to render them as 4 in your editor if you wish.

Sure, but then you'll be annoyed when dartfmt wraps your lines "prematurely" because you see them as farther to the right than it does. In fact, setting a tab stop higher than two means you can no longer rely on all the code in your window fitting in 80 columns.

I genuinely can't see any negative from using tabs (except for tools that render tabs at a size you would not like; but how is that worse than my editor, the thing where I actually write the code, not rendering at a size I would like?) 

The reason we use monospace fonts for code is because it makes it easier to line things up horizontally and ensure code fits within various horizontal dimensions.

Tab is like a super-non-monospace character that is not only not as wide as every other character, but its width isn't even stable across users and tools. That's not a good recipe for consistent typography.

Again, I don't expect this to change (and don't want to dig up tabs vs spaces) but other than "it's too late to change", I just can't see how spaces is a better choice than tabs.

Tabs add a lot of complexity. Every tool, web site, code review system, editor, etc. needs to handle them, have a UI to let users configure their width, persist that setting somewhere, etc.

In return for that, you get per-user variance on indentation. That assumes that user's ability to read code with certain indentation varies so much that it justifies that complexity. It's not just that "X spaces is so much better than Y" it's that "X is so much better than Y for user A while Y is so much better than X for user B". That's what you need to show to demonstrate that it's worth per-user configuration.

I haven't seen any compelling data to show that's the case. As far as I can tell, user variance around indentation and readability is quite low. If a certain indentation level is good for A, it's probably just about is good for B. It's important to pick a good indentation level, and that probably varies based on language, style of code, etc. But I haven't seen any data showing user-specific variance.

– bob

Danny Tuppeny

unread,
Aug 26, 2016, 2:02:31 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 18:56 Joao Pedrosa <joaop...@gmail.com> wrote:
To this day, languages and projects that prefer tabs over spaces have problem when folks see their code rendered on GitHub or some other source code host that is not their preferred editor.

This "problem" is news to me. Almost every project I've contributed to (possibly all) and all of my own (except Dart, ofc) indent with tabs.


It is relatively easy to see how in projects that indent with both tabs + spaces, that the lines don't indent neatly all the time when the tab preferences are changed. If more than 1 person edits the code with different specifications, the code could have multiple formats.

This is an argument for tabs; people won't need to mix and match if they can have their own preferences.
 

Anyway as it's always apparent when discussing programming, some people are OK if the preference works for an individual, whereas others are ready to cast the problem as one that can affect a whole company or community. Dart is supposed to be a language for larger teams. Even if we know that many projects have just a couple of developers driving them.

I'm still failing to see why spaces are better than tabs. Tabs let people have their own preference without it being coded into the source and spaces do not? :-/

Danny Tuppeny

unread,
Aug 26, 2016, 2:11:24 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 19:00 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:
That's not entirely true - if dartfmt wrapped with the assumption that a tab is 2 chars, you still have the flexibility to render them as 4 in your editor if you wish.

Sure, but then you'll be annoyed when dartfmt wraps your lines "prematurely" because you see them as farther to the right than it does. In fact, setting a tab stop higher than two means you can no longer rely on all the code in your window fitting in 80 columns.

I would not. You already can't count on code fitting into 80 chars, because I can have a long string :-)

 
I genuinely can't see any negative from using tabs (except for tools that render tabs at a size you would not like; but how is that worse than my editor, the thing where I actually write the code, not rendering at a size I would like?) 

The reason we use monospace fonts for code is because it makes it easier to line things up horizontally and ensure code fits within various horizontal dimensions.

Tab is like a super-non-monospace character that is not only not as wide as every other character, but its width isn't even stable across users and tools. That's not a good recipe for consistent typography.

This is a bit wolly; I don't see why it matters. If I prefer my indent at 4 characters, I should be allowed to have it. If some stuff doesn't match up now, then that's fine, I made that decision (but with no aligning in Dart and it already allowing lines over 80 chars, I just don't see any real implications here).

 
Again, I don't expect this to change (and don't want to dig up tabs vs spaces) but other than "it's too late to change", I just can't see how spaces is a better choice than tabs.

Tabs add a lot of complexity. Every tool, web site, code review system, editor, etc. needs to handle them, have a UI to let users configure their width, persist that setting somewhere, etc.

Not true. They only need to add options if you want them to be customisable. Spaces only "solves" that problem by not having them customisable. So how is not having these options for tabs worse than using spaces?

 
In return for that, you get per-user variance on indentation. That assumes that user's ability to read code with certain indentation varies so much that it justifies that complexity.

As far as I can see, there doesn't need to be any added complexity. Let's say you took the current dartfmt and changed all double-space indent to tabs, then everyone at Google set their tab size to 2 (which they probably already have). What are the actual disadvantages to Google (and anyone else that likes narrow indenting)?

If the only issue is "GitHub now shows it indented more than we could like" then to me that seems somewhat selfish - today, my editor shows code indented less than I would like and I think editors matter are more important than GitHub.

(and I think forcing spaces on people to work around lame GH functionality is rather silly; has anyone asked them to change it? Even I think 8 chars is ridiculous!)

Joao Pedrosa

unread,
Aug 26, 2016, 2:12:05 PM8/26/16
to mi...@dartlang.org
Hi,

I just had an idea though. Editors could render multiples of leading spaces as though they were as elastic as tabs. Then it would work.

Cheers,
Joao

--

Filip Hracek

unread,
Aug 26, 2016, 2:13:35 PM8/26/16
to mi...@dartlang.org
This assumes you never open any Google code and we never open any code of yours, right?

Bob Nystrom

unread,
Aug 26, 2016, 2:27:37 PM8/26/16
to General Dart Discussion
On Fri, Aug 26, 2016 at 11:11 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
If I prefer my indent at 4 characters, I should be allowed to have it.

Yes, but your preference has an implementation and complexity cost. Effort spent supporting customizable tab stops is time not spend on other useful features you might like. There is a real opportunity cost to letting users have their personal preference.
 
Again, I don't expect this to change (and don't want to dig up tabs vs spaces) but other than "it's too late to change", I just can't see how spaces is a better choice than tabs.

Tabs add a lot of complexity. Every tool, web site, code review system, editor, etc. needs to handle them, have a UI to let users configure their width, persist that setting somewhere, etc.

Not true. They only need to add options if you want them to be customisable.

Yes, but just now, you said they should be customizable. If you're fine with "non-customizable tabs", their ASCII representation is 32. :)

– bob



tatumizer-v0.2

unread,
Aug 26, 2016, 2:29:42 PM8/26/16
to Dart Misc
Every code I've seen, if contains tabs, contains spaces as well (maybe it's only me?). Fixed editor setting won't help with that. Also, you have to be able to open in many tools (IDE, git, code review tool, or somebody just sends a snippet of code). Makes life absolutely miserable.

Danny Tuppeny

unread,
Aug 26, 2016, 2:40:20 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 19:22 'Filip Hracek' via Dart Misc <mi...@dartlang.org> wrote:
Of course you can change it in your IDE. But do you really want to manually switch this option every time you look at someone else's code? Or do you suggest the source file should have some machine-readable comment that would give it a hint what the tab size is (like "/* tabs=4 */)?

I don't understand what you mean. No, you'd never changed it, nor would you need a hint. You set your editor to how *you* want it - eg. Google would set it to 2, and I would set it to 4. All code I open would be indenting by 4 characters for me, and all code Google open would be 2. Everyone is happy; nobody needs to mess with anything.

This assumes you never open any Google code and we never open any code of yours, right?

No, not at all. I'm not sure why you think that. Whatever Dart code you open, you would see indented at 2 characters, as you wish, and as your editor is set to.

Any code (mine or yours) that I open, I see indenting at 4 characters, as I wish, and as my editor is set to.

What you describe is exactly how it is today - I open your code and it's not how I want; you open mine (if I indent at 4 spaces) and it's not how you want.

It sounds like spaces cause the issue you are describing, not tabs? 

Filip Hracek

unread,
Aug 26, 2016, 2:40:24 PM8/26/16
to mi...@dartlang.org
Here's the broken promise I'm talking about when you introduce tabs to dartfmt.

Look at this example Flutter code:

Inline image 1

It uses spaces for indentation, but let's say it's tab with width=2. Now when you open it in an IDE with tab width=4, here's what you'll see:

Inline image 2

That's a broken promise by dartfmt: the lines are over 80 chars long. If you open it in an IDE that has tab width=8 (which seems to be a default in some of them), you see this:

Inline image 3

Again, that's definitely a broken promise (make code look consistent for users). So either dartfmt would have to assume the worst (tabs 8 chars long), or it would have to somehow find out what the tab width is supposed to be, or it would have to be okay with going over the 80 chars limit on many occasions (as opposed to on exceptionally).

Danny Tuppeny

unread,
Aug 26, 2016, 2:48:38 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 19:27 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:
On Fri, Aug 26, 2016 at 11:11 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
If I prefer my indent at 4 characters, I should be allowed to have it.

Yes, but your preference has an implementation and complexity cost. Effort spent supporting customizable tab stops is time not spend on other useful features you might like. There is a real opportunity cost to letting users have their personal preference.

I don't really understand what the cost is (other than changing it now)?

 
Not true. They only need to add options if you want them to be customisable.

Yes, but just now, you said they should be customizable. If you're fine with "non-customizable tabs", their ASCII representation is 32. :)

They already are customisable in editors. I want to be able to customise them in the places that already support it. I don't care so much if some edge-case tool that is not my editor renders them at the wrong size; I care about the 90% case, where I'm actually trying to write good code.

The difference is, with tabs, an editor/tool can add an option to set the size if they wish. Using spaces, it just does not make sense.

Danny Tuppeny

unread,
Aug 26, 2016, 2:51:22 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 19:30 tatumizer-v0.2 <tatu...@gmail.com> wrote:
Every code I've seen, if contains tabs, contains spaces as well (maybe it's only me?). Fixed editor setting won't help with that. Also, you have to be able to open in many tools (IDE, git, code review tool, or somebody just sends a snippet of code). Makes life absolutely miserable.

Actually, an editor setting will fix that. We have IDE tools that tell us when files have mixed tabs and spaces and automatically format on save! :)

But in any case, mixed tabs and spaces is not an argument for either, it's an argument to not be sloppy and have better tools. Tabs are not the cause of mixing tabs and spaces (in fact, you can probably blame spaces; since people presses the Tab key not the Space key to indent; so the mixture must come from tab key doing spaces!) ;-) 

Danny Tuppeny

unread,
Aug 26, 2016, 2:59:27 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 19:40 'Filip Hracek' via Dart Misc <mi...@dartlang.org> wrote:
Here's the broken promise I'm talking about when you introduce tabs to dartfmt.

Actually, I disagree.

Firstly, dartfmt doesn't promise less than 80 characters, you can already break that.

Secondly, if you choose to set your tab to be large and you try to render on a short screen, things aren't going to fit. This is totally acceptable and as a user you get to choose which you want; larger tabs or fitting (mostly) into 80 char.

I would take that 4-char indenting in a heartbeat. I am not coding in an 80-character wide terminal. If you are, then go with 2 characters, that's fine. With tabs, you have choice!

(I'd also argue that code could be refactored; 8 nested levels of indenting in a single method seems somewhat unreadable regardless of indenting size).

I really don't understand these arguments... "You can't have tabs because if you set tabs to 4 characters then (this thing I don't like) won't look right". With tabs, I get to choose. You can still have your code was you want. People are making (invalid) assumptions about how others want their code. The only way this impacts those wanting 2-space indenting is that other tools will display things "wrong"; and that is no different to how us wanting 4-char indenting see things in all tools.
Screen Shot 2016-08-26 at 11.28.11.png
Screen Shot 2016-08-26 at 11.27.47.png
Screen Shot 2016-08-26 at 11.28.21.png

Don Olmstead

unread,
Aug 26, 2016, 3:18:45 PM8/26/16
to mi...@dartlang.org
Look in a better world people would understand that tabs are for indentation and spaces are for alignment. In a perfect world http://nickgravgaard.com/elastic-tabstops/ would be the norm.

Having coded on many different codebases both internal and external you really need to just take the stance "when in Rome". Dart's format wants spaces so use spaces. Golang wants tabs. Python wants spaces. C/C++ can have any number of different formats. One code base I'm working on does 2 spaces another does 4 spaces. Who cares?

The tabs vs spaces war is stupid. Silicon Valley even made a point of making fun of its absurdity https://youtu.be/SsoOG6ZeyUI.

On Fri, Aug 26, 2016 at 11:59 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
On Fri, 26 Aug 2016 at 19:40 'Filip Hracek' via Dart Misc <mi...@dartlang.org> wrote:
Here's the broken promise I'm talking about when you introduce tabs to dartfmt.

Actually, I disagree.

Firstly, dartfmt doesn't promise less than 80 characters, you can already break that.

Secondly, if you choose to set your tab to be large and you try to render on a short screen, things aren't going to fit. This is totally acceptable and as a user you get to choose which you want; larger tabs or fitting (mostly) into 80 char.

I would take that 4-char indenting in a heartbeat. I am not coding in an 80-character wide terminal. If you are, then go with 2 characters, that's fine. With tabs, you have choice!

(I'd also argue that code could be refactored; 8 nested levels of indenting in a single method seems somewhat unreadable regardless of indenting size).

I really don't understand these arguments... "You can't have tabs because if you set tabs to 4 characters then (this thing I don't like) won't look right". With tabs, I get to choose. You can still have your code was you want. People are making (invalid) assumptions about how others want their code. This only way this impacts those wanting 2-space indenting is that other tools will display things "wrong"; and that is no different to how things are to us wanting 4-char indenting see things in all tools.

Danny Tuppeny

unread,
Aug 26, 2016, 3:28:08 PM8/26/16
to mi...@dartlang.org
On Fri, 26 Aug 2016 at 20:19 Don Olmstead <don.j.o...@gmail.com> wrote:
Look in a better world people would understand that tabs are for indentation and spaces are for alignment. In a perfect world http://nickgravgaard.com/elastic-tabstops/ would be the norm.

Having coded on many different codebases both internal and external you really need to just take the stance "when in Rome". Dart's format wants spaces so use spaces. Golang wants tabs. Python wants spaces. C/C++ can have any number of different formats. One code base I'm working on does 2 spaces another does 4 spaces. Who cares?

The tabs vs spaces war is stupid. Silicon Valley even made a point of making fun of its absurdity https://youtu.be/SsoOG6ZeyUI.

If we always just accept the status quo then nothing will ever improve. Everything should be challenged :-)

I agree that the whole thing is ridiculous, but mainly because I've never yet seen a good argument for spaces that makes sense to me. I don't expect things to change as a result of this thread, but I would really like to see some concrete reasons that spaces are better so that I don't have to be sad every time I see someone using them. So far, none of the arguments make sense to me, they've all either been "if we use tabs than it appears wrong in {x tool}" (which I don't see as any different to how it is today) or "if you set your tabs bigger, you won't like how it appears in {some other context}" (which makes no sense, it's someone that doesn't want it trying to justify when I shouldn't want it... I know what tabs look like, I've written a lot of code using them! :)).

I don't want to prolong a debate that'll never be resolved, but I would genuinely be interested in actual seeing some actual real advantages to spaces that don't fall into the two categories above (though I'm really not sure there any).

But, I suspect this thread has already caused way more emails than people would like; so I'll refrain from posting the same responses to the same arguments being made over and over (I'll keep reading, in the hope someone can convince me spaces have a place!).

Don Olmstead

unread,
Aug 26, 2016, 4:54:05 PM8/26/16
to mi...@dartlang.org
I didn't say spaces are better. In my opinion they're worse because they mix indentation and alignment.

I would prefer if Dart followed Golangs example which does tabs and has no line length limit. It chose 2 spaces and 80 characters as the line length.

Roll with it. That's just what you have to do in any sort of professional programming situation. Its not worth railing against something so trivial.

--

Kasper Peulen

unread,
Aug 26, 2016, 5:13:18 PM8/26/16
to mi...@dartlang.org
I think most important is consistency, I dont care much either way, but one point for spaces is that tabs look fucked up on github.
--
Kasper

Jonas Bojesen

unread,
Aug 30, 2016, 12:56:15 PM8/30/16
to Dart Misc
For me projects back. In terminals on minimalistic linux, tabs caused a lot of pain and confusion, hence space was set as standard. Just picked a random tab/terminal question from SO, this one even concerning windows. http://stackoverflow.com/questions/20691068/how-do-i-type-a-tab-character-in-powershell Only 2 years old and almost 3000 viewers
Now purely guessing, but similar the limit of 80 characters long lines, could be motivated from development in terminal prompts. So choosing these two as standard could origin from Dart projects where the target environment are terminal prompts. So far I haven't used dartfmt, but if possible I will choose more than 80 chars on own projects. With 80 chars meaningful identifiers names combined with costumes of strong typing don't match good. Looking at js Polymer seems they have a more standard approach with like 110 chars

 And typing demands more chars, not fewer, but as written above the Dart team set the standard and then more easy just to follow if one should deliver to their projects.

Danny Tuppeny

unread,
Aug 30, 2016, 2:37:22 PM8/30/16
to mi...@dartlang.org
On Tue, 30 Aug 2016 at 17:56 Jonas Bojesen <jonas....@gmail.com> wrote:
So far I haven't used dartfmt, but if possible I will choose more than 80 chars on own projects

The problem with dartfmt with > 80 characters is that it unwraps everything. So if you set it at 160 and write this:

var a = myCollection
    .filter((c) => isThing(c))
    .map((c) => convertThing(c))
    .sort((c1, c2) => c1.name.compareTo(c2.name));

it all gets unwrapped to:

var a = myCollection.filter((c) => isThing(c)).map((c) => convertThing(c)).sort((c1, c2) => c1.name.compareTo(c2.name));

Which IMO is crazy :(

I understand the idea of the same input giving the same output; but its applied really inconsistently - for example, if you have blank lines in methods, they are preserved. So why not preserve newlines before method calls?

I am using it (for now), but it does feel a little like the reasons for it doing some things we don't want are being being broken in other places anyway :(

Personally, I think a far better solution would be to have format options stored in a file (like we have analysis_options.yaml). That way we get to choose how it's formatted, but it's still consistent within a project :)

Bob Nystrom

unread,
Aug 30, 2016, 3:05:17 PM8/30/16
to General Dart Discussion

On Tue, Aug 30, 2016 at 11:37 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
I understand the idea of the same input giving the same output; but its applied really inconsistently - for example, if you have blank lines in methods, they are preserved. So why not preserve newlines before method calls?

There are a couple of places where one (and only one) discretionary blank line will be preserved. Basically between member declarations and statements. But those are not ideal when it comes to consistent automated formatted. Ideally, we would be able to automatically choose where to insert those blank lines too. Probably before lines that start with a line comment, and after statements and declarations that have {} bodies. I've taken some steps in that direction—it will always insert a blank line after function, class, and brace-bodied member declarations. But there's an art to automating the formatting while not being too disruptive to existing code. :-/

– bob



Danny Tuppeny

unread,
Aug 30, 2016, 3:18:58 PM8/30/16
to mi...@dartlang.org
On Tue, 30 Aug 2016 at 20:05 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:
I understand the idea of the same input giving the same output; but its applied really inconsistently - for example, if you have blank lines in methods, they are preserved. So why not preserve newlines before method calls?

There are a couple of places where one (and only one) discretionary blank line will be preserved. Basically between member declarations and statements. But those are not ideal when it comes to consistent automated formatted. Ideally, we would be able to automatically choose where to insert those blank lines too. Probably before lines that start with a line comment, and after statements and declarations that have {} bodies. I've taken some steps in that direction—it will always insert a blank line after function, class, and brace-bodied member declarations. But there's an art to automating the formatting while not being too disruptive to existing code. :-/

I was thinking about within methods?

thing() {
  test();
  test();


thing() {
  test();

  test();
} 

Unless I'm remembering incorrectly, aren't these both left as-is?

tatumizer-v0.2

unread,
Aug 30, 2016, 3:34:36 PM8/30/16
to Dart Misc
> But there's an art to automating the formatting while not being too disruptive to existing code. :-/
You can treat special comment like //foff to copy the following lines, until blank line, as is. That's the whole art :)

Danny Tuppeny

unread,
Aug 30, 2016, 3:42:52 PM8/30/16
to mi...@dartlang.org
On Tue, 30 Aug 2016 at 20:34 tatumizer-v0.2 <tatu...@gmail.com> wrote:
> But there's an art to automating the formatting while not being too disruptive to existing code. :-/
You can treat special comment like //foff to copy the following lines, until blank line, as is. That's the whole art :)

I hate the idea of cramming things like this into comments :/

I do think it's a tricky issue to solve technically, but it doesn't sound like the issues I mentioned are technical, more just decisions. I think it's weird to not preserve the users newlines in some places but do in others. If the same input doesn't always generate the same output when it differs only by whitespace (which I don't think it does) then it doesn't seem like that goal isn't being met and isn't a good reason to strip users newlines elsewhere.

It's not perfect, but the C# formatting in Visual Studio is excellent (without ReSharper; my colleagues using that seem to ball things up entirely). It reformats most stuff, but preserves user-formatting in a couple of places (such as the one I mentioned earlier). Since we all enabled format-on-save we have no formatting-related issues, even though there's a little scope for people to format things differently. The only thing missing is having the formatting rules in the repo as opposed to VS settings, which 'm sure will come one day.

Bob Nystrom

unread,
Aug 30, 2016, 4:24:36 PM8/30/16
to General Dart Discussion
On Tue, Aug 30, 2016 at 12:18 PM, Danny Tuppeny <da...@tuppeny.com> wrote:
Unless I'm remembering incorrectly, aren't these both left as-is?

Yes, they are. That's what I was referring to by "between statements". :)

– bob

 


Danny Tuppeny

unread,
Aug 30, 2016, 4:49:53 PM8/30/16
to mi...@dartlang.org
Oops, I mis-interpreted "between member declarations and statements".. but that wouldn't make much sense!

So, what is the reason not to preserve them for chain method calls like in my earlier example? Seems like if someone had explicitly put linebreaks in there then it's more readable; I don't think anything is being gained by stripping them but it harms readability?

Bob Nystrom

unread,
Aug 30, 2016, 5:09:58 PM8/30/16
to General Dart Discussion

On Tue, Aug 30, 2016 at 1:49 PM, Danny Tuppeny <da...@tuppeny.com> wrote:
So, what is the reason not to preserve them for chain method calls like in my earlier example?

By default, dartfmt doesn't want to preserve any of the user's original formatting. It wants to completely control the whitespace so that users don't have to worry about it at all.

So any place where it does preserve formatting is an outlier and it's those outliers that need justification.

– bob

tatumizer-v0.2

unread,
Aug 30, 2016, 11:07:27 PM8/30/16
to mi...@dartlang.org
Different approach to formatting is represented by a tool called "jslint"

It checks your code for compliance with some style rules (you can select the strictest subset to be more pious than the Pope), and complains profusely. But it never changes your code.
At first, it is shocking: it says you're missing a space here and there, so why not go ahead and insert these frigging spaces? No, it wants YOU  to insert the spaces.

It took me many a night of intense thinking to figure out the idea behind this paradox..My working conjecture (at the time of writing) is: the tool *knows* it cannot insert even a single space
without changing the meaning of the program! Indeed, the line might become longer, will no more rhyme with another line, or won't fit, or something, and who knows whether human reader can still make sense of his own writing.

What happens then is after a couple of minor nervous breakdowns and a bottle of Advil, you start writing good code, even without advice from jslint!. You develop *perfect* style!.
Isn't it a goal of any aspiring writer? @Bob?



Danny Tuppeny

unread,
Aug 31, 2016, 3:05:03 AM8/31/16
to Dart Misc
This sounds like the worst of both worlds to me! The tool isn't tidying up your code for you, yet you still have no control over the readability because it will fill your screen with warnings if you don't do exactly what it wants. Maybe good as a build-time check if you want to fail builds of people aren't following rules, but doesn't sound like a great solution on a developer machine. If you can fix their stuff, fix it. I'm so used to Visual Studio fixing all my issues when I hit Save (I have it sort usings, remove unused usings, reformat the doc) I'd hate to be doing it manually.

That said, JavaScript probably isn't the easier language to rewrite without breaking... We've found many places where or JavaScript was broken by minifiers! Luckily Dart isn't the big bag of crap that JavaScript is!

What happens then is after a couple of minor nervous breakdowns and a bottle of Advil, you start writing good code, even without advice from jslint. You develop *perfect* style.
Isn't it a goal of any aspiring writer. @Bob?



Alexandre Ardhuin

unread,
Aug 31, 2016, 9:05:14 AM8/31/16
to General Dart Discussion
400,000 GitHub repositories, 1 billion files, 14 terabytes of code: Spaces or Tabs?
https://medium.com/@hoffa/400-000-github-repositories-1-billion-files-14-terabytes-of-code-spaces-or-tabs-7cfe0b5dd7fd

And BTW I <3 dartfmt. Working on Java projects where there are almost one style per project, it's just awesome to have only one style (no need to configure tools, no need to adapt your reading to another style...)

Alexandre

--

Lasse R.H. Nielsen

unread,
Aug 31, 2016, 9:25:22 AM8/31/16
to mi...@dartlang.org
It's interesting that Go is the only language with 100% tabs.
It makes sense - they have a formatter, and they are not afraid to use it. If you have a formatter that always post-processes whatever mish-mash you have created and converts it to tabs, then tabs are less dangerous than if they have to be maintained by humans.

I probably still won't like it, but it isn't completely unacceptable.
/L 
--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Joao Pedrosa

unread,
Aug 31, 2016, 9:59:00 AM8/31/16
to mi...@dartlang.org
Hi,

Go was supposed to compile code much faster than C++ did, since the Go creators were really annoyed
by C++'s relative slow compilation and had the goal of fixing that. When Go did not ship some extra
feature, they could say "but we don't want the bloat that would slow down the compilation."

I guess being able to parse files slightly faster by having fewer space characters also helped them, even
if on that case they were just used to tabs when coming from C.

The Go code is not too nested and with their type inference and not having "generics" it keeps their code
sparse. So even if they interpret their tabstops with the 8 spaces it would still fit on 80 columns, I'd
assume.

People may complain about opinionated code formatters, but someone quoted Rob Pike as saying that
even though users don't always like the Go formatter style, they still do like the Go formatter itself. :-)

JavaScript was one of the projects with good showing of tabs still. I recall seeing tabs on the jQuery
project for example, even if it was not consistent. Users who like tabs may be less likely to keep code
limited to an arbitrary column limit like the 80. On the column limit, I'd also like to say that some
languages that use meaningful spaces may have problem breaking up expressions into multiple lines.


Cheers,
Joao

tatumizer-v0.2

unread,
Aug 31, 2016, 10:26:24 AM8/31/16
to Dart Misc
> The Go code is not too nested and with their type inference and not having "generics" it keeps their code
sparse.

It's because 70% of their code looks like

if err != nil {
    return err
}

No wonder they have excellent formatter - their job is easy. No so in dart!

Joao Pedrosa

unread,
Aug 31, 2016, 10:50:21 AM8/31/16
to mi...@dartlang.org
Hi Alex,

That is the downer. Sometimes we forget the downside of languages and think "hey I would I'd like to
try it again." Then we see a little bit of their code and are reminded of why we avoided it in the first
place. :-)

But in Dart and JavaScript we see folks saying that code that looks complicated, that has try/catch
blocks or somesuch, that it may not be optimized or inlined. In Go, they are just upfront about it. "Yes,
we do it all with structs and dynamic interfaces." While other languages have to catch up by going
backwards "Oh I want it to be quick, so I have to keep it with structs and maybe avoid other higher
level features too."

Cheers,
Joao


--

Danny Tuppeny

unread,
Aug 31, 2016, 12:16:33 PM8/31/16
to mi...@dartlang.org
On Wed, 31 Aug 2016 at 14:05 Alexandre Ardhuin <alexandr...@gmail.com> wrote:
400,000 GitHub repositories, 1 billion files, 14 terabytes of code: Spaces or Tabs?
https://medium.com/@hoffa/400-000-github-repositories-1-billion-files-14-terabytes-of-code-spaces-or-tabs-7cfe0b5dd7fd

I saw this, but I think assuming this means spaces are better is a bit flawed, for at least these reasons:

1. It assumes that "most used" is "most preferred" (or "better") when in reality IDE defaults and what existing code already uses play a big part  
2. This code doesn't seem to have excluded things like multi-line comments where all but the first line start with a space:
/**
 * comment
 */
(I don't think that would change the results, but possibly the differences could be much smaller; though maybe I overestimate how much commenting happens in OSS ;)).

I think it would've also been interesting if they'd counted the spaces being used to indent (much more tricky, I know) because it'll show whether people prefer 2/4/8 (relevant to this discussion) and also the spread across different widths (which adds weight to tabs being a better solution). If you're reading thins thinking "WTF? 8?", it's apparently what Linus requires for Linux; reasons are documented here!

That said; I really don't think it'll ever change. Existing code (which is mostly spaces) is a big enough reason for people not to change that it really doesn't matter what advantages there are. They'll only change from spaces if they're forced (like with Go).

It'd be interesting to see the Dart Team's opinions on the Go Team's decision to use Tabs and vice-versa. I think there's a lot to learn from people discussing differences in opinions and trying to convince each other; sometimes there's just stuff you never considered that might change your mind :-)

tatumizer-v0.2

unread,
Aug 31, 2016, 2:12:35 PM8/31/16
to Dart Misc
> But in Dart and JavaScript we see folks saying that code that looks complicated, that has try/catch
blocks or somesuch

Though it's a bit off-topic in the current thread... 
There's always essentially one single point in the entire program where you are supposed to handle exceptions.
The rest of try/catch blocks are there because:

1) programmer is clueless. He believes every exception has to be caught, repackaged as some other exception and thrown again (90% cases)

2) you need to catch exception to add context info. I tried to raise this issue here, but to no avail

3) in very rare cases, you have no choice: e.g. you have user's input, need to convert to int, but it's invalid. Java until version 1.5 didn't have a standard way to check syntax of int, so you either write your own, or ... catch exception
(Even now, Scanner class is not very famous).

4. There are other, ever rarer, cases - indeed, outliers beyond classification.

What go is doing essentially is not only treating everybody as category 1 above - it's FORCING everyone into this category. Very flattering.
Needless to say, item 2) is not addressed by go at all. In dart, at least it's possible to address - just there's no appetite for that.

Well, every language has its fans, let all flowers bloom


Bob Nystrom

unread,
Aug 31, 2016, 4:04:18 PM8/31/16
to General Dart Discussion
On Wed, Aug 31, 2016 at 6:58 AM, Joao Pedrosa <joaop...@gmail.com> wrote:
I guess being able to parse files slightly faster by having fewer space characters also helped them, even
if on that case they were just used to tabs when coming from C.

I don't believe tabs has a measurable performance impact on compilation time.
 
The Go code is not too nested and with their type inference and not having "generics" it keeps their code
sparse. So even if they interpret their tabstops with the 8 spaces it would still fit on 80 columns, I'd
assume.

Yes, Go in general doesn't crawl to the right as far as other languages:
  • There are no namespace declarations with nested bodies like C# and C++.
  • Methods are not nested inside a class body.
  • No nested try/catch/finally blocks.
  • No generics means shorter type annotations.
  • The core libraries have a distinct preference for terse names. Though, acting against Go is that all uses of imported names must be prefixed.
Also, they don't have any official limit on line length.

– bob

tatumizer-v0.2

unread,
Sep 2, 2016, 5:24:53 PM9/2/16
to Dart Misc
Tip:
if you want to stop dartfmt from merging your lines, there's already a feature for this.

BEFORE:
   var a = []
   
.filter((c) => true)
   
.map((c) => c)
   
.sort((c1, c2) => c1.name.compareTo(c2.name));


dartfmt -l 160 test.dart
prints
  var a = [].filter((c) => true).map((c) => c).sort((c1, c2) => c1.name.compareTo(c2.name));


AFTER:
   var a = [] //
   
.filter((c) => true)
   
.map((c) => c)
   
.sort((c1, c2) => c1.name.compareTo(c2.name));


dartfmt -l 160 test.dart
prints
  var a = [] //
     
.filter((c) => true)
     
.map((c) => c)
     
.sort((c1, c2) => c1.name.compareTo(c2.name));


The feature was found by way of intense thinking and hours of experimentation.



  

Danny Tuppeny

unread,
Sep 2, 2016, 6:10:19 PM9/2/16
to Dart Misc

lol, interesting idea! :D


--

tatumizer-v0.2

unread,
Sep 2, 2016, 7:37:26 PM9/2/16
to Dart Misc

> lol, interesting idea! :D


Just don't tell Bob, he will be upset :(





Danny Tuppeny

unread,
Sep 3, 2016, 4:28:13 AM9/3/16
to mi...@dartlang.org
On Sat, 3 Sep 2016 at 00:37 tatumizer-v0.2 <tatu...@gmail.com> wrote:

> lol, interesting idea! :D

Just don't tell Bob, he will be upset :(

I don't think he gets upset easy.. he continues to respond to my repeated attempts to destroy all his hard work! ;)

But as long as you put a "real" comment there, this seems totally legit to me! :D

Bob Nystrom

unread,
Sep 6, 2016, 12:53:41 PM9/6/16
to General Dart Discussion
On Sat, Sep 3, 2016 at 1:27 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
I don't think he gets upset easy.

I have raised two toddlers. As long as you are not literally smearing feces on my furniture while screaming at the top of your lungs, I've seen worse. :)

– bob

Danny Tuppeny

unread,
Sep 6, 2016, 12:55:21 PM9/6/16
to mi...@dartlang.org
You've been to my house?!

Danny Tuppeny

unread,
Sep 6, 2016, 12:55:43 PM9/6/16
to mi...@dartlang.org
Oh man that sounded weird. I also have two toddlers =) 

Bob Nystrom

unread,
Sep 6, 2016, 12:59:39 PM9/6/16
to General Dart Discussion

On Tue, Sep 6, 2016 at 9:55 AM, Danny Tuppeny <da...@tuppeny.com> wrote:
I also have two toddlers =) 

I'm sorry for your furniture. :)

– bob

Reply all
Reply to author
Forward
0 new messages