Introducing Elm Lens

The tl;dr version: I wanted meta-information about my functions inline with my functions, and so I made a new Atom plugin. Please give it a spin and let me know what you think! (on Atom)

8 Likes

I very much like the idea of letting me know which functions are local and which are exposed.

Does it work across directories? ie I have several Elm files in /src, and others in src/data, and my feeling is that the tool cannot pick up cross-references.

Elm Lens scans all directories recursively in all projects open within the current workspace, and processes all Elm files within them, so yes, Elm Lens will capture all these references. If you have tests, those count towards external reference counts in your main project.

The known issue is actually that Elm Lens can’t distinguish between two different Elm projects that are open in the same workspace. That’s on my roadmap.

OK, well, I wasn’t seeing that - there were some functions which were marked as 0 external which were in fact accessed from other modules in the sub-directory.

Does Elm Lens use data from the elm-package.json file to decide what is in the current workspace?

I also noticed that my Main.elm file wasn’t parsed, and external functions called from Main were not being picked up.

The project I am using this on is a very old one, with frequent refactoring and changes, and I estimate that Elm Lens has cut the amount of code by 40% simply by eliminating dead code.

The ability to accurately restrict imports and exports is also a huge benefit, so many thanks for this.

I just recently corrected a problem that was caused by Atom not correctly reporting the project directories for a workspace in some cases. It’s possible there are still glitches.

Is the project in question publicly available? Would it be possible for you to share a particular revision I could clone to repro this case? If so, please open a bug on Elm Lens with that information.

My Main.elm file did not have a module Main exposing (..) line at the top. I added that in, and Main.elm was parsed. The functions it imports from other modules are also picked up now, with the correct 1 external reference.

So, no bugs to report at the moment.

I just confirmed that not having a module declaration will cause elm-syntax to fail the parse, so it seems that’s what was happening. Good to know. Thanks!

One other minor thing I noticed. I use a package called elm-guards, which is a small wrapper round the Tuple type, which uses infix functions, thus:

    infixr 3 =>
    (=>) : Bool -> a -> (Bool, a)
    (=>) = (,)

I access Guards from another module, but still see the message on that function 0 external references

Not a common use case, by any means…

I just wrote the test that proves that this is a bug. Working on a fix now. Thank you!

I just published a version 0.1.1 of Elm Lens that should correct this issue.

This is a really terrific extension, exactly what I needed.

Not only can I cut dead code and restrict import/export, but it gives me pointers about better ways to structure my code.

Excellent work, indeed.

2 Likes

Yes, 0.1.1 fixes that in my project.

1 Like

Awesome plugin!

Is there a way to get a quick outline of unused function across a project’s code base?
I’ve just install the plugin and I am currently working on a large app and I would welcome the opportunity to remove plenty of legacy functions but I’m a bit lazy to go through all the files to hunt for them :slight_smile:

Thanks again for the plugin!

The way I’ve been dividing up utility context in my mind is:

  • Whole project quality overview: Elm Analyse
  • Project refactoring tools: Elmjutsu
  • Quick (“at a glance”), inline function metadata: Elm Lens

Whole project overview of unreferenced exports seems more like Elm Analyse’s domain to me.

1 Like

I feel like my mind just blew … I’m still fairly new to the eco system.
Just ran Elm analyse on the code and it confirms most of what I thought
Thanks for the link on top of the plugin!

1 Like

Very nice project :+1:

The only thing that put me off was the terminology as “lense” is something else in Haskell; maybe a more literal name would mitigate confusion (“elm-function-stats” or something along those lines?)

Is anyone porting this to vs-code or should I give it a go?

5 Likes

Sure! Let’s discuss details on Slack. I have a roadmap for where I’m taking Elm Lens, and it’d be good to keep parity between editors.

1 Like

Another anomaly - in an application which shows ball positions on a pool table, I have a normal module called Balls.elm, which Elm Lens is unable to access (Elm Analyse can find it, but does not process messages for this module).

I have renamed it, rebuilt it, moved it around in the import declarations, to no avail. All other modules in the app are correctly handled

The module is called once, from Main

module Main exposing (..)

import Balls exposing (showBalls)

The module itself begins

module Balls exposing (showBalls)

import Collage exposing (..)
import Element exposing (..)
import Color exposing (..)

type alias Poz =
  { x : Float
   , y : Float
  }

type alias Ball =
   { poz : Poz
   , col : Color
   , cat : BallType
   }

Rather odd.

It’s not obvious what’s going wrong in this case. Please file a bug on Elm Lens (https://github.com/mbuscemi/elm-lens/issues) and include a link to the affected GitHub project and file.

It’s not entirely unconceivable that elm-syntax is failing because of that extra space in the record type alias there. Have you tried with that extra space removed?