Ruby Colored Glasses: Elixir

Share this article

Today makes our first post in a new ongoing series called Ruby Colored Glasses. This series aims to briefly study items outside the Ruby community that are interesting. These items may have influenced or been influenced by Ruby. Here at Rubysource, we think it’s important to look around and see what we can learn from other communities. Enjoy.

One of the sweetest things about Ruby is its elegant syntax and developer friendliness. So how does Erlang fit in? It turns out a brilliant Brazilian name Jose Valim decided to view Erlang through Ruby colored glasses.

Despite being a 25 year old language, Erlang has some interesting characteristics that are hip in todays blog-o-sphere:

Of course there are others but I’ll leave it up to you to learn more about Erlang. In this article I’m going to introduce you to Elixir.

Elixir

Jose is an award winning Rubyist and had decided to take some time to explore other programming languages including Erlang. After playing around, Jose decided to build his own language, a superset of Erlang, named Elixir. Its description on GitHub concisely describes it as providing,

Charming syntax, method dispatching and metaprogramming on top of Erlang VM

Since the first commit to GitHub in January 2011 there have been three releases (the current version is 0.3.0). Although it’s still early days, I think it’s worth exploring other programming languages, especially those that provide some familiarity to Ruby developers.

In the following sections I’ll introduce basic concepts such as types, operators and functions and provide comparisons to Ruby where appropriate.

Types

Elixir has a handful of basic types which are core to the language and conveniently correlate to Ruby types, for the most part.

Numbers

Integers and floats are the only number types provided by Elixir, whereas Ruby has five types of numbers: Integer, Fixnum, Bignum, Float and Rational. All the typical arithmetic operators work as expected:

3 + 2  % => 5
2 - 1 % => 1
3 * 3 % => 9
6 / 3 % => 2.0
6 / 4 % => 1.5

The % is how comments are defined, which is used in the examples throughout this article to show what the output would be from some operation. Everything probably looks normal, with one exception: why is 6 / 3 result in a float? In turns out that Erlang always returns floats when performing division. If you want to perform integer division you have to use the div operator (you can also get the modulo with the rem operator):

6 div 3 % => 2
7 rem 2 % => 1

One other cool feature is method dispatching is available for data types, very much like Ruby:

5.+ 3 % => 8

The above snippet will work in Elixir and Ruby, pretty sweet right?

Atoms

If you’re familiar with Symbols in Ruby then you’ve already got atoms licked. Atoms are literals whose values are equal to their name which are also not garbage collected (which is the same behavior in Ruby and Erlang).

'functional
'Functional
'so_very_functional
'"hello windows users"

Booleans

true and false. Were you expecting something else? Well, under the covers the values are actually atoms 'true and 'false. That feels a bit verbose and wouldn’t fulfill the Elixir goal of providing “charming syntax”, so you can just use true and false like you’d expect.

Tuples

Tuples are equivalent to a non-mutable, fixed-size array.

x = {1, 2, 3}
x.length   % => 3
x.set 0, 7  % => {7, 2, 3}
x   % => {1, 2, 3}

Notice that once the Tuple is created the contents can not be changed. A set method is provided which will clone the tuple, update the value on the clone and return it. The closest thing in Ruby would be a frozen Array, which wouldn’t quite be 100% like a tuple:

x = [1, 2, 3]
x.freeze
x[0] = 5     # RuntimeError: can't modify frozen array

Lists

Lists in Elixir are very similar to Arrays in Ruby, they can contain anything. In fact, they share a very common API, check out some of the Elixir examples:

x = [1, 2, 3]
x.length   % => 3
x.map do(val)  % => [3, 6, 9]
  val * 3
end
x.any? do (val)  % => true
  val > 2
end

How do you decide whether to use a list or a tuple? A tuple is best suited for situations where you don’t plan on updating the elements. This is because tuple elements are stored contiguously in memory, which results in having to reallocate the entire space in memory when performing an update (although it allows for really fast access).

On the other hand lists are easy to update, and iterate over, because they’re implemented as linked lists. Jose provided me with an example of when tuples might be a good fit:

