If you had to choose one single feature in Elixir that you love the most, what would it be?

It’s got to be Elixir’s hierarchical name-space and module system for me


i love everything in elixir. easy and relaxing syntax, pipes, guards, exunit, pattern matching, genserver, mix, functional programming. I’m feeling so happy whenever i code elixir, plus i have nothing to worry about performance.

but i would like to highlight two things that are so important that they save a lots of my time writing elixir code: typespecs and the new code formatter. We probably need to make them community best practice.

1 Like

We use typespecs for all functions but I still don’t know how to enforce them or what they really bring to the table in practice.

Can you elaborate on what typespecs give you? For us, it’s just visual clarity of the types a function is expecting.


With typespecs, not only you get visual clarities, but you can get more with dialyxir.


immutable data as much as pattern matching for me

to be blunt, I would miss pattern matching and immutable data even with José :wink:

Jośe valim
From a ruby ninja to elixir creator. What’s coming next.

I also liked pattern matching, but it came along with erlang.


I would say the combination of function overloading and pattern matching in the function head. As far as I know that combination is unique to erlang and elixir.

I wonder if referencing “function overloading” in context of Elixir/Erlang should best be avoided. In other languages overloaded functions are separate functions discriminated by arity and/or parameter types. In Elixir functions of the same name but different arity are separate functions - but other than that:

  • the terminology of “multi-clause function
  • the fact that the order of the clauses matters
  • and the fact that the syntax for a multi-clause anonymous function looks like this:
iex> my_function = fn
  {:ok, x} -> "Everything is ok: #{x}"
  {:error, x} -> "There was an error: #{x}"

all suggest that all the clauses of the same arity (and name) belong to the same function. Sure patterns and guards can mimic discrimination by parameter type - but in principle each clause is part of the same function.

So when the documentation states things like:

Specifications can be overloaded just like ordinary functions.

@spec function(integer) :: atom
@spec function(atom) :: integer

it's bound to create confusion.

If it’s in Elixir (regardless from where it stems or however many other languages have it) then it is eligible for this thread :003:

Off topic fork moved here.

1 Like

This is not a feature, per se, but Phoenix. And of equal value to me, is the functional paradigm of Elixir.


I’ve been using Elixir’s Gettext module quite a lot lately (to create multilingual sites). It really is well-done and enjoyable to use, and similar to Phoenix, seems to be built with macros. So, while I don’t code macros myself, I have to admire the resulting power and declarative constructs that it can enable in Elixir.


Oh yes, definitely, Plug and Phoenix and Mix are full Elixir creations, they definitely are features!! ^.^

I think this really depends on where you are coming from when you start learning elixir. Obviously, if you are coming from other languages that have this feature like haskell you probably won’t think “method overloading” when you see this.

If having pattern matching in the function head is confusing to newcomers it’s probably because when they see it they immediately think method overloading. Generally speaking, this is more of a problem when developers are learning a new language in general because they are trying to map/force their current knowledge on top of the language they are trying to learn.

Not having pattern matching in the function head means that the developer would be coming up with a new name for a function that does EXACTLY the same thing or the programmer would now have to take responsibility for the conditional check (like every other language) instead of letting the language do it.

There is also a developer ergonomic effect by pattern matching in the function head: cohesion is much easier to achieve. Given the example above, if you are performing a check on whether the first value is :ok or an :error, then you could easily make the argument that there are 2 reasons for that function to change instead of one. Pattern matching in the function head lifts the logic so the programmer is only coding that function for that specific logic branch. This makes it much easier to change code later without breaking anything else.

That being said, you could say that once the programmer learns to read the entire function head, that it would create less confusion not more since the function head communicates MORE information like when when the function can be called.

The community :slight_smile: . I think everything starts in the community; all of Elixir’s other features could be re-created from there.

I love the civilized form of discourse an collaboration that is possible with you all. I really like the way Elixir’s core team responds to feedback and encourages/stimulates people to contribute, and I also really enjoy the larger community that has formed around this. You are wonderful people. It really feels special to be able to be part of this.

Maybe it sounds cheesy, but it’s something that might not be said often enough.
I love you guys :heart:!


An interesting idea, ‘what if’ Elixir’s named function definitions matched the anonymous function definitions, so like:

def blah do
  :ok, x -> x * 2
  :error, _ -> :error

def blah do
  (:ok, x) -> x * 2
  (:error, _) -> :error

Or so…

Not Elixir, but OTP is the magic that makes Elixir happen. So, for me OTP!

I think that bunching all the functions clauses together in one unit is better, it pushes the idea that this is one function and shows more clearly all the bits which comprise the function. Otherwise, in the worst case, you may need to scan the whole module to find the function clauses. I know this is not encouraged but it is legal. Or has it been changed now? However writing macros becomes easier if you can split the function clauses.

And yes, I am influenced by my past with Erlang. :wink:

I entirely agree, that is why I like how OCaml does it, a ‘multi-head test’ is done via the function keyword:

let someFunc = function
| Blah x -> string_of_int x
| Vwoop 0 -> "invalid"
| Vwoop x when x<0 -> "Lower Vwoop"
| Vwoop x -> "Vwoop"
| ...

Elixir does still require function clauses to be together though, but otherwise they ‘look’ like separate function definitions. Of course macro’s and super change all that up too. ^.^

For note, super means that a function was defoverrideable theFunction... first, which means that each function internally gets a unique name, and when the module is finally compiled the ‘last’ one defined gets the real name, and the ‘super’ call inside it just delegates to the previously named one. Interesting method to work around the one-definition rule, though again I still like how OCaml does it:

let someFunc x -> x * 2

(* This references the previously defined function *)
let someFunc x -> 2 + someFunc x

(* The `rec` completely hides prior definitions, instead this references itself *)
let rec someFunc x -> if x <= 0 then 0 else someFunc (x-1)
1 Like

Who said, flattery does not pay :wink: