8

There's a general rule to name any unused variables with an _ in Elixir. Doing so stops anything being bound to that variable.

However I have noticed a widely used pattern of prefixing with an underscore to denote an ignored argument, in the form of _tail (with the intention being to provide a hint as to what the variable would be).

This is encouraged by the language via a warning in the shell if you try to then access _tail:

warning: the underscored variable "_tail" is used after being set. A leading underscore indicates that the value of the variable should be ignored. If this is intended please rename the variable to remove the underscore

But here's the catch; _tail has the variable bound to it, whereas when using just _ it does not.

Does this mean that there's a performance penalty when naming ignored variables with anything other than an _? Or does Elixir still bind _ behind the scenes, and just error on any attempt to access?

Edit: It looks like the Erlang compiler specifically optimizes this case to treat _* as _ and thus there is no overhead, source: http://erlang.org/doc/efficiency_guide/myths.html

9
  • 2
    "The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming." --Donald Knuth. Worry about a performance penalty when you find a problem with performance in your code and not before. Commented Dec 28, 2015 at 14:03
  • @OnorioCatenacci I'm more interested in how it works rather than using it for improving performance at the moment. Generally I agree with the quote you used, however not worrying about something until it becomes a problem is quite an ignorant way to work. For example; I would probably never learn the answer to this question, as I doubt anything would warrant looking at performance this closely. Commented Dec 28, 2015 at 18:15
  • 1
    @OnorioCatenacci totally agree if your code isn't working that it's not worth it. The process you described, I'm basically at the end stage of making it fast - but the customer is myself (side project). That's what lead me to ask the question above - but only because I got to wondering what it different it actually makes (if any), rather than suspecting it of any particular issue. Commented Dec 28, 2015 at 18:35
  • 1
    BTW there is some discussion of _var vs. _ in this thread from the Elixir Core mailing list: groups.google.com/forum/#!searchin/elixir-lang-core/underscore/… I'm not sure it's what you're looking for but FWIW. Commented Dec 28, 2015 at 18:35
  • 1
    Ah, ok. I did misunderstand the nature of your question then @zackehh. My apologies for the misunderstanding. Commented Dec 29, 2015 at 13:35

2 Answers 2

10

Given everyone already gave the disclaimer to not worry about this kind of performance behaviour, the answer is: if a variable is not used, the compiler will notice it and the compiled bytecode will simply ignore it, as if you used _. That's the same reason why if you do x = 1 and never x, you get a compiler warning.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for weighing in. I hoped someone with more ability to speak to the underlying mechanics would add a comment or an answer.
5

Indeed there's special behaviour in Erlang (and hence Elixir) for the _ variable. But unless you measured that this is a performance problem for your application, I wouldn’t worry too much about this. I imagine overhead of binding variables would be completely insignificant if you're doing anything interesting inside the function.

3 Comments

I'm not really asking for personal use, I'm more interested in the behaviour pattern - e.g. is "tail" treated the same as ""?
Just noticed my comment was butchered by markdown :) _tail treated the same as _ :)
No, it is not. _tail is treated exactly the same as any other variable (besides _). You could say that the leading underscore only controls compiler warnings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.