As an example, if you were retrieving data from a database in Erlang, you would return a list of tuples, where each tuple contains each record information (a tuple for each row) and all tuples inside the list.

For more information check out the List source.

Ordered Dict

As you might have guessed an OrderedDict is similar to a Hash in Ruby. It’s a mapping of key-value pairs which are ordered. However, unlike Ruby, the keys are not ordered by insertion but by using Erlang ordering rules.

x = {1: 'a, 5: 'e, 3: 'c}
x.key? 1   % => true
x.key? 9   % => false

Strings

Strings are treated as UTF-8 binaries. What does that mean? Well, Elixir stores strings as binaries where each character is represented by 1 to 4 bytes. Ruby 1.9 on the other hand has decided to allow for a lot of flexibility when it comes to how strings are encoded. A string can be converted between char lists and a string by using to_char_list and to_bin.

x = "hello"
x.to_char_list    % => [104, 101, 108, 108, 111]

[104, 101, 108, 108, 111].to_bin  % => "hello"

If this binary stuff intrigues you, it’s worth reading more on Erlangs documentation site.

Operators

Elixir has many common operators that you’re used to seeing but there are a few extras that are interesting. I’ll quickly list them all and highlight the interesting ones.

Term

All of the standard term operators are available: ==, !=, <=, <, >=, >. However, there are two extra operators that might be new to you, unless perhaps you’ve used JavaScript: === and !==. These two operators provide the ability to check if two values are exactly equal or exactly not equal to each other.

1 == 1   % => true
1 === 1 % => true
1 === 1.0 % => false

Notice that 1 is not equal to 1.0 because the first value is an integer and the latter is a float.

Arithmetic

Again not much new here: +, -, * and /. However, if you want to perform integer-to-integer division or get the modulo you can use the div and rem operators respectively.

4 div 2   % => 2
5 rem 2  % => 1

There are other operators such as logical and bitwise which are very much like Ruby’s.

Functions

Naturally functions play a major part in Elixir, it is a functional language after all. Functions can be created by using do or ->, the latter is for creating in-line functions (similar concept to lambda in Ruby).

sum = do(x, y)
    x + y
end
sum.call 1, 3   % => 4
sum.apply([1,3]) % => 4
sum[4, 2]   % => 6
sum.(9, 1)  % => 10

[1, 2, 3, 4].map -> (val) val * 2  % => [2, 4, 6, 8]

In the code above you can see that there are several ways you can invoke a function. For anyone familiar with JavaScript you’ll recognize the call and apply functions, they work just as you’re used to.

Another neat trick provided by Elixir are anonymous functions. For example, if I wanted to get the length of each string in a list I could do this:

strings = ["hello", "everyone", "reading", "this"]
strings.map do (val)   % => [5, 8, 7, 4]
    val.length
end

% or a bit simpler
strings.map -> (val) val.length   % => [5, 8, 7, 4]

As you can see, I’m just calling length on each item in the list. Using an anonymous function I can simplify it even more:

strings.map _.length    % => [5, 8, 7, 4]

Pretty sweet, right? Is that it? Of course not. Functions can be passed as arguments:

sum = -> (a, b) a + b
double_sum = -> (f, a, b) f.call(a, b) * 2
double_sum.(sum, 5, 3)  % => 16

There’s certainly more to learn about functions, especially by reading the source.

Next

I only scratched the surface here and hopefully gave you enough of a taste to tempt you into exploring more on your own. Elixir is actively being developed with new features and bug fixes regularly being fulfilled. Some areas that would be worth exploring next include:

  • pattern matching
  • exceptions
  • invoking erlang methods

Please leave feedback about your thoughts and discoveries, if anything it’s great that you’re taking time to explore languages outside of Ruby.

Craig WickesserCraig Wickesser
View Author

Craig Wickesser is a software engineer who likes to use Ruby, JRuby, Rails, JavaScript, Python, Java and MongoDB. He is also a moderator for RailsCasts, a former writer for InfoQ and a former editor for GroovyMag. You can check Craig's stuff out on his blog.

elixirerlangruby
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form