Erlang is a platform with unique capabilities, yet the language is still considered exotic. There are several reasons for this. For example, cumbersome arithmetic, unusual syntax, and functional programming. These are not disadvantages—they are simply things most programmers either cannot or do not want to work with.
A few days ago, Jose Valim published in his repository a project for a language built on top of Erlang. This language features a simple object model and Ruby-like syntax. Below are excerpts from the documentation and a video demonstrating a simple example.
Disclaimer: %username%, before making conclusions about what Elixir can or cannot do, please at least read through the README.
---
Elixir is a programming language that runs on top of Erlang. Like Erlang, it is a functional language with strict evaluation, single assignment, and dynamic typing, designed to support distributed, fault-tolerant, always-available applications with hot code swapping. Elixir allows you to call Erlang modules without needing to convert data types, so there is no performance loss when invoking Erlang code.
The main difference between Elixir and Erlang is syntax and object orientation. Elixir provides a very simple object model and a syntax largely inspired by Ruby.
At the moment, the main task is developing the standard library. Most of the existing standard library is written in Elixir itself, and you do not need to know Erlang to contribute. Familiarity with OTP principles is enough.
To get started, clone the repository, compile it, and test it:
$ git clone https://github.com/josevalim/elixir.git
$ cd elixir
$ make test
$ bin/elixir -v
Elixir 0.1.0
---
Comments in Elixir, like in Erlang, are marked with “%”:
% This is a commented line
“% =>” indicates the result of an expression:
1 + 1 % => 2
---
Elixir supports integers and floats:
2 + 15 % => 17
-13 * 10 % => -130
1986 - 1985 % => 1
5 / 2 % => 2.5
4 / 2 % => 2.0
---
As in Ruby, everything is an object. You can call methods on numbers:
-1.abs % => 1
5.div(2) % => 2
% surprise!
1.+(2) % => 3
---
Atoms in Elixir are called Symbols (like in Ruby), but the syntax comes from Lisp (Jose explained on Twitter that he wants to use “:” for dictionaries):
'atom
'Atom
'atom_without_spaces
'"Atom with Spaces"
---
Lists are the most useful data structure in Elixir (as in any functional language). They can contain anything and have a set of methods:
['atom, 1, 2, 3, { 'some, 'tuple }]
[]
[1, 2, 3].length % => 3
['a, 'b, 'c][1] % => 'b
[1, 2, 3] + [4, 5, 6] % => [1,2,3,4,5,6]
---
Lists in Erlang and Elixir are implemented as linked lists, so prepending elements is much faster than appending:
list = [2,3,4]
% Don't do this:
[1] + [2,3,4]
[0,1] + [2,3,4]
% Do this instead:
[1|list]
[0,1|list]
---
The real power of lists comes when used with functions:
[1, 2, 3].map do (x)
x * 2
end % => [2, 4, 6]
[1, 2, 3].foldl 0, do (x, acc)
acc + x
end % => 6
---
In Erlang, strings are lists of character codes:
"hello" == [104, 101, 108, 108, 111]
This is inefficient since each character takes 8 bytes (not bits!). Elixir implements strings as UTF-8 binaries:
"hello world"
"hello".to_bin
"hello".to_char_list
"Arrow ⇧ up".length % => 10
---
Strings are the only objects that require conversion:
String.new string_from_erlang
"string_from_elixir".to_bin
"string_from_elixir".to_char_list
---
Strings support interpolation:
"string #{'with} interpolation"
"1 + 1 = #{1 + 1}"
---
Functions are central in Elixir:
my_function = do
1 + 2
end
my_function()
another_function = ->
1 * 2
end
another_function()
---
Elixir supports pattern matching and single assignment:
x = 'foo
{ x, y } = { 'foo, 'bar }
[h|t] = [1,2,3]
---
Pattern matching is also used in function definitions:
module Math
def fibonacci(0)
0
end
def fibonacci(1)
1
end
def fibonacci
fibonacci(n - 1) + fibonacci(n - 2)
end
end
---
Calling Erlang methods is straightforward:
Erlang.is_atom('foo)
Erlang.lists.member(1, [1,2,3])
---
Elixir’s object model includes:
Dynamic dispatch
Mixins
Encapsulation (public, protected, private)
Open recursion (via self)
Reflection
Example:
object Person
def constructor(name, age)
{ 'name: name, 'age: age }
end
def name
@name
end
def age
@age
end
def name(value)
self.set_ivar('name, value)
end
end
---
This is only a small part of Elixir’s capabilities.
A few days ago, Jose Valim published in his repository a project for a language built on top of Erlang. This language features a simple object model and Ruby-like syntax. Below are excerpts from the documentation and a video demonstrating a simple example.
Disclaimer: %username%, before making conclusions about what Elixir can or cannot do, please at least read through the README.
---
Elixir is a programming language that runs on top of Erlang. Like Erlang, it is a functional language with strict evaluation, single assignment, and dynamic typing, designed to support distributed, fault-tolerant, always-available applications with hot code swapping. Elixir allows you to call Erlang modules without needing to convert data types, so there is no performance loss when invoking Erlang code.
The main difference between Elixir and Erlang is syntax and object orientation. Elixir provides a very simple object model and a syntax largely inspired by Ruby.
At the moment, the main task is developing the standard library. Most of the existing standard library is written in Elixir itself, and you do not need to know Erlang to contribute. Familiarity with OTP principles is enough.
To get started, clone the repository, compile it, and test it:
$ git clone https://github.com/josevalim/elixir.git
$ cd elixir
$ make test
$ bin/elixir -v
Elixir 0.1.0
---
Comments in Elixir, like in Erlang, are marked with “%”:
% This is a commented line
“% =>” indicates the result of an expression:
1 + 1 % => 2
---
Elixir supports integers and floats:
2 + 15 % => 17
-13 * 10 % => -130
1986 - 1985 % => 1
5 / 2 % => 2.5
4 / 2 % => 2.0
---
As in Ruby, everything is an object. You can call methods on numbers:
-1.abs % => 1
5.div(2) % => 2
% surprise!
1.+(2) % => 3
---
Atoms in Elixir are called Symbols (like in Ruby), but the syntax comes from Lisp (Jose explained on Twitter that he wants to use “:” for dictionaries):
'atom
'Atom
'atom_without_spaces
'"Atom with Spaces"
---
Lists are the most useful data structure in Elixir (as in any functional language). They can contain anything and have a set of methods:
['atom, 1, 2, 3, { 'some, 'tuple }]
[]
[1, 2, 3].length % => 3
['a, 'b, 'c][1] % => 'b
[1, 2, 3] + [4, 5, 6] % => [1,2,3,4,5,6]
---
Lists in Erlang and Elixir are implemented as linked lists, so prepending elements is much faster than appending:
list = [2,3,4]
% Don't do this:
[1] + [2,3,4]
[0,1] + [2,3,4]
% Do this instead:
[1|list]
[0,1|list]
---
The real power of lists comes when used with functions:
[1, 2, 3].map do (x)
x * 2
end % => [2, 4, 6]
[1, 2, 3].foldl 0, do (x, acc)
acc + x
end % => 6
---
In Erlang, strings are lists of character codes:
"hello" == [104, 101, 108, 108, 111]
This is inefficient since each character takes 8 bytes (not bits!). Elixir implements strings as UTF-8 binaries:
"hello world"
"hello".to_bin
"hello".to_char_list
"Arrow ⇧ up".length % => 10
---
Strings are the only objects that require conversion:
String.new string_from_erlang
"string_from_elixir".to_bin
"string_from_elixir".to_char_list
---
Strings support interpolation:
"string #{'with} interpolation"
"1 + 1 = #{1 + 1}"
---
Functions are central in Elixir:
my_function = do
1 + 2
end
my_function()
another_function = ->
1 * 2
end
another_function()
---
Elixir supports pattern matching and single assignment:
x = 'foo
{ x, y } = { 'foo, 'bar }
[h|t] = [1,2,3]
---
Pattern matching is also used in function definitions:
module Math
def fibonacci(0)
0
end
def fibonacci(1)
1
end
def fibonacci
fibonacci(n - 1) + fibonacci(n - 2)
end
end
---
Calling Erlang methods is straightforward:
Erlang.is_atom('foo)
Erlang.lists.member(1, [1,2,3])
---
Elixir’s object model includes:
Dynamic dispatch
Mixins
Encapsulation (public, protected, private)
Open recursion (via self)
Reflection
Example:
object Person
def constructor(name, age)
{ 'name: name, 'age: age }
end
def name
@name
end
def age
@age
end
def name(value)
self.set_ivar('name, value)
end
end
---
This is only a small part of Elixir’s capabilities.