78 comments

[ 3.2 ms ] story [ 62.3 ms ] thread
The tradeoff here is not being able to use a universal set of tooling to interact with source files. Anything but text makes grep, diff, sed, and version control less effective. You end up locked into specialized tools, formats, or IDE extensions, while the Unix philosophy thrives on composability with plain text.

There's a scissor that cuts through the formatting debate: If initial space width was configurable in their editor of choice, would those who prefer tabs have any other arguments?

You can't easily search / grep etc. an IR, unless you use some kind of reverse translator. Readable source files have their benefits in being simple in that sense.
Interesting read. I’ve often wondered why the projection we see needs to be the same as the stored artifact. Even something like a git diff should be viewable via a projection of the source IR.

With things like treesitter and the like, I sometimes daydream about what an efficient and effective HCI for an AST or IR would look like.

Things like f#s ordered compilation often make code reviews more simple for me, but that’s because a piece of the intermediate form (dependency order) is exposed to me as a first class item. I find it much more simple to reason about compared to small changes in code with more lax ordering requirements, where I often find myself jumping up and down and back and forth in a diff and all the related interfaces and abstract classes and implementations to understand what effect the delta is having on the program as a whole.

Aren't most projects these days written in a mix of languages, most of them text? You'd have to get them to change to use the same tools we currently use, or else you'd have to use special tools. The beauty of the modern stack is the base tools are near universal.

If you want everyone to see their own preference of format, either write a script or get AI to format it for you.

I've heard that Google works [sort of] that way (don't know, myself). They have a lot of tools that allow devs to use what formatting they want, and it's made standard, during checkin.

I heard this, many years ago, when we used Perforce. The Perforce consultant that we dealt with, told us this, as an example of triggers. Back then, I was told that Google was a big Perforce shop (maybe just a part of Google. I dunno).

I have heard that this was one of the goals of developing IDLs. I think the vision was, that you could have a dozen different programmers, working in multiple languages (for example, C for the drivers, Haskell for the engine, and Lua for the UI). They would be converted to a common IDL, when submitted to configuration management, and then extracted from that, when the user looks at it.

I can't see that working, but a lot of stuff that I used to think was crazy, has happened, so, who knows?

It never ceases to amaze me how many times people can essentially re-invent S-expressions without realizing that's what they are doing.
It basically is, unless you’re in a whitespace-Nazi language like Python (no offense!).

It doesn’t get much less formatted than Minified JavaScript, except maybe Perl or Brainfuck.

