Your Elixir Tips Thread

This blog post hit my timeline earlier, and I’ve also been learning about some fantastic Elixir related tips via @pragdave’s new online course, his book, and @sasajuric’s EIA - so thought it would be cool to start this thread to see what tips you might have yourself :003:

5 Likes

One of my favourites so far is making functions do only one thing (or one transformation) - so if possible, avoid if/elses/conditionals and go for multiple def clauses instead. This makes your code more readable and maintainable/refactorable and just overall less brittle. This is definitely one of the answers to my “surely there has to be a better way of doing things” when developing using a different programming language :lol:

14 Likes

Probably one of the best tip I’ve heard was always use pipes wherever possible. Do not overdo it but make sure to use it in situations that will make your code easier to understand.

EDIT: Also, it is beneficial to organize your files by responsibilities. For instance, I will create separate modules for the main implementation and GenServer capabilities.

6 Likes

Well, I’ve some:

  1. Understanding some key concepts of Elixir, which @josevalim nailed explaining them on his keynote for last ElixirConf EU. For those who like to go straight to the point, is the “What is Elixir? (ElixirConf version)” part I’m talking about. What I mean is that, once you understand the concepts he talks about, you will understand how Elixir is made to work, and consequently do better code for Elixir.

  2. Use railway oriented development, and Kernel.SpecialForms.with/1 is a great tool for it. Pipe operators are great when you have to make a simple job in many steps, but when you have to handle errors on any of these steps, with fits better.

  3. Another silly thing I do is to avoid var attributions on my functions, at all. I know, maybe a lot silly, but conceptually it’s very tight with what @AstonJ said. No attributions help me to think when I can extract another function to do something that I’m saving in a variable to use after. Of course, that’s not something to do in every single case, sometimes it’s a good idea to save calculated values which will be used a lot later. But most times, you could do this:

    def foo(map) do
      bar = Map.fetch(map, :bar)
      "ID: #{bar.id}, NAME: #{bar.name}"
    end
    

    Without attributions:

    def foo(map) do
      map
      |> Map.fetch(:bar)
      |> do_foo()
    end
    
    def do_foo(bar) do
      "ID: #{bar.id}, NAME: #{bar.name}"
    end
    

    I know, silly example, but on complex cases it can help you a lot. Hope you got what I mean.

6 Likes

Oh, one more thing! Apply the “let it fail” philosophy wherever you can!

For example, instead of:

case foo(bar) do
  {:ok, bar} -> {:ok, bar.foo}
  resp -> resp
end

Do no match all clause, and let it fail for unknown scenarios:

case foo(bar) do
  {:ok, bar} -> {:ok, bar.foo}
  {:error, resp} -> {:error, resp}
end

Again, silly example, but what I mean is: exceptions like CaseClauseError are better errors to get than unexpected values escaping out of your own code, believe me.

9 Likes

Reading @josevalim’s post on this thread just got another insight of tip:

Prefer alias over import. Aliasing is clearer (explicit is better than implicit), faster to compile and does not affect performance on runtime at all (I guess)!

2 Likes

To clarify, both alias and import are fast to compile and both do not affect the runtime performance. The issue is that import implies a compile time dependency, aliases do not. When you do import Foo, Foo needs to be available at moment and the compiler will block until such happens.

5 Likes

Also, just to clarify, it is so the compiler can scan the exposed functions on the module to know what to import from which module.

/me wonders if an option on import could import only: ... names without the compile-time checks, perhaps like import Blah, compile_check: false, only: [my_fun: 1, my_fun: 2, more_funs: 1, ...]

1 Like

More than tips, I’m trying to find repositories with sample code. I’m very fresh in FP (and Elixir too), I´ve already started @pragdave´s course too. It was a great source but I want to find more code to learn strategies of coding in FP because today all my code looks like an OO approach.

It’s easy to find tools and libs written in Elixir in github, but sites, apps and information systems that is my focus now it’s not so easy to find.

If someone knows or have any github repositories I will be gratefull.

2 Likes

Here’s a neat tip from PragDave

If you want to comment a public function, but hide it from the documentation system, try the following. (The trick is the “!” operator.)

https://twitter.com/pragdave/status/1000456904185966592

4 Likes