Introducing Elm Lens

Matthew Buscemi
4 min readDec 27, 2017

--

An Elm file with Elm Lens markup

As my Elm projects grew larger, I began to notice some mildly irksome recurring situations:

  1. I have an Elm file that’s more than a screen’s worth of code. I’m in the file’s latter half and I want to know whether a function I’m looking at is local or exposed. Finding out involves scrolling all the way back up to the top of the file, and then, once I’ve discovered the answer, I have to scroll back down and find where I was again.
  2. I want to get a rough idea of how dependent the rest of my system is upon a particular function. The quickest way to find that rough idea is to: highlight the function, right click, select Elmjutsu, select “Find Usages,” have another panel open up, scan the panel, then I get to go back to my file.

Don’t get me wrong, Elmjutsu is great, and “Find Usages” is phenomenal for helping me go to that reference that I can’t quite remember where I put it. But that’s a fundamentally different problem from the one I described above. I wanted to be able to tell at a glance how much of my system depends on a given function, just like I wanted to be able to tell at a glance whether the function was exposed or local.

I decided to make a Atom package for information about Elm functions that I want to be available at a glance, and I call it Elm Lens. The goal of the project is to provide code visualizations that enable maximum productivity when working with large Elm applications.

When you open up Atom with Elm Lens enabled, the plugin scans your project for Elm files and begins parsing them in background processes. Elm Lens can display exposing information and local references nearly immediately, as it requires parsing only one file. In order to show you external reference counts, the whole project must be parsed, but these process do not block you from working! The function markup will change to show you when Elm Lens is doing background processing.

Elm Lens markup changes when the file is reprocessing. The current file is updated when you save.

One of the most exciting moments for me during Elm Lens’s development was when its reference counting got good enough that I could start believing it. Much to my dismay, I started to notice orphaned functions in my project. These were functions who had once served a purpose, but all their references had been refactored away, and now they were taking up space.

Since I could now easily detect that case, I decided to change its markup to make it a bit more noticeable:

Local functions with zero internal references and exposed functions with zero external references have warning icons and bright red text. This makes it hard to miss cruft that you probably want to clean up.

Of course, I discovered edge cases. There are a couple of times when we want to expose functions with zero system references:

I decided on this rule: if the type signature of the function begins with Program, it gets to ignore the exposing rule (and gets a special markup tag, too!). The same is true of your unit tests. Those functions are also externally unreferenced. We expose them so that our test runner can pick them up. Functions with a type signature of Test will have markup that looks like this:

I owe a big shout out to Mats Stijlaart. Elm Lens wouldn’t have been possible without his awesome elm-syntax library! He was also kind of enough to implement some changes to help me display Elm Lens markup correctly.

Please give Elm Lens a try and let me know what you think. To use it, open Atom, go to Settings, click the “Install” tab, and search for “elm-lens.”

--

--