Initial release of VS Code extension: Elm Module Explorer

Hello everyone!

I just released the first iteration of a VS Code extension presenting a type oriented tree view of functions for the currently open file. In addition to organizing by type, it also attempts to classify the use of the type in each function as (Input | Output | InputOutput | Referenced), and uses (+/-) to indicate whether the function is exposed. The plugin should be fast and responsive.

The extension can either be installed directly from within VS code or from the Visual Studio Marketplace.

If you use VS Code and think this might satisfy some need you have, then I would really appreciate feedback! Please do note that this extension is not attempting to replicate a “hoogle-like” experience as that is already covered by a plugin from another author (the name of that plugin is elm-signature).

Thanks

15 Likes

Very useful thing, thank you! For big files with many types it will be useful to just make list of data and list of all functions in alphabetical order for fast navigation

Really nice extension!
I tried it on our codebase and it works great :smiley:

I just want to comment on the overview page

what you call “truly dizzying” is in fact known as positive/negative argument position.
This article which explains it nicely. Although it’s using haskell to explain it, I just thought I’d mention it in case you’d want to incorporate some less hand-wavy explanation in the description.

Thank you so much for the positive feedback! Thank you even more for the article on Covariance and Contravariance and the specific formulation in terms of positive and negative position. I was already familiar with covariance and contravariance from work in Scala and C#, but I’ve not seen such a nice description of positive and negative positions.

I would like your opinion on two different topics if you are willing to consider.

Potentially Useless Distinction

  • In (Int -> Widget), the type Widget is in a positive position; covariant if widget were a type argument.
  • In (Widget -> Int), the type Widget is in a negative position; contravariant if a type argument.
  • In ((Widget -> Int) -> Int), the type Widget is in a positive position because the function will clearly produce a Widget. However, in this example Widget is produced internally by the function i.e. consumers of the function do not explicitly apply a Widget as an argument to this function. In this case the extension will label Widget as referenced rather than as either input or output. I speculated this could be a useful distinction when thinking about how functions and types relate from a consuming point of view (whereas I tend to think of covariance and contravariance in terms of type assignability and generalization). Do you think this third category of referenced is a useless distinction? Perhaps it would be better to only classify types as covariant and contravariant because that is better understood by the community?

Potentially Insulting or Underestimating Description

I did not make a formal reference to covariance and contravariance because

  1. I was using a slightly different distinction.
  2. I didn’t want to use “scary” language. I’ve noticed that the Elm community can sometimes avoid computer science / math terms in order to make the concepts more approachable (as opposed to PureScript which embraces categories). I was trying to do the same thing in avoiding covariance and contravariance, but perhaps that was just insulting? I should probably at least mention the topic.

I’m not sure how I would use such distinction in your tool’s output, but for me it would feel confusing
if you classified types like (Widget -> Int) -> Int into either of the first two, so it makes sense to keep it. Not to mention that you can have weird types with even more nesting (however rare this kind of situation might be) like ((Widget -> Int) -> Int) -> Int where Widget is again in negative position.

For this reason I was hesitating if I should post my comment :slight_smile: From my point of view you can still keep the beginner friendly explanation and just mention some external resource for those who want to learn more about these concepts. Unfortunately I don’t know of a good language-independent place describing positive/negative argument concepts :confused:

Nice to have extension :slightly_smiling_face: A fold/unfold toggle button would be useful I think.