 I just want to start off by saying I'm really happy to be here. Thank you to Elixir Days for inviting me, and thank you to all of you for your time. So let's get started. So this is a GitHub issue that I discovered in October. It's Elixir Issue 6643. The title is Format Code-Based Files with the Upcoming Code Formatter. It was opened by Jose Valim, the creator of Elixir on Elixir, and it's part of why I'm here today. So it looks like all that lurking on Elixir's issue pages was worth something after all. I'd like to read the introduction to this issue because I think it's important. Elixir Master now includes a code formatter that automatically formats your code according to a consistent style. We want to convert Elixir's code base to use the formatter on all files. We understand that this means a lot of code churn now, but on the positive side, it means we can automatically enforce and or format future contributions, making it easier for everyone to contribute to Elixir. So this issue set off a very large refactoring project where many people changed a single file on the Elixir code base to get Elixir conforming with its own new formatter. And now, new pull requests to Elixir must pass through the formatter without requiring any changes. And I think this is going to have a very big ripple effect on projects throughout the Elixir community. As he was closing this issue, Jose provided a few statistics on the project. 425 files were changed. Of 214 pull requests led by 84 committers, 368 commits, and the time to complete was just four days. So to me this shows the power of this community and also the effectiveness of the tool. 84 people were able to use it in a very short amount of time with limited or no issues. And I think it shows enthusiasm for this tool even at the time when it had not yet been released. My name is Jake Worth. You can find me around the Internet at J.W. Worth. I work at Hatch Rocket in Chicago. Elixir has been my hobby language for about a year and a half, and when I'm not working I help maintain an open source Phoenix application called Today I Learned. So what is this? It's just a little GitHub issue, but I think it represents a really big change. We are a changing community. Our version 1.6 style is subjective. We are all code artists slinging our own artisanal version of Elixir. After 1.6 style conforms to a community style guide. We all have an agreement on what we think good style is and we share a consensus. And the word community is interesting to me because this was not the result of a democratic process or a standards board. It's a really big change and it will affect each of us and the Elixir community and it led me to some questions that maybe you thought about too. Such as what is auto formatting? Why should I care and most importantly what is it going to do to my code? So here's my pitch that I will try to return to throughout the talk. Format your code now. It is where Elixir is headed. This moment puts Elixir in the middle of a larger and I think fascinating discussion that is going on in software development. One that I think is changing. And I'm here today to help us gain a better understanding of this tool and a deeper grasp of that discussion that is happening right now. My agenda is we will be talking about a history of auto formatting, then we will look at arguments for and against and close out with practical applications. Once I get off stage these slides will be on speaker deck at JW Worth. This talk is going to be about 37 minutes so hopefully we will end in time for that coffee break. Part one, a history of auto formatting. So in this part of the talk I want to discuss auto formatting, where it comes from and what it looks like right now. So the first thing I think I need to answer is what is auto formatting? This is my working definition. Auto format to cause the layout of a document to be created or edited without further effort by the execution of a program. This is from an online dictionary and it's for a definition of something like what we're talking about but a little different but I think it applies. The term auto formatting is used interchangeably with linting but to me linting and auto formatting are not the same thing and this is a table I made to try to understand the difference. So the first row we have is a linter. The target of a linter is a code smell. It is looking for suspicious or unconventional syntax and the action it takes is it makes recommendations. It doesn't necessarily change the code. The original linter was created by Steven C. Johnson and it was called lint and it was created in 1978 while he was working at Bell Labs developing Unix and he envisioned lint as part of a two program system. The linter would identify the unconventional syntax and tell you about it and then the compiler would be freed up from that responsibility to just make the program performant. So we contrast that with an auto formatter. An auto formatter is looking for inconsistent style. It doesn't match some set of rules and it can recommend changes but it most of the time goes even farther and it actually changes the code. So I went on a little quest to figure out where this idea of auto formatting came from and this is what I found, a program called GNU indent. This is a Unix utility that formats C and C++ and it has multiple copyrights but the oldest I found was 1989. If you are aware of auto formatters that are older than this, I would love to be proven wrong by someone who's been doing this for longer than I have. There are a lot of auto formatters covering languages from Colbaugh and Fortran to JavaScript and Ruby but the oldest one I found was about 1989 and the oldest linter, the lint program, was 1978 so there's a difference in the time there which leads me to a theory that I have about auto formatting. Auto formatting solves a modern problem. Let me explain. So we need auto formatters now because we are using certain languages. We are using these modern, expressive, high level languages like Elixir and we are using languages like JavaScript that have a lot of baggage and technical debt and these languages provide a lot of different ways to do something. The Ruby principle of least surprise comes to mind for me where if I try something in Ruby I've never tried before I should not be surprised by what happens. I should have a pretty good idea of what's going to happen. Contrast that with a language like C that Stephen Johnson was using that has less choices and less expressiveness. So these modern languages they have more things that can be more decisions that you can make. So that's my theory based on my time thinking about this problem. We can talk about a recent example of a community that adopted an auto formatter and that is Golang. So Go was created in 2009 and the auto formatter, GoFump was released in 2013. Four years later. There's an overview of this moment in Go's history on the Golang blog. In that blog, we are talking about the history of the Golang blog. In that blog post, the author observed that 70% of the packages in the wild at that time were already conforming with the GoFump rules. And the community set out to close the gap. So from a casual Go users perspective, to me it seems hard to find Go code today that doesn't conform to this tool. And I think there are some lessons that we can learn from this. In that blog post, the author made four arguments for GoFump that I'd like to quickly review. Auto formatted Go ought to be easier to write. Never worry about minor formatting concerns while hacking away. Easier to read. When all code looks the same, you need not mentally convert others formatting style into something that you can understand. Easier to maintain. Mechanical changes to the source don't cause unrelated changes to the files formatting. Diffs only show the real changes. And lastly, uncontroversial. Never have a debate about spacing or brace position ever again. Yeah, sounds great. That sounds pretty good, right? I'm pretty much sold on this tool. I love that word uncontroversial as if anything in programming could ever be truly uncontroversial. But this was the dream. And it seems to have worked. When we look at Go code today across projects, it seems very uniform in appearance. And that's because of GoFump. So to wrap up on Go, I think that this can be done. And it has been done recently. Let's contrast that with what's happening right now in Elixir. Elixir was created in 2011. And the mixed format tool, the auto formatted for Elixir, was released in January of this year. And there's a nice overview at the ElixirConf keynote last year by Jose Valim. In that talk, he explained why he built the tool, the main keyword being productivity. And I want to talk a little about the arguments that he made later in the talk. But for now, as soon as he finished that keynote, he went out and tried to be successful with the tool as Go had done. Part of that was the pull request that I showed at the beginning of the talk, where we're actually changing the Elixir language. Some other interesting stuff happened, too. This is pull request 46 to a project called Elixir Style Guide. Remove guidelines that are automatically handled by a code formatter. It was opened by Jose Valim. What this pull request does is it removes 443 lines of Style Guide documentation, which is about half the project. Jose opened a similar pull request against Credo, the popular code analysis tool, removing 12 Style Checks that are made redundant by the auto formatter. So these pull requests weren't meant to be merged. And in fact, since taking the screenshot, they both have been closed. But they were meant to make a statement. And to me, that statement is pretty clear. We don't talk about these anymore. These rules are built into Elixir now. And we have other problems to solve. That is a brief history of this technique bringing us to right now. In the next part of the talk, I'd like to look at arguments surrounding this controversial practice. So part two, arguments for and against. In this part of the talk, I'd like to cover the main arguments for and against making a change like this. You know, it's already been decided for Elixir. Like, we already have the tool. But I think it's worthwhile to consider the implications. Because it definitely won't be the last time that a language tries to make such a pivot. So here's a preview of my arguments. Four, we'll be talking about productivity, consistency, friendliness to newcomers, and execution. And against, I'm calling that but my preferences. And that is the whiniest voice that I can conjure. But we will dive into that in a second. Okay. So argument four is productivity. This is a definition of bike shedding from the jargon file dictionary. Bike shedding. Technical disputes over minor marginal issues conducted while more serious ones are being overlooked. The implied image is of people arguing over what color to paint the bicycle shed while the house is not finished. The implication of this type of idea, I think in this context, is that most style preferences don't matter. Your code has a lot of bike sheds that you can spend a lot of time thinking about and discussing. When you take all those bike sheds away, when you stop arguing about the color of the bike shed, you will have more time to produce. At least that's the idea. Second argument four is consistency. And this is something that Jose talked about in his keynote. Elixir should have a consistent style. And distinct style guides separate us. When you're booting yourself up in a language and you have to choose between multiple style guides, it's hard to know what the best practice is. And we need to have collective ownership of the community's code. We should all feel like we own the major projects in our community, the major open source projects. That's one of the reasons that you would open source a code base to begin with. So Jose brought up an interesting metaphor about consistency that I would like to illustrate. So this is Steve Jobs at the Appokino in 2009. And he's wearing an outfit that he wore a lot, which is glasses, a black mock turtleneck, Levi's 501 jeans, and a pair of New Balance sneakers, which you can't actually see. Jobs was known to have owned hundreds of copies of this outfit, this exact outfit. And he wore it every day, even on really important days like the Appokino. For a simple reason, to eliminate trivial decisions, rather than focus on his appearance, Jobs chose to delegate that to a repetitive system, and instead focus on the huge and consequential decisions that he had to make every day. He was trying to be consistent and as a result be more productive, which I think he definitely was. Okay, a third argument for is friendliness to newcomers. New developers shouldn't have to learn how things are done here on every team. Maybe we can let them focus on onboarding and then learning about your product and contributing as quickly as they can. Elixir code should be exemplary. If we take some elixir code and put it in a snippet and then put it in a book like Seven More Languages in Seven Weeks, which is where I first saw the elixir language, it should look good and it should reflect highly on the community. And feedback on your code need not always come from a human. Perhaps the formatter can handle low level style concerns before an overworked open source maintainer ever has to even see the code. We want more people at elixir days and newcomers feeling welcomed by us and our code conventions is one of the ways that that happens. There's one more argument for this tool and it's specific to this auto formatter which is the execution of this tool, the specific way that it was designed. And here are the guidelines outlining this tool. So it has three guidelines. The first is it does not change code semantics by default. The formatter is not supposed to change what the code does. And there are some safeguards built in to continue to verify that this is true. The second is that it minimizes configuration. I know we have some people who have written Ruby in the room. You might be familiar with a library called RuboCop, a popular auto formatter in linter written in the Ruby language. So RuboCop has many flags that you can turn on and off that change what it cares about. So many that it's usually written into a file called .rubocop.yaml. When you look at a large legacy Rails application, this file can grow to be tens or hundreds of lines long. And that makes it very difficult to know what the gem is going to do when you run the executable. It's very tough to predict. If we contrast that with the config file for the Elixir language for its own auto formatter, it's only 19 lines. So we're shooting for minimal configuration. And third, there are no special cases or few special cases. Every function gets treated the same and nothing is special. So I think just based off these guidelines and exploring the tool, I think it was executed well. And that's definitely an argument for. Okay, on to the main arguments against. The big one for me, I'm calling but my preferences. So decisions made by the Jose of your language community can feel arbitrary. And they can clash with personal preferences that we've been developing for years. I'd like to look at a style concern that to me perfectly encapsulates this dilemma. And that is the trailing comma. Elixir's formatter always removes the trailing comma. And if there was any confusion on whether this is going to change in the future, we have a quote from Jose that there will be no trailing comma ever. So here's a quick overview of this issue. Here we have two lists. They look almost exactly the same, but you can see that they're a little bit different. And the reason that they're different is that in the second list after the two, there's a comma. That is the trailing comma. It's purely a style preference and it doesn't change how the elixir compiles. But it might not be the style that you like. And I think our written language demonstrates why some programmers might not like this style. This is a famous quote from Julius Caesar. I came, I saw, I conquered. So that's I came, comma, I saw, comma, I conquered, period. A collection of three statements. Let's read the sentence again with a trailing comma. I came, comma, I saw, comma, I conquered, comma, period. This is a collection of three statements with a weird kind of confusing character just shoehorned in at the end. If you were to write this down, your victory would probably be overshadowed by people being confused by your grammar. It means generally the same thing, but to some people it feels sloppy and wrong. Well, this is how some programmers feel about the trailing comma in their code. So why don't we just not use them? Well, like everything, it gets a little more complicated. Consider these two lists. If I want to change the code in the first list to the code in the second list, how many lines of code do I have to change? Two. The answer is two. I have to add a comma after the second list item and then I can add the third list item. So I'm actually changing two lines of code when I only really, in my mind, am changing one thing. This seems kind of wasteful. It adds extra lines to my get diff and some white noise I probably don't need in my project. If we're back in the time when programmers were measured by lines of code, I would look like some kind of rock star because I did double the work. But if we always put a trailing comma at the end of every list, then when we add a new list item we only have to change one line of code. Also, if you like to sort the items in your list programmatically, like by alphabetical order, I know some people who like to do that, the trailing comma makes that easier because any order of the items in the list is still valid elixir. You don't have to go and find the thing that moves to the top and put a comma next to it. So does this really matter? Well, as a person who likes to think about style, I don't like the trailing comma. But as a team member and a person who works in open source, I like the trailing comma. It's controversial and one person made a decision. But if we go back to those personal preferences, there's a potential benefit here. And that is if it's successful, it has the potential to end persistent debates. Perhaps the trailing comma debate has been had enough times and isn't worth having anymore. And in defense of this, I offer a quote that I find pretty pertinent in my programming life, known as Eagleson's Law. Any code of your own that you haven't looked at for six or more months might as well have been written by someone else. A lot of my cherished style opinions have changed over the years and I'm pretty sure yours have too. When I look at old code that I wrote, sometimes even a few months in the past, I don't always like the style that I was really attracted to at that time. And sometimes I go back and I change it for aesthetic reasons. So what if we took that randomness out of the equation? What if our code was just consistent and predictable and maybe even a little bit boring? So in conclusion, talking about these arguments, to me I think that there are more and stronger arguments for auto formatting than against. And I consider myself a cautious vote for. Okay, on to part three, practical applications. So at one point in the history of this talk, I was going to cover the setup of the tool. But right now, I think that there's better ways we can use our time. The auto format is now officially released. It's a pretty straightforward tool and like many parts of elixir, the documentation is really excellent. So for basics of using the tool, that's where I would point you. Instead, I want to move straight into practical applications. So there was a cool anecdote from that keynote I've been talking about. The moment that Jose finished the auto formatter, he took it and he ran it against the source code for the auto formatter. And so just code that he had immediately written, he auto formatted. And he was really surprised by how different the code looked. But as he started to read through it, the changes started to feel natural and correct. And in a weird way, he was shifting his own concept of what good elixir code actually looks like. In this part of the talk, I want to try to do the same thing for all of us by looking at some production elixir code in a project called Today I Learned. This is a little bit about that project. So this is Today I Learned. You can see it at til.hashtracket.com. We built TIL in 2015 as a platform for our company to publish short technology blog posts. And we started off by writing it as a Ruby on Rails app. But picked up some interest in elixir and we rewrote it as a Phoenix elixir application last year with the name TILX. TIL plus EX. It was really fun and it was part of why I'm here today. It really made me love elixir and this world. If I was going to describe Today I Learned structurally, I'd say that it's a server-side rendered kind of fancy crud application. Like the Rails app that preceded it. In regards to code quality, I think it reflects that we were all learning elixir, the people who built it with me. We were trying out unconventional patterns. We were trying out some things that maybe had never been done before in Phoenix, at least not somewhere where we could see it. And we were maybe doing some things the Rails way. That elixir and Phoenix both had releases during our development cycle so we wanted to stay on the edge with those and some of the syntax was changing out from underneath us. My point is that the code can be a little inconsistent and that makes it a great sandbox to test out the formatter. Also it's open source so we wanted to be exemplary and approachable to people who want to learn about Phoenix. So we felt that our best way to achieve this was to comply with the formatter as early as we could. In January, we undertook our own refactoring project led by this issue. Autoformat Tilex issue 218. In a couple of days we had auto-formatted the entire project. We decided to do it all at once just as the elixir language had done. Here are a few statistics of this project that we went through. We had 90 total elixir files in the project. 31 of those files about 35% passed the formatter on the first try. So only one third of our entire code base was formatter approved. I was surprised by this. I thought that we would do better. First, a lot of these files were taken from books or perhaps auto-generated by the Phoenix project. Second, the code was open source so there were a lot of eyeballs looking on it. Third, we were already running credo against every CI build. So we were already trying to comply with what we thought was the best practice for style. And none of this was enough to prevent us from having to format 65% of the files in our project. So my conclusion from this experience is that churn is coming. If your project is bigger than ours if your project is older than ours if it's not open source and you run mixed format on your project it's going to change a lot of files potentially. And that might be another argument against but it wasn't enough of an obstacle to stop the elixir language from doing it. So something to consider. What follows are some abbreviated code examples for the changes that the format are made to our Phoenix project. The code on the top is going to be before and the code on the bottom is going to be after. Okay, so this is our post controller. We used a plug function to assign the channels that go with our today learned posts. So we used a plug function and we call load channels which is a function that's defined further down the file to make it conditional when the action is in a list of atoms representing the different actions where we want this to happen. We ran mixed format on this file and it looked like this. It's not really that different. The argument to plug has now been wrapped in a parentheses. Some people call the code on top poetry mode because it's maybe a little bit more fancy or svelte to not have those parentheses but this is what the Elixir format or wants our code to look like going forward. I think this might help somebody learn about plug but in general I'm pretty ambivalent and this was a very common recurring change. A little farther down the post controller we assign a variable that we're going to use to paginate our index page. So we take this page variable which we match on params and then we send that through an Elixir pipe map.get and then through another pipe string.to integer. When we formatted this here's how it looked. So that raw input value params has been dropped down onto a new line and the pipes are lined up with a params keyword. Map.get is the same that line hasn't changed but string.to integer now has a parentheses. And I think that's to make it clear that this is a function call and that what's coming out of the pipe above it is going in there. So I think this is a little bit better to me it's a little more readable and a little clear but don't have a super strong opinion. Further down the post controller we call the render function to render our search page to tell it how to render. We pass it the con, we pass it the connection we tell it what template to render and we assign two variables that we're going to use in the template post and post count. This looked different running through the formatter as well. So this was broken down each comma separated item in that parentheses was broken down into its own line. This is not a change that I have strong opinions about perhaps you feel different. Okay. Still in that same file we haven't even gotten out of this file we have a case statement. So what we're doing here is we're deciding if a post is editable by the person the current user. So we assign a variable post we match that on the case statement of whether or not that user is an admin. If they are not an admin we take the current user we get their associated post and then we look in the repository for that is our target post. If they are an administrator then we look at all the posts. Run that through the formatter and here's what we see. Okay. So we have another new line after the equal sign the case statement has been broken down onto its own line. Then after the false catch after that arrow we go down to another new line. The pipes are lined up with current user I think they were lined up with false before and then not many changes after that. There's a new line between false and true and then there's a line break after the arrow on the true line. Case statements to me is an example of code where there's many different ways that you could write it that would be valid. So to me making a decision is a good thing and I don't particularly feel strongly about it either way but I kind of am happy that the decision is being made and to me this is better than the way that we wrote it. Slightly more readable. Okay. Moving into our router so we're assigning two module attributes here auth controller and cores origin and there's not a lot to see here except you'll notice that the application module name is lined up. I know a lot of people like to write code this way. I definitely have in the past using a vim plugin called tabularize to line these all up and try to make it look more readable. If you run this through the formatter those extra spaces between at cores origin and application have been removed. So I didn't like this when I first saw it but then I started to sit and think about it. So if we have a list of these module attributes that we're assigning and we decide to add a new one that's longer than auth controller then all of those application modules are module names are going to be moved over. Or if we get rid of that or make it shorter and somehow they're all going to be moved over the left. So that has a side effect. Changing the auth controller attribute has a side effect that affects other lines of code and can add to churn. And when you view it through that lens I think that the value is a little bit more debatable. We're prioritizing style right now over potentially having to make unnecessary changes in the future. So although this isn't my personal style I think after thinking about it a little bit it's definitely better. Okay in our config.exe we have a config for Guardian. We are telling it which allowed algorithms it can use for coding and decoding and we're using HS512 and then we have an inline comment that is coming along with the code. When we ran that through the formatter it moved the inline comment on top of the allowed algos key which to me was kind of weird earlier versions of the formatter would take all the inline comments and move them all on top of this this line of code which looks really strange if there's multiple inline comments. I'm not a fan of comments and code in general especially inline comments so this actually brought this comment to my attention I had forgotten it was there. It was probably copy and pasted from Guardian's Read Me. Wherever it came from the idea that this is optional is advice that we took a long time ago. We know that it's optional and we decided to include it so that information is maybe not so useful at this time. So I actually just got rid of the comment. Conclusion here for these changes is I think that these are pretty small pretty forgettable changes that generally improve the code and to me do not make it worse. There are changes that I generally like but there are also changes I would be very unlikely to ever apply on my own consistently. So what's next? We changed all these files we could test deploy and move on but that's really only half the problem the other half is enforcement because if somebody adds a new file to change these files all these pull requests all that churn that we decided we were going to accept turns out it was for nothing. So how do we make the changes stick? For Tilex we went with a CI integration so we're using CircleCI and once we installed Elixir 1.6 on our CI server we added this step. It's around the same time we were running our tests. So we add the mix format step with the flag check formatted. So mix format is the baseline command to format everything but the check format flag is there because that checks to see that the code base is already formatted. If that fails then the formatted contents won't be written to disk or printed to standard out. So if you try to push to our project or you open a pull request we have it on pull request as well and mix format everything that it needs to change then the build is going to fail. So if you want to contribute to today I learned you have to format your code with the auto formatter. That's the decision that we made. So now we're in four second on CI just the same way as Elixir is doing but more important to me is how do I keep people from pushing red? It's not fun to push red to an open source project you want to contribute to. How do I prevent that? This is what I have set up on my machine right now it's very basic but it's for Vim I have an automatic command on bufferite post any time a buffer is written after that if the file matches EXS or EX silently go into command mode with a colon shell out mix format and then pass the check equivalent flag and do all of this on the modulo which is the current buffer. The check equivalent flag is pretty cool it checks to see that the abstract syntax tree before and after running the syntax the formatter has not changed to make sure that it's not changing what the code actually does as Jose was trying to accomplish. I believe that this tool has been integrated already with a lot of the popular formatters that are out there right now and that type of adoption is going to be really important. When you look at GoFump it's integrated with every text editor and version control system that's out there and I think that's where an idea like this lives or dies. It's not fun to push red and automation can help us to prevent that. I hope that this part of the talk has shown what the formatter does and given you some ideas about how you could integrate it with your own project. To wrap up my thought is that you should format your code and we've looked at a history of auto formatting that this can be done on an open source project. We've talked about arguments for and against and I think there are more arguments for than against. We've seen some practical applications and seen that you can actually set this up right now. There's another reason to use this tool as well and that is new auto generated code and code that you bring in from dependencies are likely going to be using the auto formatter. By using it yourself you're going to have some harmony with those projects and you're not fighting against style that is going to be part of those products that you bring in. That's why I say format your code, integrate it with your text editor and your CI. My larger point here is that we are more than masters of the bike shed. We are more than pedantic memorizers of style conventions. We are builders and we should focus on building cool things. That's what I came to Elixir Days to talk about. I hope to talk to some of you more afterwards if you share that passion. Once again, my name is Jake Worth. Thanks to Elixir Days and thank you all for your time. So I guess I just wanted to ask are there processes in place for the Elixir community to modify the style if that's not serving the community well? Because I understand preferences are neither here nor there but some developers might be dyslexic and line breaks are necessary for understanding that stuff and so that can actually make developers leave. It's not that they have preferences but they actually can't code anymore if the code becomes illegible to them. Do you know if anything's in place at this time for the community? That's a great question. The accessibility of this tool is not something that I had considered until right now. So thank you for bringing that up. Elixir does somewhat have to me a feel of the benevolent dictator for life spirit where we have a very involved, passionate lead maintainer and I don't know at this time how receptive he is to suggestions for changes but I would encourage anyone who feels that way to pursue it through the GitHub Elixir repository because I think that stuff's really important. Okay, well guess what? Thank you, Jake.