3 Elixir Language Features I Love
Elixir is a delightful and productive language to build with. Here are 3 reasons to give it a look.
We are truly privileged to select from a wide variety of programming languages that support different programming paradigms and offer various features.
I've been working more and more with Elixir over the past couple of years and have come to enjoy working in the functional paradigm. Here are a few of the features offered by the language that I love.
1. Immutable Data #
- easy to use (reduces the # of things we have to load up into brain RAM)
- eliminates a large class of bugs related to mutation and shared state (both of which are critical to programs that do Interesting Things™)
- supportable by libraries if unavailable in host language
Functional languages generally favor immutable data by default (such as Erlang, Haskell, Clojure and other lisps). Elixir enforces immutability unconditionally, which makes it less memory-efficient than mutable languages, but also far less error-prone, which can be a nice trade-off depending on what you're building.
2. Pipes #
- natural way to express a series of operations on some data
- easy to read and understand
- easy to insert, remove, or reorder the steps in a transformation
If you've spent any time with Unix then you're already familiar with pipes. They enable composability by allowing for the chaining of operations. Instead of writing something like summarize(groupBy(filter(thing)))
, you would write thing |> filter |> groupBy |> summarize
. To understand the former you need to read the operations inside out, but the latter reads left to right or top to bottom, which is much more natural.
Unix is probably the most widely known example of pipes, but they're also supported in languages like F#, Elm, Haskell, reasonml, Clojure, and many more. One day JavaScript will have them too!
3. Pattern Matching #
- flattens conditionals
- simplifies accessing nested data
- helps reduce the parameter space of a given function
- formalizes assertions or expectations about values and data types
- checkable at compile time
Pattern matching is one of those features that you come to appreciate so much that it's painful to return to a language that doesn't support it. Elixir takes patterns to another level through its match operator (=
).
Many programming languages use =
to represent some form of assignment semantics but in Elixir it behaves more like a mathematical equals sign. Elixir attempts to match the patterns on either side of =
, raising a MatchError
if it cannot. You can read more about the match operator in Elixir's getting started docs.
Pattern matching is supported by a variety of languages like Ruby, Python, Rust, F#, Haskell, Python, C# and many more. It's even coming to JavaScript (soon™, hopefully).
If you're curious to see some of these features in action you can take a look at some of the solutions I put together for a previous Advent of Code in Elixir here.