Aaron VonderHaar shares the origin, history and plans for the future of elm-format and a new, related tool!
Thank you to our sponsor, Culture Amp.
Special thanks to Xavier Ho (@Xavier_Ho) for editing and production of this episode!
Recording date: 19 Mar 2020
- Aaron VonderHaar (@avh4)
00:00:00 Intro and sponsors
00:04:22 How Aaron got into Elm
00:06:09 The origins of elm-format
00:12:15 Avoid configuration options
00:15:53 elm-format's evolution
00:17:50 elm-format's parser
00:20:33 Auto-correct syntax errors
00:21:55 Learn Elm with elm-format
00:23:41 Major “internals” projects
00:25:30 elm-refactor coming soon
00:32:03 The Elm version flag
00:35:06 Controversial formatting
00:41:08 Where changes in elm-format come from
00:47:05 Still beta
00:49:00 Inclusion in Elm core
00:51:12 elm-refactor coming soon (continued)
00:52:50 Teaser: elm-program-test
00:53:54 Sign-off and Outro
[00:00:00] Kevin Yank: hello, and welcome back to Elm town. It's your old friend Kevin, and I'm here today with Aaron VonderHarr. Hi, Aaron.
[00:00:07] Aaron VonderHaar: Hi Kevin, how's it going?
[00:00:09] Kevin Yank: Very good. Good to have you with us. Aaron is, if you don't know the name, the author of elm-format and, I think, a lot of listeners will be perking up at that because I have yet to meet someone who doesn't love elm-format. After using Elm for a little while.
[00:00:27] So I think we'll have a lot to talk about today. Before we get into that though, as usual, I want to acknowledge our sponsors, Culture Amp. They pay my bills and they are letting me record this in the middle of a work day. So thank you, Culture amp. You've probably heard of all of this by now listeners, but as you may already know, we make a web application that businesses all over the world
[00:00:50] we're talking 2,500 plus companies now around the world, use our web application to collect feedback from their employees,
[00:01:00] to run their performance reviews and to mush the data that comes out of those things together in order to understand their people, their culture, how people are feeling about work and, and how to improve their workplace.
[00:01:13] that's a mission I am very excited to be writing software for. And if you would like to write Elm in production on that kind of web app, you should reach out firstname.lastname@example.org is my direct address. Or you can visit cultureamp.com/jobs in order to see what roles we have open at any given time.
[00:01:32] And also thank you to Xavier Ho, our producer who makes us sound great by cutting out all of the mistakes and trimming the boring bits from these episodes, so you get the very best Elm Town that we can make, dear listener.
[00:01:47] Aaron, welcome to the show!
[00:01:49] Aaron VonderHaar: Thanks for having me.
[00:01:51] Kevin Yank: for those who might not be familiar with you or might not have heard your story before, tell us about yourself and what led you to Elm.
[00:02:00] Aaron VonderHaar: Sure. well, let's see. When I first was getting into programming, I really took an interest and kind of had some mentors that got me interested in user experience and kind of that aspect of development, but web development was kind of the big thing when I was getting out of college.
[00:02:17] And, I did a fair amount of that. I did a lot of mobile app development after the iPhone came out and, did some, a lot of big work for some Android projects.
[00:02:27] Kevin Yank: Are we talking about native apps for those platforms or still on the web?
[00:02:31] Aaron VonderHaar: Yep. Native apps. Actually, I did one project for this Android phone. I was actually in charge of the team that was re-skinning and developing new core apps that were going to be shipped with the phone itself from the manufacturer. I've done a lot of Android and iOS stuff. But yeah, I eventually ended up doing some consulting work at Pivotal Labs and started doing more web development there and I guess got interested in Elm…
[00:02:57] …kind of on the side. I started going to the meetups in San Francisco, got to know Evan and Richard Feldman…
[00:03:03] and got more and more interested in it. And eventually when I started looking around for a new job, NoRedInk was looking for people to do more Elms. So I ended up working on Elm almost full time, at NoRedInk, after that.
[00:03:17] Kevin Yank: Pivotal Labs was one of those names that, when Culture Amp was first looking at Elm and you know, you do the thing of, well, who else is using it? And NoRedInk was obviously on the list, but, Pivotal was one of the early big names, I would say that, you know, they were on the Elm website…
[00:03:35] …there were one or two people from Pivotal who had given talks about stuff, that they were doing there or had open sourced projects. Were you exposed to Elm at pivotal at all?
[00:03:47] Aaron VonderHaar: I think I was the one that did a bit of the exposing. I'm trying to think back. We did a project, I think for Twitch where we used a bit of Elm, and I had actually brought Richard in to do a lunch talk for a few people who were interested in it.
[00:04:00] I think the next thing when they started using it for was the front end for the Concourse CIS system.
[00:04:06] And later, I think, I believe it's now used in Pivotal Tracker itself. But yeah, I definitely heard about it outside of Pivotal and started talking about it with a few people there. We had like a functional programming club where we would talk about Haskell and then other functional programming languages like Elm.
[00:04:22] Kevin Yank: So tell me about how you got into that FP stuff, cause I do find there are two kinds of Elm people. There are the people who got into FP first. And then Elm was a cool way to, to stretch their FP muscles. And then there were the people who got into Elm first and then realized they had to learn some FP in order to use it effectively.
[00:04:41] Aaron VonderHaar: Yeah, well, I would say Java was my language of choice before Elm. I guess largely because a lot of the great, IDE integrations and tooling and automated refactoring stuff that you can do with Java. So I'd say I was aware of functional programming, but had never really used it much, professionally, other than playing around with it.
[00:05:03] And, kind of following. Or just reading interesting articles. Actually, the talk that I mentioned however long ago, at Strange Loop that Evan gave was kind of about the nature of functional reactive programming that was back around like Elm 0.15 or something like that.
[00:05:20] Over the years and hadn't really found anything that was good for like a work environment until Elm came along. But yeah, I was definitely in the, object oriented worlds, not the functional world until Elm, and didn't really know any Haskell until after I started working on elm-format.
[00:05:41] Kevin Yank: Right. Okay. So the, the FP club came later.
[00:05:45] Aaron VonderHaar: We didn't really have any advanced functional programming practitioners. There were actually some guys from Walmart Labs who were working out of Pivotal's office for a while and they used Haskell. So they would occasionally stop by and, and, give us some pointers on how to learn Haskell.
[00:06:01] But that was kind of more just an educational thing. Nothing that we ever really brought into our work for any of the Pivotal clients that I worked with.
[00:06:09] Kevin Yank: how long were you working in Elm before elm-format started to be an itch you wanted to scratch.
[00:06:16] Aaron VonderHaar: Yeah, that's a while ago. Let me try to remember here. I definitely started going to the meetups, kind of more heavily than having any big project in Elm when I was first playing around with it. So I was interested in kind of more just toy experiments rather than building any particular side project in Elm.
[00:06:38] I think I probably was going to the meetups for maybe six or eight months, maybe even a bit longer before I wanted to start doing something bigger. I guess my motivation for choosing elm-format as a project was that I was really interested in editor tooling, like I mentioned, as something in Java that appealed to me.
[00:07:01] And I thought Elm format would be a good opportunity to get familiar with how the Elm parser worked and how the compiler worked, without really having to commit to like maintaining the compiler itself. But I could learn something about the parsing, and have a useful product that other people could use as a side effect.
[00:07:20] Kevin Yank: Right, right. I'm less interested in the specific timelines, but it's more what you're getting at there is that not everyone's first reaction when picking up a new language is how can I make the tooling better?
[00:07:33] Especially for something like Elm where the compiler and the tooling around it was already considered at least at the time, to be quite cutting edge…
[00:07:43] …and quite a highlight for it. most people would go, okay, I've got this new language. It's a toy. I want to play with it. Let's start building things. It sounds like you very quickly kind of gravitated towards a sort of meta project where you would get to learn about the thing by helping to build the tools for it.
[00:08:00] Aaron VonderHaar: So one of the things that attracted me to Elm in the first place was similar principles, like the idea of the usability of tools that developers use in their daily work. Especially coming to the meetups where I got to talk to Evan a lot, back in those days
[00:08:17] one of his core interests, especially at the time, was really looking at the experience of people trying to use the language and almost like doing user interviews with them, seeing what they struggled with and trying to solve problems. I'm a big example of that was when Elm went from using signals back in 0.15 or 0.16 to the current Elm architecture, which everybody knows now.
[00:08:43] The big project of Evan’s to understand, like, what was it that was confusing about signals and made it hard to understand and how could that be solved potentially in a, in a drastically different way, which turned out to be the case there, but make it a lot easier for people to understand, especially for web developers to understand.
[00:09:30] it's kind of been like a common thread for me.
[00:09:33] Kevin Yank: is it a part of it that Elm is a simple enough language that contemplating writing your own parser for it, it felt within reach in a way that it didn't usually for other languages?
[00:09:44] Aaron VonderHaar: Yeah, I think that's definitely the case. And having used the language as well, the syntax of Elm is relatively straightforward. Like there's a lot fewer weird edge cases, and weird syntax in it, as a language. So, yeah, I think that was part of it.
[00:10:00] Kevin Yank: So did you go straight to the idea of an auto formatter? was that like immediately a need that you perceived and it was the inspiring idea that you were pursuing from the beginning or did you go through several iterations of interests before you landed on elm-format?
[00:10:16] Aaron VonderHaar: That's a good question. My memory from then is kind of fuzzy, but Evan and Richard and I were talking fairly often and were having a few lunches, and I can't remember, it might even have been Evan or even Richard who thought that it was a good thing to have in the Elm ecosystem. And one of them had written up a Google Doc kind of listing the rough idea of what it might do.
[00:10:42] gofmt was around at the time. So the idea was kind of based on that, that it would be basically no configuration, and kind of one way to do things. At some point, yeah. I think that the idea just appealed to me. I was kind of looking for a bigger project to do and I jumped on it and started flushing it out, started building it, started working on it in my spare time, and went from there.
[00:11:05] Kevin Yank: I'm not familiar with gofmt. I would say apart from elm-format, the big auto formatter that I'm aware of that most people will have now heard of is Prettier. And at least as I experienced it, Prettier came after elm-format. But can you talk about what was inspiring about the prior art of gofmt?
[00:11:22] Aaron VonderHaar: Yeah. First of all that it was a blessed tool of the official Go tools, and I haven't actually followed it that much in the recent years. So I don't know what has changed since then, but the appealing aspects were that it was an official tool supported by the core Go organization, or I don't know how they're organized, also that it didn't have configuration options.
[00:11:48] So there was no customization between projects. And part of that was because it was an official tool. Basically every published Go package, I believe, was, supposed to have their code Go formatted so that any Go code do you looked at, would follow the same conventions. So that was an aspect of it. And the other aspect of it was trying to do the right thing without
[00:12:15] getting in people's way. So that's a big thing I've tried to do in elm-format is not have configuration options, but also as much as possible, make everything you type format in a reasonable way without having tons of different choices for you as the person typing the code.
[00:12:33] Kevin Yank: What's an example of a choice?
[00:12:34] Aaron VonderHaar: One thing that elm-format is restrictive in is if you have a function call and you have the name of the function and then you have a bunch of arguments, each are separated by white space, there's a choice in those white spaces of where do you put line breaks? Do you put a line break between every item between some of the items?
[00:12:53] Do you try to group certain items with line breaks? So elm-format is extremely restrictive. In that there's now three options. You can either have all the arguments on the same line as the function call. Or you can have the function name and the first argument on the same line, and then everything else is on separate lines.
[00:13:13] Or you can have all the arguments on separate lines. So those are the only three options. So there's no choice to, for instance, like have the first argument on a separate line, then have the second, third, and fourth arguments on a line together, and then the fifth argument on a line. So that's an example of
[00:13:30] a choice, like it's restrictive and that you can't control how it formats in some sense, but it also removes the choice, so as you're typing code you over time, learn to not even think about it, not spend time thinking on it. You just type it out, let it get formatted and move on.
[00:13:47] Kevin Yank: if you are imagining more flexibility there, apart from like leaving it in the author's control, which things are grouped on one line or not. I mean, there's other things like how indented are the function parameters, are they all lined up with the first one?
[00:14:02] If the first one's on the same line as the function call? Yeah, I can see all of that. so reducing the number of things, I imagine it makes your job easier as the author of elm-format?
[00:14:14] Aaron VonderHaar: I guess so. I mean, one of the interesting things is that I've kind of, I've tried to drive those design choices by the code implementations. So I've really developed elm-format in kind of a test-driven way, where I've made it essentially do the simplest thing possible first, and then as we've discovered cases where that format really doesn't make sense…
[00:14:41] First of all, I've, I've tried to make a pretty high bar of pushback and say like, okay, let's make sure that this is a really common use case before we start adding special cases to the formatter. And then once it is, let's look at where does this structure of code occur the most often in real world code and what formatting makes the most sense for the most number of cases where this type of code would occur in the wild, and kind of optimize the design of the format for that.
[00:15:14] and from there, I've written, I don't know how many hundreds of test cases for elm-format where it's basically an input file and the expected output file. So, building over time. It hasn't really been hard to maintain because of the way I've done that, but if there's been a choice about formatting, I've tried to have the initial version do whatever formatting is simplest to implement given
[00:15:42] how everything is currently factored and see how that works out and if it doesn't work out, then kind of intentionally design a specific format for how that code appears in the wild.
[00:15:53] Kevin Yank: elm-format's been around long enough now that I imagine you are probably much happier with the current version of it than you were with the initial version of it.
[00:16:01] Can you talk about some of the things that were janky earlier in the life of elm-format? Some things you're glad are now left in the past, or even some lessons learned, mistakes made?
[00:16:14] Aaron VonderHaar: The first things that come to mind are things that are still janky, which we haven't implemented yet. The single line if statements, so it still breaks if statements out onto like five lines even if they're really short. Huh? Let me think back. I think actually, I've, I've been relatively happy with even the initial versions of elm-format.
[00:16:37] And actually in the test suite still, you can find some really old Elm files that I copied in from some open source libraries from probably Elm 0.15 even, where I put some real code in there to make sure that when I ran elm-format on some real files, that the results was at least, well usable, certainly, but also better than what was there before.
[00:17:06] So, yeah, I think for me, elm-format has been pretty usable almost from the beginning and has just been incrementally improved. One pain point is when a new version comes out that has some changes to the format, how do you apply that to your repository that has 40 people working on it, and they all have different branches in Git that all need to get merged.
[00:17:30] So that's kinda been a challenge to deal with. But for elm-format itself, I've actually been surprised about how stable it's been to work with over time. I've been glad that I chose to write a very comprehensive test suite for basically every new formatting rule I've added. Cause that's really helped avoid issues with bugs and regressions happening.
[00:17:50] Kevin Yank: What is elm-format written in?
[00:17:53] Aaron VonderHaar: So it's written in Haskell which I started mainly because I forked the Elm compiler in the beginning, and that just ripped out everything that wasn't related to parsing, and started from there. And it has diverged drastically in the meantime, but that was the biggest reason to write it in Haskell.
[00:18:11] Kevin Yank: So that was going to be my next question. Did you find yourself writing or implementing an Elm parser from scratch or were you able to reference the compiler’s implementation? It sounds like you grabbed the compiler's implementation and ran with it.
[00:18:25] Aaron VonderHaar: Yeah, the biggest shortfall of the compiler's parser, which works great for the compiler, but for elm-format's, purpose, we need the comments and the whitespace information to be retained.
[00:18:41] So that was the biggest change initially that I had to do to the parser was to kind of modify the abstract syntax tree to track all that information and make it available for formatting.
[00:18:53] Kevin Yank: And I can imagine keeping that code base in a state where you could then consume further developments to the official parser probably was off the table pretty quickly then.
[00:19:04] Aaron VonderHaar: That's interesting actually. So most of the parsing files that define the parsers are still quite similar, or when I've had new changes to the syntax and the official Elm compiler, they've been relatively easy to fix up. But the big issue has been, I think in Elm 0.19 or, I forget which version exactly.
[00:19:29] Evan rewrote the entire, underlying library or— The old parser used to use this Haskell library called parsec, and Evan basically wrote his own new parsing library that's a lot faster, which is one of the reasons for speed gains in one of the recent versions of Elm.
[00:19:48] Kevin Yank: That sounds like an Elm 0.19 thing to me.
[00:19:50] Aaron VonderHaar: Yeah. So that new parser, has still not made its way to elm-format. I've kind of talked with Evan and made a strategy of how I can basically write an adapter layer, that implements essentially the parsec API on top of Evan's parsing library. And then I can just swap that in and then over time, migrate the rest of the code to use the new parser directly.
[00:20:18] But that's going to be a big project and it's something that's kinda been on hold because I've ended up having other big refactoring projects within elm-format that I've wanted to do to the code. So that's still a big pending project that has been on hold for a while.
[00:20:33] Kevin Yank: Okay. Are there any other kind of interesting major features of the internals of elm-format?
[00:20:41] Aaron VonderHaar: Well, there's one of my favorite features is that there are certain syntax errors that elm-format will correct automatically.
[00:20:50] And one of my favorite things is pairing with someone and they make one of those mistakes and it gets fixed and they don't even notice. The biggest example is if you mix up colons and equal signs, either in a record expression or in a record type, it'll fix those to the right ones.
[00:21:08] Kevin Yank: Yes, and becoming aware of those, suddenly it's like you have a third hand to help you type. It's you— You realize, okay, I've just defined a record type. Now I need to write an initializer, like for the default value of it, I can just copy, paste and save and it'll change all of my colons to equals signs for me.
[00:21:29] Aaron VonderHaar: Yup. Exactly. Yeah, so that type of feature is something I'd, I'd like to add more things like that. For instance, when you paste that, if you have arrows for type functions, those don't parse correctly. So maybe doing something with those. Also, like removing things like trailing commas, and what are some other good examples?
[00:21:50] Oh, fixing indentation of case expressions, is another good one.
[00:21:55] Kevin Yank: My favorite thing early on about Elm format was not anything to do with, you know, getting consistent code formatting or anything like that as a learner of the language Elm format was my first feedback on whether the thing I had just typed made any sense at all. Like was it syntactically correct?
[00:22:15] Because if the formatting snapped into place, it was an immediate, instant feedback that yes, you did something right. You typed the Elm correctly, and it was like just a squirt of serotonin of “Good boy. You did something well here.” And that, for me was my first kind of, experience of the developer delight in the Elm ecosystem.
[00:22:38] So it was even before my code got to the compiler, it was elm-format that was telling me, Nope, try again. Nope. Try again. Yes, you did it!
[00:22:47] Aaron VonderHaar: Yeah. That's great to hear. that's an interesting, because basically all editors and tool plugins make use of, so it's something that's consistent across editors. Whereas other things like getting syntax errors highlighted, kind of have a different experience across different editors.
[00:23:05] Kevin Yank: It was nice to have the two tiers of feedback as a learner where it would say, no, that's not quite right. And if you want to know what you did wrong, you can go and read the compiler output. Or if you want to challenge yourself to realize what you did wrong and try and fix it yourself, you can just keep
[00:23:21] tweaking and saving and, and try one more thing to see if, if elm-format is happy, and at a certain point you go, okay, I give up. Tell me, compiler, what did I do wrong? But it was nice to have that quicker feedback loop of, “Oh, I'll try one more thing. I'll try one more thing. Oh, I got it right by myself!
[00:23:38] “I've learned something.”
[00:23:40] Aaron VonderHaar: Yeah, that's great.
[00:23:41] Kevin Yank: Let's see. Where were we? We were talking about internals.
[00:23:44] Aaron VonderHaar: Oh, yeah. Well, so there's a few big, big projects within Elm format. Adopting the new parser code is one that I mentioned. Another that's been going on has been having a way to transform Elm source code into JSON files and back and forth. And the idea for that is that it would allow elm-format to kind of be
[00:24:11] a translator or a reusable parser where you can turn your own files into JSON, you can write tools in what other language you want to transform the JSON and do whatever kind of fancy code transformation or linting that you want to do, and then turn that back into Elm code if you want to.
[00:24:30] Kevin Yank: Would the JSON be kind of like a static version of an AST?
[00:24:35] Aaron VonderHaar: Yup, exactly.
[00:24:36] So that's something that's been in progress and I've been trying to make the JSON representation of the AST be something that is easy to modify without making modifications that produce invalid code. So that's been kind of an interesting project. And another kind of internal feature that elm-format had when Elm 0.19 came out is that I wanted to
[00:25:03] experiment with the ability to automatically upgrade code. So in Elm 0.19, there were a bunch of changes to like the core library, the Http library, the Html library. So I started writing some code hidden in elm-format that could basically be an upgrade mode that would transform your code from the old API to calling the functions correctly in the new API.
[00:25:30] And I've been continuing to kind of expand that, and I'm actually going to be spinning off a new tool currently called elm-refactor. You know, creativity in naming for Elm.
[00:25:41] and the idea for that is you'll be able to define definitions of how to upgrade code. Say if you're working on a library and you have a major version change, you'll be able to write an upgrade definition that will allow elm-refactor to automatically upgrade people's code from the old version to the new version. So that's something that's getting close to working. We've been using it a bit within NoRedInk for some UI style guide upgrades. And, I'm hoping to get it ready for people to beta test, in a month or so.
[00:26:16] Kevin Yank: Is the Http 1 to Http 2, is that kind of like an example of the ambitious version of what you are trying to solve for?
[00:26:24] Aaron VonderHaar: Yeah. I think that would definitely be the ambitious one. Actually one of the weirder ones in Elm 0.19 was in Html where style attributes went from taking a list of styles to being a single style, which is now you have a list of items at the attribute level. So kind of doing that transformation was one of the weirdest ones where you have like a single expression that in a certain context now becomes a list of expressions that have to be spliced into the containing list.
[00:26:53] Kevin Yank: It's just tedious enough that you don't want to do it by hand. The thing we had to do a lot of, in our transition to Elm 019 was top-level destructuring in Elm modules where at the top level of a module instead of saying function name equals you would actually
[00:27:10] have a tuple or a record destructure and saying the function returns two values in this structure, and you can reference those names elsewhere in your module. And that was a feature that was removed in Elm 0.19 and we were using it for our style sheets integrations.
[00:27:27] So a CSS module would return a className function, a classList function, and a third one. And you could, you could grab any one of those from the top level declaration. So every single CSS module in our code base, we had to manually convert to three separate functions, which, return a field of the styles function.
[00:27:51] Aaron VonderHaar: So, yeah, that's the type of thing where being able to convert your files to JSON, transform them and convert them back, could allow people to build quickly, hopefully some custom tools to do whatever they need to, transform a huge code base.
[00:28:06] Kevin Yank: Yeah. I wanted to ask you that. What is driving that desire to be able to have that JSON representation to do transformations on? Are there specific use cases at NoRedInk that are driving that, or is there some particular tooling you have in mind for the Elm community that you'd like to enable?
[00:28:24] Aaron VonderHaar: Yeah. I think this comes back to tooling for Java where there's still a lot of things I miss from doing Java development, specifically automated refactoring tools. Elm tools have a bit of support for things like renaming things. But there's a lot of other interesting tools like introduce a parameter to this function and across your code base, set this as the default value, as an example, or select some expression in the body of a function and say, extract this expression to be a parameter to the function, or extract this to be in a let block, or take a particular definition and inline it to everywhere that it's used.
[00:29:09] Those kinds of transformations are the type of things that I constantly find myself missing from using Java, for instance, and figuring out a way to provide tooling authors the support that they need to be able to quickly develop those features. Cause the problem right now is if anyone wants to implement any of those, they first have to implement a parser.
[00:29:58] be available to just convert code into a safe data structure that can be easily parsed in whatever language you want to write further tooling in, then that would really open the door for people to write more advanced tooling or even custom tooling specific to a project.
[00:30:15] Another example for the elm-refactor tool that I mentioned: it looks like one of the options that I want to add to that is being able to normalize your imports across the code base. So you'll be able to say something like, refactor import Maybe, for instance, exposing some specific things. Html, for instance: say you can say, import Html exposing everything, and then it'll be able to go through every Elm file in your project, change however those files import Html to match the way that you specify, and then also update all the references throughout the file where it uses something from Html, and if it used to be Html.div, but now it's exposing everything in the import, it'll just change it to div since it can be accessed directly. But also have the tool be smart enough to know that, oh, if something else is in scope defined locally called div, it's not going to change that cause that would break your code.
[00:31:17] Kevin Yank: Yeah, right. Wow. So it's like kind of managing a virtual global namespace across your code base.
[00:31:25] Aaron VonderHaar: Yup, and especially apply consistency when you have a large team of developers that having the details of how you expose each module on those habits are kind of not worth spending time on trying to communicate it across a large team. But if you have a tool that can do that automatically, it'll make things nicer and make a problem of communication about the fine details of a style guide go away.
[00:31:50] Kevin Yank: And save those dozens or hundreds of times a day that an engineer in your team needs to scroll to the top of the module and go, how was that imported again?
[00:32:00] Aaron VonderHaar: Yup, exactly.
[00:32:02] Kevin Yank: Amazing.
[00:32:03] There was a certain point at elm-format where you needed to introduce a version flag so that the invocation of album format would tell it which version of Elm it should be targeting.
[00:32:15] can you talk about, you know, what pushed you over the edge to need to do that? And what was involved in implementing that?
[00:32:22] Aaron VonderHaar: Yeah. So that is still there actually. It's just that now, almost everyone's using 0.19, so that's the default. And also, with some contributions from some other people, like Martin. There is now some automatic code to try to guess what version it is, and if it can't figure it out, it'll ask you to specify it.
[00:32:43] But that's still there. That is because there were some incompatible syntax changes between certain Elm versions. I can't remember if I had to add that in 0.17 but certainly in Elm 0.18. It was actually the way characters are escaped in strings is different. So I think that was the main feature that kind of forced me to add it because I wanted to be able to just parse the file, irrelevant of what version of the language it was as much as possible, and then only when we format, based on what version we wanted to output, escape things in the correct way. Because the AST itself isn't different for representing strings; it's just how they're represented in the in the output file.
[00:33:36] Kevin Yank: Did that have negative side effects on the internals? Like was there a splintering of, the code that supports old version of Elm versus the code that supports new version of Elm, whereas before there was just a single implementation?
[00:33:50] Aaron VonderHaar: It's actually been surprisingly smooth. The worst part about it is that I have an ‘elm’ parameter that I've had to thread through a bunch of functions, but that's basically been the worst of it. I just thread that through where it needs to go and then case on it and then do the correct thing. There's only really minimal differences between how things are formatted. For instance, like there used to be direct syntax for range expressions, and I basically parse that into the AST and when we print it, I check the Elm version and if it's after Elm 0.18, or whichever version it was removed in, I just print it out as a call to List.range with the two parameters. And if it's still Elm 0.17, I print it with the square brackets and the two dots. So it's been surprisingly simple to maintain, and actually it's been more of a pain to remove old versions. Actually most of them format still supports Elm 0.16. I did actually remove that as an option from the command line tool recently, but most of the internals still support all the way back cause it's just been easier to keep maintaining it than to go through and remove it.
[00:35:06] Kevin Yank: one of the things you talked about was that the importance of a tool like this, having no configuration options that it is the standard and the benefit of accepting that and shortcutting all of those potential conversations and hand-wringing over configuration is, way greater than the cost of adopting any one formatting decisions you might not, you might not agree with.
[00:35:32] what aspects of the formatting that Elm format does felt like. You know, easy and uncontroversial. What aspects feel a little more controversial? what do you still get feedback about to this day that people are grumpy about?
[00:35:46] Aaron VonderHaar: Yeah, that's been interesting. And, I think kind of the incremental approach of adding features that I described before has educated that a lot.
[00:35:55] Certainly the most controversial thing currently and still is the amount of vertical spacing. That kind of means a couple different things. One is the spacing between top level definitions, which is something that was one of the big things that Evan talked about when I
[00:36:17] first was going through ideas. And for him, like, what made code readable – cause he's been designing the language with a particular way of reading it and a particular way of writing it in mind – so that's one of the things that came from him early on. And, I mean, it's something that people bring up, but as also something that I've been trying to watch for.
[00:36:40] Where does that actually affect and cause a real problem for people? Like, okay, it's very common to have a lot of stuff on the screen that you need to see all at once. But I haven't been able to find good use cases to support changing it. So that's something that stayed. One of the big controversial items was the indent level.
[00:37:03] Two versus four spaces, and it's actually something we experimented with both ways. If you've used elm-format for a long time, there were different versions with each.
[00:37:13] That's another thing where, I mean, occasionally you get people who come to Elm and they want things a certain way and they complain about it.
[00:37:22] But in pretty much every case I've seen when people start using it, they get used to it and it's, it's not a big deal later on. And actually I did hear from one person who was like, “Hey, my company says that all code must be indented with two spaces. How do I configure that for elm-format?” But I said, well, you can't configure it. This is just the way it is. And he was like, “Well, okay, great. I'll tell that to my boss and we'll use four spaces.”
[00:37:52] But yeah, I mean, that's something where there's always going to be debate, but I feel like luckily I'm someone who isn't bothered by a lot of criticism and I feel like I'm capable of looking for what merit there is and keeping that in mind and thinking about, okay, are there changes to the formatting I want to try making or experiment with, or do some research on and consider it and make the choice.
[00:38:22] And it's kind of like my responsibility as the maintainer of elm-format to do that assessment. Not get stressed out by people having different opinions and making a choice. And an interesting thing to keep in mind, I think, is that while there are people who are vocal about not liking a certain way a certain thing formats, there's a lot of other people who are perfectly happy with the way it is and get a lot of value out of, for instance, having a single unconfigurable tool that just does everything without having to worry about it. So you have to keep in mind that people who are happy with the way things are, and it's kind of my job to help protect that as well and make sure that the tool doesn't evolve into something that becomes painful to use down the road.
[00:39:11] Kevin Yank: So you're saying you have to remember that silent majority is there, even if they're not always telling you.
[00:39:16] Aaron VonderHaar: Yeah, and it can be kind of hard to assess that cause you don't interact with most of the elm-format users day to day. And if they aren't interacting on the GitHub issues or via other means, then it's hard to know what they want, but you know, I try to do my best.
[00:39:32] Kevin Yank: You were talking about the vertical spacing and the horizontal indentation, like those two things are not disconnected. I imagine if something, if code is very vertically spaced, then if it weren't also generously, horizontally spaced, then it would look a little out of balance.
[00:39:49] To what extent do you feel like you are making decisions based on aesthetics versus technical considerations or some other benchmark of success?
[00:40:01] Aaron VonderHaar: I would say that aesthetics would not be a concern, but the related concern of usability would be. I think if, for instance, I had evidence that a certain formatting choice, for instance, reduced the cognitive load for people reading it or made it easier to parse or, within a certain block of code,
[00:40:28] what are the important things to notice when you're looking at it for the first time, or when you're scanning it, when you know something's there and you're trying to find it, like what formatting makes it the fastest and lowest cognitive overhead to find those things? I think those would be good reasons, in my opinion.
[00:40:46] I mean, I haven't gone into that much depth on a lot of things, but certainly if there was some big controversial choice, and maybe over time I'll have more time to think about those usability aspects of some of the formatting and make changes based on that. Those types of concerns would be valid to me,
[00:41:03] but I'd say aesthetics independent of that hasn't really been a concern.
[00:41:08] Kevin Yank: I was wondering if we could drill in on a particular change that was made relatively recently in the life of Elm format and discuss, you know, what led to it, why it was made, how successful you consider it. The one that pops into my head, I don't know if you have a better example in mind, is the way let-in blocks were indented differently at a certain point for— I feel like for a long time,
[00:41:32] the body of the in was further indented from the in and then a certain point it got out dented. You know what leads to a change like that? What would conversations started it?
[00:41:44] Aaron VonderHaar: So that's an example of, a change that was motivated by kind of a core principle of elm-format. So even early on there was a list of five or six things, and I still in the elm-format README near the top. I don't have them memorized, but the one that was relevant here was that we wanted to minimize the noise.
[00:42:08] When you are diffing files. So like when you have a version control change, we want to avoid unnecessary changes to lines that aren't actually affected by a change. In the case of the let block indentation, that was basically the reasoning behind it. if you have a body of code, or the function body of some function and it exists,
[00:42:32] and then later you're going to refactor that code and extract some local variable, that variable has to be defined in a let block. So you're going to have to add a let block to a body of code that was already there. And in doing that in the old way, that would mean that the code that existed there before has to get indented,
[00:42:52] which by default in most diffing tools is going to highlight those lines as being changed. Certainly there are options in diffing tools to hide white space only changes. But given that that's not the default in most places that people are viewing diffs, making the change to have the in body of the let blocks not be indented means that if you add a let block somewhere, it's not going to
[00:43:18] cause the diff tools to by default highlight everything else that's inside there that didn't actually change other than some new variable is now referenced.
[00:43:28] I think it was made in an experimental version first to try out and see what it felt like for use in the real world.
[00:43:36] but I do also remember that, I was kind of tracking my own experience and other people's before making that change, as to how often that happened. And I did find for myself that I would quite often make those kind of changes and see that happen.
[00:43:54] Kevin Yank: Can you recall whether for this particular change or more generally, do ideas like these generally come from the community and flow into your process? Or are you dreaming up these improvements yourself based on your own experience most of the time.
[00:44:07] Aaron VonderHaar: I'd say it's about 50/50. So the GitHub issues page for elm-format. I'm happy if, if anyone drops any ideas they have, I'll tag it with the discussion label on there. So there's a huge list there. I probably tend to go back to things that people brought up, like years ago, even if they don't even follow it anymore.
[00:44:30] So there are a fair number of those. My time that I have available to invest in elm-format varies a lot, month to month and even year to year. But there are a large number of those, and I try to get through them over time and, mark them for particular releases, and when I'm going to get to considering them.
[00:44:50] And then there are a lot of things that just come from me. But I would say most of those are not controversial. Those are more things that are just such a small detail that no one else is even bothering to think about it. An example being like the colon and equals, automatically fixing that was something like, I was in the code. I was like, oh, that would be really easy to implement, and I bet that would help. So I tried it, it worked. But that's something that probably no one else is gonna be spending the time thinking about in detail to even to think to suggest it.
[00:45:21] Kevin Yank: For me, a recent, discovery in elm-format that delighted me was the auto escaping or auto encoding of, characters in strings.
[00:45:31] Yeah, the way you can, you can paste a rich string and then elm-format will automatically make more verbose and more clear, the encoding of the special characters in that string. I really like that shortcut.
[00:45:42] Aaron VonderHaar: Yeah. And that that was an intentional one. specifically there's a list of, kind of special things that it intentionally will escape. For instance, like confusing white space characters, for instance, that aren't normal spaces. And the idea there was to make sure that if you're, especially if you're copying and pasting code, or even typing it accidentally in some way, that you will clearly notice if you put something there that you didn't intend.
[00:46:13] Kevin Yank: Yeah. Like a non-breaking space or something like that.
[00:46:16] Aaron VonderHaar: Yep.
[00:46:17] Kevin Yank: I looked up those five principles in the README and here's what they are: “The benefits of elm-format: It makes code easier to write because you never have to worry about minor formatting concerns while powering out new code. It makes code easier to read because there are no longer distracting minor stylistic differences between different code bases.
[00:46:37] “It makes code easier to maintain because you can no longer have diffs related only to formatting; every diff necessarily involves a material change.
[00:46:46] “It saves your team time debating how to format things because there's a standard tool that formats everything the same way, and it saves you time because you don't have to nitpick over formatting details of your code.”
[00:46:57] Something that was pointed out to me recently by a beginner in Elm at Culture Amp, is that it is still in beta.
[00:47:05] And, the engineer who, I'm thinking of who started playing with Elm for the first time, like two weeks ago as we record this, he said to me, “I saw elm-format, but I saw it was still in beta. So I figured the right thing to do was to stay away for now.” And as a tool that, you know, if you ask me, this should be in your essential first install, especially as a new learner of the language.
[00:47:28] Aaron VonderHaar: The main issue here is just time available to support an open source project in my free time. I think, elm-format is pretty much there. But you can actually— I think I have the issues organized pretty well, so you can actually go and look and see what are in the 0.9 and then the 1.0 release, the 1.0 would be the non-beta release.
[00:47:56] So there is a finite number of things, but there are some things, like one of the weird things that bothers me is. There isn't complete and comprehensive, like new-line handling for types. So for all the expressions, everything works pretty well. But if you have a type definition, you don't have the proper control over
[00:48:19] where you can put new lines. So that's one specific thing that I think I want to get fixed before calling it 1.0. But I mean, you're right, that it, it is something that is certainly stable enough for people to use. But I guess in my mind, and kind of given that I have the luxury to not need to hit milestones to make a living off of this,
[00:48:44] I guess there's certain level of quality that I feel like it demands for me to feel proud of calling it 1.0. Anyone can take a look in the GitHub issues and see exactly what things are blocking that from happening.
[00:49:00] Kevin Yank: The thing you mentioned about gofmt, earlier was that it was blessed by the core team of the language. And I feel like that is somewhat unofficially the case with elm-format,
[00:49:13] yet, you know, someone installing Elm for the first time might overlook elm-format because it's not in the default installation, for example.
[00:49:22] Do you have any thoughts about how you would, like the way elm-format is, packaged, distributed and discovered to evolve in the future?
[00:49:31] Aaron VonderHaar: So the plan has always been from the beginning to eventually have it included. I'd say the main thing that's changed is that it hasn't really seemed that urgent. My impression is that Evan's been happy with the way I've been maintaining it and hasn't felt a need to take it over. For instance, like I've still had time, even after all these years to continue to dedicate to it.
[00:49:54] So it hasn't been in need of a new owner. I mean, there are, there are other tools, in particular elm-test is something that ideally should be part of the core tools as well, and yeah, I don't know. It's just kind of that there's a lot of balls in the air. It's kind of a low priority to try to do that.
[00:50:13] It seems like Evan's philosophy for Elm, if not for open source in general, is that he really sees value in having tools and packages kind of attributed to the author that develop them and using that knowledge and reputation of the person who's responsible for a tool to inform you about the quality of that tool, for instance.
[00:50:39] So I think in kind of his philosophy, it makes sense to continue to have, for instance, elm-format maintained under my name. Rather than trying to merge a lot of things into Elm, which allows him to kind of be the main person for the main Elm stuff. And the other tools that are mainly owned by other people, those are still attributed to them.
[00:51:05] I mean, at some point in Elm's growth, I expect that's gonna need to change, but it seems to be working fine for now.
[00:51:12] Kevin Yank: If people are wondering what's exciting in the world of Elm format, what is there to look forward to? It sounds like that refactoring tool you were mentioning earlier is a big focus for yourself right now.
[00:51:23] Aaron VonderHaar: Yeah. Like I mentioned, hopefully in the next month or so, I should be posting about that on, I guess the Elm Discourse and
[00:51:32] the Elm Slack. Look for that. If people are interested in trying that out, even contact me on Slack sooner if you want, but I should be posting some stuff and looking for feedback on that pretty soon.
[00:51:45] Kevin Yank: I don't know if this would be spoiling it, but like what is the user interface for that likely to be in its initial version? Is it a command line tool? Cause it sounds like the sort of thing that needs to be, integrated pretty deeply into an editor. Is it, is it editor tooling authors that you want to hear from at this point?
[00:52:03] Aaron VonderHaar: Yeah. So this is actually more for bulk refactoring and, it is a command line tool. Basically the definition of your upgrade, essentially, it looks like code, that it just inlines and does simplifications on. So, for instance, at NoRedInk, we have, our style guide where we have, for instance, shareable components for buttons, for modals, for drop-downs, things like that. So we've been using the, alpha version of this refactoring tool to, for instance, if we introduce a new API for doing modals, we can write an upgrade definition for that and then run it across a whole code base, and then point everything to use the new module, even if it has a very different API.
[00:52:50] Kevin Yank: I've heard that kind of tool described as like a codemod tool. The other thing I'm looking forward to is our second episode with you, Aaron. We were chatting before recording this and, you've got a whole other, thing you're working on there at NoRedInk around test driven development. And, did you want to, give a, you know, a sneak 30-second teaser about what we’re going to talk about there?
[00:53:13] Aaron VonderHaar: Yeah. So folks might have seen this on, the, discourse and the Elm Slack. but elm-program-test is the name of the library. and I think we'll be talking about how we use that at NoRedInk and some of, my philosophy about. How to test Elm, what you should test, how to write comprehensive tests in a large project where you have front end and back end or even different back ends that are all interacting and being used by your own project.
[00:53:42] And in particular how you can test, your commands in your update functions and the long-running interactions that may be making HTTP requests, interacting with the user, and so forth.
[00:53:54] Kevin Yank: Ooh. that's heady stuff. I can't wait to, I can't wait to hear your take on it. Um, already looking forward to that recording. Thank you very much, Aaron, for stopping by giving us the inside look at elm-format and its development. I want to personally thank you for all of the time and effort you've put into that tool.
[00:54:13] as I've said, it provided the first example of delight I had in learning Elm and it continues to do that every day for me to this day.
[00:54:23] Aaron VonderHaar: Well. That's great to hear. Thanks for the kind words.
[00:54:26] Kevin Yank: You're welcome, Aaron. Talk to you again soon. Yeah, and thank you, listener for joining us in Elm Town. We'll be coming to your ears with another episode before too long.