Proposal: IEx hints

In Elixir we are continuously trying to improve the experience for developers learning the language. However, there are still common road blocks users run into, despite of the tips and warnings put into the learning materials.

This proposal is about a hints mechanism for IEx that will allow us to print some information and guidance to users in common situations.

As an example, imagine the situation where IEx prints a list as a char list for the first time, a situation newcomers often find themselves in:

iex(1)> Enum.map([0, 1, 2], & &1 + 10)
‘\n\v\f’

In such cases, we could print hints, such as (don’t worry about the hint content for now):

Did you expect a different result than '\n\v\f'?

By default Elixir prints a list of ascii characters in single quotes.
Since [10, 11, 12] is a list of characters, you saw the '\n\v\f' result
above.

Whenever you are in IEx and you are not sure about what a data type means,
use the `i/1` helper to give you more information:

    i('abc')

Each hint will be show only once. There will also be a function to disable all hints.

Before moving forward, the Elixir team has two questions:

  1. Would such hints be generally helpful?

  2. More importantly, which hints do you believe we could show on IEx? Hints should be valid language idioms that may be confusing when you first experience it. If an invalid construct is confusing, let’s say it has a poor error message, then we should improve the error message instead of adding a hint.

Please let us know when the hint should trigger and what we should suggest.

Thank you.

Note: This is an on-going discussion. Before joining the thread, please check the current discussion and see if your feedback and concerns haven’t already been brought up.

32 Likes

I’d personally think that would be greatly useful for new people yes.

7 Likes

I’d like to see hints about the “no function matches…” once in a shell session. Having a better-communicated lack of matching function is IMO paramount in a language with pattern matching.

Imagine I have a function that accepts either map or list, and somebody tries to pass a tuple to it. The default message was confusing to me the first several times.

I realize we’re talking rookie mistakes, yes, but there’s nothing wrong to hold the hand of the people here and there. It’s also nothing major, but IMO worth a once-in-a-session hint.

5 Likes

Generally I like the idea a lot and think it would be valuable to have enabled by default. My only concern is it might get too noisy for those more familiar with Elixir.

Is this per IEx session, or will the history and the disable option be persisted between sessions? I’d very much like some form of persistence.

2 Likes

Maybe instead of ‘default’ persistence it defaults to per-session, but at the bottom of each it says to run ‘some’ command to disable globally, which would add some kind of flag or so into the ~/.iex.exs or whatever file that disables globally.

I can very much see it being slightly irritating on new installs, but something like that would make it very easy to disable.

6 Likes

Yes but as mentioned have a way to turn it off via a config file :slight_smile: Otherwise it’s an awesome proposal and I’d love to contribute to it.

5 Likes

As I have mentioned in the proposal, hints are not about error messages. If an error message is unclear, then we should improve the error message, there is no reason to keep such cases as hints.

To quote the proposal:

Hints should be valid language idioms that may be confusing when you first experience it. If an invalid construct is confusing, let’s say it has a poor error message, then we should improve the error message instead of adding a hint.

An issue has been opened to track function clause error improvements.

Hints will be shown only once per computer. Once a hint is shown or you disable them, you should never see them again.

5 Likes

Something, that I often see people struggle with is the “no process” exit. With the things people are doing when starting out, it usually means some application is not started, or they forgot to add something to their supervision tree.

I’m not sure, though if this is a good candidate for that kind of additional messages, or maybe improved error.

3 Likes

v1.4 already has an improved error for that, let’s see how it will go. If your hint is related to an error or an exit message, then it is not a hint. Instead open up a bug report to make the error message clearer.

2 Likes

@josevalim: To answer your questions:

  1. Yes and no. I think that add hints as you described is not best idea. Why? We use iex mostly to two things: try Elixir or library API (and in this case its a good idea) and for debugging code. I can’t imagine that I’m browsing bigger debugged (more than one) data and have mixed it with tips. We could have a case that tips could decrease readability of debugged data.
    For example:
"It's a result of `&IO.inspect/1` with really long data ..."
Elixir first tip
'second result'
Elixir second tip
325185.1242421
...

What I suggest is to add one more tips / tutorial (or similar name) executable for that or add this tips at start of iex. Maybe with prompt to optionally display next …

my@prompt > iex
...

Did you know that ...?

iex(1)>

or tutorials:

Tuple is ...
Would you like to see documentation for it? [No/yes]

Where No (default) will clear console and display another tip and yes will open a docs in default browser, clear console and display next tip. To exit we could add info to press Ctrl+C.
Think how GUI apps work. They don’t display a tip when you click on specified button, but at start of app in separate window. I think that iex could have something similar (but of course in console).
What do you think about it?
2. I suggest to add hints based on Elixir’s biggest gotchas? topic.

1 Like

The problem with anything opt-in, such as a different command line tool or a flag, is that newcomers won’t know/remember to do so, which pretty much defeats the purpose of having IEx hints.

This is also not meant to be a tutorial, we already have plenty of mechanisms for teaching Elixir, we are not planning to introduce another one. The goal is to have a simple and unobtrusive system for hints. We are not going to stop the user workflow and ask questions. Those would be too disruptive.

That’s why I am not worried about the debugging aspect because hints will be shown only once per computer and won’t interrupt the workflow. Hints are also based on iex’s input/output, so it wouldn’t interfere on the IO.inspect examples you mentioned above.

Those are very good concerns but I think we are safe for now.

Good call!

4 Likes

I would say yes, for that kind of system of hints, however, I don’t have any suggestion specifically for iEX, but I would like to see the same approach for migrations. I know, its Ecto, but maybe there could be any layer between that translates errors.

1 Like

Ok, so how new developers known about iex? From official site :smile:

Ok, so here is my proposition:
We should have 2 ways to disable this feature:

  1. per session like: iex --no-hints
  2. global - in configuration file

I believe that if someone is going to test API then he will not disable this and otherwise he would get tips in next time.

5 Likes

From the official site, blog posts, books, screencasts, online courses, university classes, presentations, etc. It is impossible to change all of them to talk about some special flag.

Yes, those two mechanisms should be supported as well as an API to call directly from Elixir, such as IEx.hints(false).

5 Likes

From that topic, I got rebinding:

iex> x = 1
iex> x = 2

but I am not sure it is something worth having a hint for because I expect most newcomers to actually be ok with rebinding? Emitting a hint and talking about immutability can cause more confusion than help in this case? Thoughts?

2 Likes

I learned lots of languages and don’t remember any with rebinding/pattern matching. I think that they should be described in one tip, for example:

One of Elixir language features is support pattern matching.
Note; pattern matching is not variable assignment.

iex> x = 1
iex> 1 = x
iex> 2 = x # exception
iex> x = 2
iex> 2 = x
iex> [a, b, %{c: c}] = [1, 2, %{c: 3}]
2 Likes

something great would be to be able to invoke a hint, independently of the context :slight_smile:

6 Likes

I think these hints would be immensely useful!

I think that beefing up the help system is a great idea.

However, I would prefer it if the getting of help information were explicitly requestable. By default, iex shouldn’t offer these help messages. I often drop into iex from a random directory (with no configuration) to play around with a bit of elixir - so I don’t want to see a bunch of extra help information that I have to affirmatively disable.

Instead, I would prefer it if iex required you to activate the help system, either as a mode that can be enabled or disabled with a command - or perhaps as a special way to enter a command. For example, preceding the command with a “??” would enable the help for that command:

iex(1)> ?? Enum.map([0, 1, 2], & &1 + 10)

1 Like

@crusso: Let’s create a tip about disabling tips! :077:

3 Likes