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

Not necessarily a feature but my favorite aspect of Elixir the culture of explicitness. Much better than lots of magic or implicit behavior.

4 Likes

This forum!!!

16 Likes

It’s almost like Elixir
is the perfect storm
not slowed down by dogma
 but enhanced by practicality
merged together by Jose’s vision and building the best programming language in the world


4 Likes

The awesome community & leadership. Second to none.

6 Likes

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

3 Likes

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.

2 Likes

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

2 Likes

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.

2 Likes

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}"
end

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.
3 Likes

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.

2 Likes

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.

3 Likes

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:!

5 Likes

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
end

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

Or so