Call to library authors: define "Nutrition facts" for your meta-programming

One common concern about using Elixir libraries is that use SomeModule does not make clear how it impacts the caller. While the goal of use is precisely to provide a common extension point, and most of the time those changes are minor, it is impossible to know what it does without reading the source code.

For this reason, from Elixir v1.15, we are recommending libraries to include a summary alongside each module, typically within the first section of its @moduledoc, that succinctly explains the impact of using said modules. In this pull request, we have added this note to all use XYZ modules in stdlib, like this:

> #### `use GenServer` {: .info}
>
> When you `use GenServer`, the GenServer module will
> set `@behaviour GenServer` and define a `child_spec/1`
> function, so your module can be used as a child
> in a supervision tree.

Which will be rendered like this (see block at the bottom):

Think of it as “Nutrition facts” for meta-programming. If you are a library author and your modules can be used, please consider doing the same. :slight_smile:

94 Likes

Good idea. I’ll update the ex_cldr libs over the next week or so.

Update: added to the ex_cldr README and the Cldr module and published to hex.pm.

18 Likes

This is where libraries that don’t use use win, nothing to document! :grin:

17 Likes

Best code is no code! :joy:

2 Likes

With careful consideration, use beneficially cleans up a lot of noise and I’m glad it exists.

(•_•) even if it is a bit
( •_•)>⌐■-■
(⌐■_■) overused

Sorry, I couldn’t resist. I’ll see myself out.

33 Likes

In this case, it feels like Kernel — Elixir v1.15.0-rc.1 itself could say a bit less obscure about the use itself.
Right now it says Uses the given module in the current context. as a first sentence. It gives more room for questions like “what is context?”. “what does uses mean?” instead of hinting that there will be something that gets generated along with importing.

In fact hovering over use in VSCode is what I do when trying to get a refresher on what it actually performs.

2 Likes

I think it’d be helpful for IDEs to replace the hinttext for such things to display the @doc of the __using__ macro for the module itself, rather than the general docs for use and the Module respectively. If the library has nutrition facts set up, that’d make it a really clean development experience!

Oh never mind, I see that the nutrition facts in stdlib are in the @moduledoc not the macro @doc, so the current experience is ok.

1 Like

Right, but hovering over :controller in Phoenix

use ProjectWeb, :controller

could’ve unwrapped what’s a bunch of stuff is delivered to you by it.

  • Hover over use shows macro’s hint.
  • Hover over ProjectWeb provides nutrition facts.
  • Hover over :controller gives a clue of what is being brought in.
1 Like

On a somewhat related note, a cool feature available on neovim using elixir-tools, is the expand macro:

162372669-4782baba-1889-4145-8a4f-e3bf13a6450d

18 Likes

Thank you! It’s a great feature! The hint is you need to select for it to actually work, I thought it was broken!

And it duplicates the output on my end too in VSCode.

1 Like

PRs welcome ! Only keep in mind the first sentence is a short summary. :slight_smile:

1 Like

:slight_smile: Before PRing though. What do you think? Imagine yourself a few months Elixir user!

use(module, opts \\ [])

Applies a module as a compile-time extension to the current context.

The use macro combines a require of the module with the invocation of its __using__/1 function, allowing the module to define macros, callbacks, or other compile-time constructs.

2 Likes

Maybe send a PR and link to it here so people can give feedback? I am not evading, I just think my opinion is the least important here. :slight_smile:

:heart:

4 Likes

LOL! You created one of the most readable and clear language syntax and you are not important!

2 Likes

https://hexdocs.pm/pathex/Pathex.html#__using__/1

Check this out. I’ve written this information in three different places already.

6 Likes

Nutrition facts? :thinking: … This is going to be very useful.

For those “eating code for breakfast” :slight_smile:

Really like the new ‘default style’ directive for such information as the struggle was real sometimes.

1 Like

The nutrition facts comparison is very good one, also because these can lie to you, like these one clearly don’t add up to 100:

This is going to be quite similar, but that’s not something that can be easily avoided.

What I would love to see, and maybe there is such thing already, is an information given to me back when I “use SomeModule” in my editor/IDE. I guess that’d be the language’s server doing, that would report to me, in a pop-up or some other form, what happened here, which behavior(s) was introduced, what functions were defined, what modules got imported, things like that.

The documentation is static, and has to be maintained, the language server is dynamic and can generate an actual report, that would take into consideration options pased to the “use” macro, to give me a precise overview of what actually happened to my code when I used it.

The same thing could be available for other macros, also “import” to know what functions got imported.

Again, this may already be available in full or partially, I’m not an expert on the subject.

EDIT: Oh hi there it’s me again commenting on a thread without reading it fully. Need to try this, not in language server and NeoVim specific but looks like what I suggested:

Great idea!

@josevalim This is the first time I’ve seen the {: .info} syntax. I love how it looks, but starting at which version does ExDoc support this?

1 Like