Few weeks back I was reading a blog about concurrency limitations in Ruby (which we all are aware since long) and how Elixir is evolving. Thus I was extremely curious to know this new dynamic functional programming language "Elixir", the two decades old Erlang language & Erlang Virtual Machine (VM) known for running low-latency, distributed and fault-tolerant systems. This article is a result of my curiosity about Elixir and Erlang.
This article does not cover (i.e. out of scope) installation steps of Elixir & Erlang on Mac, Ubuntu or Windows machine as lot of help is already available online to do so.
What is Elixir?
Elixir is a functional programming language. Functional programming promotes a coding style that helps developers write code that is short, fast, and maintainable. Elixir has been designed to be extensible, letting developers naturally extend the language to particular domains, in order to increase their productivity. Elixir leverages the Erlang VM. José Valim is the creator of the Elixir programming language. His goals were to enable higher extensibility and productivity in the Erlang VM while keeping compatibility with Erlang's tools and ecosystem.
What is Erlang?
The Erlang VM and its standard library were designed by Ericsson in the 80’s for building distributed telecommunication systems. The decisions they have done in the past continue to be relevant to this day. As far as I know, Erlang is the only runtime and Virtual Machine used widely in production designed upfront for distributed systems.
On one of the blog, it was mentioned that
Erlang is a Ferrari wrapped in the sheet metal of an old beater. It has immense power, but to many people, it looks ugly. It has been used by WhatsApp to handle billions of connections, but many people struggle with the unfamiliar syntax and lack of tooling. Elixir fixes that. It is built on top of Erlang, but has a beautiful and enjoyable syntax, with tooling like mix to help build, test and work with applications efficiently.
Its a well known fact that Ruby is not a good language to build concurrent code. MRI, the main ruby interpreter, has a global lock that prevents any code to run in parallel. It is true that other implementations like JRuby and Rubinius don’t have that global lock, but still they are not optimal for concurrency, because the language itself is not designed for it.
Ruby objects are mutable, so it has state. When the code is running in parallel, this may lead to strange behaviour and bugs due to unexpected race conditions unless we are very careful.
The basic data-types (arrays, strings, hashes) are not prepared for parallel read/write. To solve this problem there is a gem called hamster that provides a set of real immutable structures, but still, is not part of the core. The vast majority of the libraries are not still thread safe.
In summary, people that are serious about concurrency tends to use real state-less programming languages. Functional programming shines with all its bright at this, and one of the most popular programming languages is Erlang.
Concurrency is Elixir's key to performance. It uses lightweight processes running on all of cores and additionally it has a very nice syntax similar to Ruby.
This is an excellent video of José Valim explaining why Elixir - https://vimeo.com/53221562
Its around 1 hour long and José takes us through the Journey of why he wrote Elixir, Goals & Inspiration for developing Elixir.
In brief, his video highlights following goals and motivation behind developing Elixir
Goal1 - Productivity is the top goal for developing Elixir
Goal2 - Extensibility
Goal3 - Compatibility
Extras - Use power of concurrency for example: running tests in parallel.
What is Phoenix?
Phoenix is a framework for building HTML5 apps, API backends and distributed systems. Written in Elixir, you get beautiful syntax, productive tooling and a fast runtime. Phoenix builds on top of Elixir to create very low latency web applications, in an environment that is still enjoyable. Response times in Phoenix are often measured in microseconds instead of milliseconds.
What is Functional Programming?
The most popular language for parallel and distributed programming is Erlang -- a functional language. An even better candidate for parallel programming is Haskell, which supports a large variety of parallel paradigms.
In functional programming all data is immutable. Functional programming involves writing code that does not change state. The primary reason for doing so is that successive calls to a function will yield the same result. Why do we want successive calls to a function to yield the same result? There are a few reasons why that's undesirable. First, if a function returns the same result, then you can cache that result and return it if the function is called again. Second, if the function does not return the same result, that means that it's relying on some external state of the program, and as such the function can't be easily precomputed or parallelised.
In functional programming languages you have first-class functions (functions that can be passed around just like any other value) and higher-order functions (functions that take other functions as arguments). In first-class functions you can pass functions as parameters to other functions and return them as values
So C is a non-functional programming language? Yes. C is a procedural language. However, you can get some of the benefit of functional programming by using function pointers and void * in C.
Functional languages are of two types, pure and impure. Haskell is considered as pure whereas Erlang Elixir is considered impure functional language. Refer this wikipedia document listing all programming languages by their types https://en.wikipedia.org/wiki/List_of_programming_languages_by_type
Few well know functional languages are F#, Clojure, Haskell, Scala, Erlang and Elixir
How hard is functional programming?
It definitely requires some getting used to. We'll have to learn to replace loops with recursion, to map and fold lists, traverse data structures without iterators, do input/output using monads, and many other exciting things. All these techniques have value on their own. As programmers we constantly learn new tricks, and functional programming is just another bag of tricks.
Why am I interested in Elixir?
Here are some key reasons about my interest in Elixir
- Erlang, Performance & Parallel processing. Tried and tested since more than two decades in Telecom domain.
- Concurrency - It can be done in Ruby but its wild west and not that great. Concurrency is basically heart of everything done in Elixir due to Erlang.
- Compiler instead of interpreter - but yes still dynamically typed and not statically typed.
- Since Elixir leverages Erlang, the processes are not OS processes - but instead they are much more lightweight. 100K on a single Erlang instance is not uncommon, millions per instance are doable.
- Defined, well understood pattern for handling state and message passing among processes.
- 100 bytes per process in Erlang / Elixir (2 MB per process in Java or other platforms.)
- José Valim and Rails background - Lot of synergy in developing apps.
- Phoenix - Web framework equivalent to Rails.
- Experts vouching for the language and its power in distributed environment.
It's standing on the shoulder of giants, in this case the Erlang VM. A battle-proven VM that makes it really easy to build a highly-scalable, fault-tolerant and distributed systems. A perfect fit for web applications. It already has a great set of libraries for web development: Plug (spec for composable web app modules - think Rack/wsgi), Ecto (library to query and interact with databases) and Phoenix (a fully-featured web framework). All of them have reached 1.0 or are about to do so, and they're incredibly well-designed and powerful.
Great tooling, out of the box: mix (build tool and much more), hex (package manager), ex_unit (unit-testing framework), ex_docs (generate documentation from the code), and others.
Fantastic community: this is a very special attribute of Elixir, and one that the creators and core contributors of the language are putting a lot of effort into: they're extremely available (irc, slack, ml, SO, etc.), they always respond very promptly to questions, issues, PR and give a lot of feedback, they take a lot of times explaining the concept of the language to beginners, and so forth. As a result the whole community behaves in the same way, it's quite impressive what they've achieved.
I am on Elixir slack channel for more than one week now and I have personally experienced these great things about the Elixir community. I have also posted, at bottom of this article, one of my chat on Slack channel.
Few special mentions about Elixir - The very strong meta-programming capabilities. The |> (pipe) operator. Pattern matching capabilities etc.
My interests with compiler and how things work?
Here is a quick depiction of how Elixir works internally (taken from one of the videos by José)
Ruby on Rails vs. Elixir ecosystem?
iexis for Elixir just like
irbis for Ruby and
iexstands for interactive Elixir.
- Atoms in Elixir are Symbols in Ruby. (Few other basic data types like int, float are common)
- We need to write functions to mutate data structures in Elixir instead of objects to hide the state or implementation.
- I will list down more soon.
Platform & Elixir Language features in brief
Elixir data types are immutable. By being immutable, Elixir code is easier to reason about as you never need to worry if a particular code is mutating your data structure in place. By being immutable, Elixir also helps eliminate common cases where concurrent code has race conditions because two different entities are trying to change a data structure at the same time. Reference to Elixir basic data types - http://elixir-lang.org/getting-started/basic-types.html
Elixir ships with a great set of tools to ease development. Mix is a build tool that allows you to easily create projects, manage tasks, run tests and more. Mix is also able to manage dependencies and integrates nicely with the Hex package manager, which provides dependency resolution and the ability to remotely fetch packages.
Coexistence with the Erlang ecosystem which is a huge benefit. Elixir is not trying to re-invent the wheel. Elixir allows to use or call Erlang methods and functions inside Elixir code. So there is a complete interoperability between Erlang and Elixir and vice versa.
Extensibility and DSLs
This wikipedia document lists out key features of Elixir very well - https://en.wikipedia.org/wiki/Elixir_(programming_language)
When you come from an object oriented point of view - as most developers do - picking up OTP (Open Telecom Platform) principles for all the concurrency and fault tolerance glory needs time and at least I needed more than few introduction. Some things that are non-brainers in OOP need serious thinking in a functional language. But usually, most problems can be tackled with less code in Elixir compared to, say Java.
Elixir in Production
One of the things that amazed me the most was the range of business domain Elixir is being used. From web development to game platforms, to embedded devices.
Here is a Blog by Plataformatec about Elixir in Production - http://blog.plataformatec.com.br/tag/elixir/
Elixir Slack Channel
Here is a link to Elixir Slack Channel. https://elixir-slackin.herokuapp.com/
It has roughly 1300 plus registered users and mostly 70+ are active at a given time. I am already part of this slack channel.
Question: What happened to dynamo. I was watching an elixir tutorial on YouTube which mentioned dynamo was the web framework for elixir. but I saw that dynamo was put in maintenance only mode. Why?. Is phoenix the replacement for dynamo now?
Answer: Dynamo was José's playground for what a web framework written in Elixir would look like. And Phoenix is now the "blessed" web framework.
Question: Why would you call Elixir from Erlang?
Answer: If you release a Elixir library that does something awesome and Erlang person wants to use it. Its pretty much for the same reason why you would call Erlang from Elixir.
Here is a query I posted on Elixir slack channel and the quick and detailed response I received.
rohan [1:11 PM]
Hello everyone. I come from non FP (Functional Programming) background. I have generally done Procedural coding using C and lot of OOP using C++ and Ruby. So my question is - do we really need to learn Scala or Haskell first to understand FP better or starting with Elixir is also fine? Though I have done some FP using function pointers in C but not much.
gjaldon [1:12 PM]
starting with Elixir is great, I think
tallakt [1:13 PM]
@rohan: From my experience you shoul rather start with Elixir before Scala and Haskell
gjaldon [1:13 PM]
Scala has a mix of FP and OOP so that could get confusing
tallakt [1:13 PM]
They are all interesting, but Elixir is the simpler mental model IMHO
gjaldon [1:13 PM]
I agree with @tallakt ^
rohan [1:14 PM]
sure @gjaldon and @tallakt - thanks :simple_smile: this is helpful. Thanks for your quick response and inputs on my query.
olivermt [1:18 PM]
unless you are interested in getting lost in a maze of types, I also highly suggest starting with elixir :wink:
rohan [1:19 PM]
sure @olivermt I actually started with Elixir few days ago, but while reading few blogs on FP I noticed tips about starting with Haskell and Scala, thus I was curious to know from Elixir community here. :simple_smile:
olivermt [1:20 PM]
the pattern matching of elixir kinda alleviates a lot of the need for strict typing, so in my oppinion elixir is the way best choice for a FP newbie
rohan [1:21 PM]
good to hear that @olivermt thanks for your inputs.
rohan [1:21 PM]
good to hear that @olivermt thanks for your inputs :simple_smile:
rohan [1:24 PM]
Is this true about FP ?? "Functional programming promotes a coding style that helps developers write code that is short, fast, and maintainable." Read it on one of the blog. Doesn't it depend on a developer how good or bad they write in their language of choice. Or how FP promotes these things ?
olivermt [1:25 PM]
in elixir its promoted by the |> operator
so easy to chain small components
makes the code very readable
and since you implement one function per set of inputs using parameter pattern matching, its all very compmentpartmentalized
god damn, did I actually spell that last word correctly??
anyhow, it makes you work harder to write bad code
because writing it the right way is almost always the easiest way to do it
the huge GOD FUNCTION of java where you send in a map reference and some magic happens, that just isnt possible in elixir
you are force to always consider the boundaries of your data
what goes in, what comes out
I really cant see anyone trying to make a 200 line function in elixir, it just doesnt feel natural
gjaldon [1:27 PM]
and FP code is less complex because you don’t have to deal with state like you do in OOP
there’s no complex class hierarchies
your functions are pure and do not change state in other parts of your application like some methods in OOP do
rohan [1:30 PM]
very interesting. sounds great @olivermt and @gjaldon
tallakt [1:36 PM]
@rohan: believe the hype! in all honesty, I think it is partially true since Elixir has immutability, and that OOP turned out not such a great idea after all... in particular with respect to concurrency. FP will make you rethink the way you program in a big way, and you will be a better programmer for it
rohan [1:53 PM]
Sure, Thanks @tallakt
Elixir and Micro-services - http://blog.plataformatec.com.br/2015/06/elixir-in-times-of-microservices/
Hex packages list (880 in total while writing this article) - https://hex.pm/packages
Should I use Elixir or Go? - http://www.quora.com/Concurrency-computer-science/Should-I-use-Go-Erlang-or-Elixir-for-a-mobile-app-backend
Latest Video on Elixir by José Valim @ Erlang User Conference 2015 - https://www.youtube.com/watch?v=QXcedVc2LQM
The Power of Erlang, the Joy of Ruby by Dave Thomas - https://www.youtube.com/watch?v=lww1aZ-ldz0
Subscribe to Engineering At Kiprosh
Get the latest posts delivered right to your inbox