Others have already mentioned how why this is a bad idea (e.g. common plaintext tools don't work, added complexity, etc.)

But I'll also mention that this pretty much already exists. You can have whitespace options for git. I also imagine there's some setup using hooks that uses one formatter locally, and another for remote.

Also, the common IR already exists - it's just the AST. It was "solved" back in the day when people were throwing whatever they could to the wall to see what sticks since it was all so new. With the benfit of hindsight, I think we can say that it's not that good of an idea.

I think the problem can be defined equally as: we can't invest in something more abstract than "plain text" at this time. When we try, it gets downgraded to a plain text projection of the syntax.

The plain text encoding itself exists in a process of incremental, path-dependent development from Morse Code signals to Unicode resulting in a "Gigantic Lookup Table" (GLUT, my coining) approach to symbolic comprehension. The assumption is useful - lots of features can "just work" by knowing that a particular bit pattern is always a particular symbol.

If we push up the abstraction level, we get a different set of symbols that are better suited to the app, but not equivalent GLUT tooling. Instead we usually get parsing of plain text as a transport. For example, CSV parsing. It is sloppy; it is also good enough.

Edit: XML is also a key example. It goes out of its way to respect the text transport approach. There are dedicated XML editors. But people want to edit it as plain text and they can't quite get there because funny-business with character encodings gets in the way, adding a bunch of ampersands and semicolons onto the symbols they want to edit. Thus we have ended up with "the CSV of hypertext documents", Markdown.

Along these lines, Go eliminates many formatting decisions at the syntax level. E.g.,

  func main()
  {
          fmt.Println("HELLOWORLD")
  }
is not just non-standard formatting, but illegal Go syntax. Similarly, extra parentheses around if clauses are not allowed.
That’s essentially what black has done with Python, though.
There’s also a typography element to formatting source code. The notion that all code formatting is mere personal preference isn’t true. Formatting code a certain way can help to communicate meaning and structure. This is lost when the minimal tokens are serialized and re-constituted using an automated tool.

https://naildrivin5.com/blog/2013/05/17/source-code-typograp...

Kind of a stupid take if you ever plan on sharing your code or using git.
> you could view the source however you wanted. Spaces vs. tabs didn't matter because neither affects the semantics and the editor on the system let you modify the program tree directly (known today as projectional editing).

But formatting still doesn't matter. Outside of whitespace-dependent languages, formatting is a subjective thing -- it's a people concern, not a computer concern. I can store my JavaScript as AST if I want to.

In theory we could have an IDE apply a reformatting to any piece of code we looked at and formatted any changes back to the standard for the code base on updates. One of the things I dislike is that sometimes autoformatting does a poor job and looses some information that manually formatting provides but honestly in go fmt is mostly fine it just works.

All of this seems doable, I just think for the most part we don't care very much about our preferences, it has very little impact on readability. Its definitely doable however we could view the code however we most wanted it and have it stored in a different formatting. Might not be 100% round trip stable but it probably doesn't matter.

There is always better where the defaults can be overridden and formatting forced and we only format new and changed lines to reduce potential instability but again go fmt doesn't really suffer from this so its possible to make things pretty reliable. Its simple really, there is a default formatting and the code is stored that way and we can then have our view of choice reformat the code as we want it, when its stored its stored in the default.

This is how Chrome Dev Tools shows source code. The original is often minified or in whatever format the author left it. And when you check the "pretty" checkbox in dev tools, it shows up using whichever format Chrome developers decided it should look like.
I have gotten into discussions with people about linters and code formatting standards in general and I always liken it to a work desk. If my company decided that every work desk had to be 100% generic and that every day if I put any adjustment, even to the seat height, on that desk they would reset it, I would probably think that place was hostile. Even if I could 'auto format' it back to something close every time I stepped up to the desk I would be pretty unhappy. It just wouldn't feel like mine and eventually I would be beaten into whatever style, which wasn't my own, the code came out of the repo as. Basically, linters are evil. They only work for the person that set them up.

Leave code format up to the primary owner of the file. It is pretty rare that code has more than one person that does 95% of the edits on a file so let them own the formatting. In the rare case where there are shared files with shared edits then it is ok to mandate some sort of enforced format but those are so rare that it generally isn't worth discussing. The proposed approach here ignores all the messy non-standard stuff that happens because of the margins or the rules that are very hard to build in when codifying personal coding style.

Let me have my messy desk and I'll let you have yours.

Unison doesn't move the formatting choices further than the machine on which the code was written. The codebase only contains the AST.

Its such a cool idea, though I haven't spent much time using it in anger, so its hard to say if its a useful idea.

Reminds me of dion systems. A few years ago a group of devs was working on a programming environment that feels very close to what DIANA is describing.

The project is dead enough that they no longer own the TLD for the company. As far as I know, the only remnants of the project are youtube recordings of demos held at conferences.

I've never understood why people care so much about the linter settings. It's so obviously bikeshedding, just make a choice, run the linter automatically and be done with it. I'm too busy doing actual software engineering to care about where exactly everything goes - I promise after a week you'll just get used to whatever format your team lands on.
Same! I have no patience for these kind of arguments about formatting. I don't care that you don't like what the formatter does, it isn't about you. I've written code in several different languages over the years and the main take away is that I can get used to reading anything. It's so important to pick a standard and follow it. As long as that standard is somewhat sane I couldn't care less what the actual standard is.

Another argument that is a pet peeve of mine is significant white-space vs curly braces. It literally doesn't matter. We often get new Python developers coming from a C# background and the amount of bitching about curly braces is so annoying. Just learn the language bro, it's not that hard.

Some styles can actively make some people less productive though e.g. I really try to avoid allman braces because I can work a lot better with denser (for a certain definition of dense code)

This, however, usually doesn't effect me if the official format for a project is one way or the other because [drumroll] I just format my tree differently and then format to the official style when I push.

Those that complain:

I've worked with several Development Leads to actually define these. After the initial adjustment period, everybody's local environment setup properly: No one ever spent time reviewing style and formatting on Pull Requests.

Just decide as a team, auto-apply if possible (less than 5 seconds for big changes), enforce, and be done with it. Stop wasting everybody's time because after weeks you cannot make your mind on it and also don't tell your team/Lead about it.

> just make a choice, run the linter automatically and be done with it.

Most people probably do this. These types of discussions (probably) come up when someone else made the choice and other people also need to adhere to this choice. This is important for teams, but sometimes big egos don't want these choices made for them.

It’s very simple: format code to a standard. Preferably the language default formatting. But it must be a standard that can be auto formatted to with a tool. Now when someone doesn’t like that standard, they can auto format from that standard to one of their liking for local development and back again to the project standard for pushing to the project. This can even be done automatically with gitattributes during checkout and commit. But without strictly enforcing a autoformatable standard this is not possible and you end up with bikeshedding.
I like that. We should have something like this for python.

Black is great, but maybe it's just me since it aligns with how I like the code formatted.

Would there be any downsides for python (or git ?) to define a standard way of formatting to save a valid file, and all the formatting necessary to read a file happens in the IDE showing the file ?

That would very much fit with python ethos 'There should be one-- and preferably only one --obvious way to do it.'

I have to disagree with the premise. Formatting code is a critical communication channel. Well-formatted code should tell you:

1. The developer has enough experience to understand that formatting matters.

2. The developer has enough discipline to stick with their chosen formatting rules.

3. The developer has the taste necessary to choose good formatting rules.

4. The developer has the judgement necessary to identify when other concerns justify one-off violations of the rules.

These are really important attributes for a developer to have. They affect every aspect of the code, not just formatting. Formatting is just a very quick proxy to measure those by.

Unfortunately, things like autoformatting and linter rules are destroying the signal. Goodheart's law strikes again.

I’d say you go re-read the article.

> The developer has the taste necessary to choose good formatting rules

Rely on this and you’re in trouble. More time will be lost just to argue which style is better. Go with the in-built formatter way of Go and Rust

my initial gut take from the title was "OH MY GOODNESS don't let {x} toxic developer who writes TERRIBLE code see this as justification". There are enough toxic bros who either 1. think this is unnecessary or 2. think it is perfectly solved.

re: intermediate representation and projectional editing: yes, editors are now getting better at helping you refactor code (rename function in language XYZ is possible in language servers for IDEs, /no AI required, it works better when a human coded AST tool does it/)

projectional editors aren't around /because the more complex parts of it are harder/ - BUT - I could definitely see more intelligent refactor tooltips written by humans.

For example: in Rust, if I've been passing a pointer vs borrowing (or whatever), pattern A for most of my code, then pattern B and it complains, it would be useful to have a tooltip that goes "do you want to refactor all the other references/parameters to pattern B" instead of Rust's default "this function isn't using pattern A" borrow checker error.