A dive into Reia language (part 1)

Ok, I’m a curious guy …so why not spend some hours in learning another language?
I’m particularly interested in Reia after looking for some (safe) environment for distributed computation.
Reia has a syntax very similar to ruby, but it runs on Erlang virtual machine (that’s probably one of the most advanced and safe environment for distributed applications). A like a lot the idea: powerful of Erlang with (friendly) syntax fo ruby. Why not giving Reia a chance?
Disclaimer: I’m not a Reia expert, I’m just approaching it at the time of writing this post.
Installation
Prerequisites are small: you need ruby and erlang installed on your computer.
- download Reia from Github
- unpack it
- enter its directory
- hit a
rakecommand - hit a
rake installcommand
Done.
First program
In order to see that everything worked well, let’s try to hit some commands through Reia interactive shell:
$ ire
Reia Interactive Shell (prerelease)
Running on Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:true]
Loading standard library from /opt/local/lib/erlang/lib/reia/lib... done.
>> puts("Hi, guys!")
Hi, guys!
=> [nil]
>> 2+2
=> 4
>> 2*5
=> 10
>>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
a
It works like the Erlang shell (so, use “CTRL+C” to leave it).
Now let’s try the must-do-it thing: Fibonacci serie.
$ ire
Reia Interactive Shell (prerelease)
Running on Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:true]
Loading standard library from /opt/local/lib/erlang/lib/reia/lib... done.
>> module Fib
.. def calc(0)
.. 0
.. end
..
.. def calc(1)
.. 1
.. end
..
.. def calc(n)
.. calc(n - 1) + calc(n - 2)
.. end
.. end
=> Fib
>>
..
.. puts(Fib.calc(10))
55
=> [nil]
Do you see the first nice thing? We can define functions by pattern matching on arguments list, like we usually do in Erlang.
Incidentally I’ve found a similar thing applied directly in Ruby with the use of Functor (used, for example, in Waves ruby framework).
Basically, with a functor we can (in Ruby) define somthing like that:
#!/usr/bin/env ruby
require 'rubygems'
require 'functor'
fib = Functor.new do |f|
f.given( Integer ) do |n|
f.call( n-1 ) + f.call( n-2 )
end
f.given( 0 ) { 1 }
f.given( 1 ) { 1 }
end
puts fib.call(20)
Language reference
Ok, now let’s summarize the language reference. Maybe it should be a little boring, but quickly you’ll have a big look at the picture.
Modules contain functions, so we can call it using the form module.function as seen above.
Data types: 10 (integers), 3.1415 (floats), true and false (booleans), nil (no value).
Atoms: :oranges, :"Hi people"
Strings: "", '', 'foo', "2 + 2 = #{2+2}"
Lists: [] (empty list), [1,2,3,4,5]
Tuples: () (empty tuple), (x,) (single element tuple), (x, :foo, fib(10)) Tuples are immutable value sets.
Hashes: {} (empty hash), {:name => 'Your name', 'age' => 32}
Binaries: <<>> (empty binary), <<0>>, <<0,1,2>> Binaries are list of integer in 0-255 range
As you can see most of the things are identical tu ruby.
Operators can be:
- boolean:
and,or,notand the equivalents&&,||,! - comparison:
==,!=,<,>,<=,>= - numeric:
+,-,*,/,**,%
For branching and loops we practically have all ruby constructs:
if condition
...
elseif condition
...
end
unless condition; ... end
x = 2 if condition
x = 1 unless condition
case condition
when :first
...
when :second
...
when _
...
end
# notice the use of the catch-all '_'
while condition; ... end
until condition; ... end
do ... while condition
for x in a_list
...
end
for x in 1..100
...
end
For array types we have the powerful each method too.
Lambdas:
>> times_2 = fun(n) { n * 2 }
=> #<Fun erl_eval:-expr/5-fun-3->
>> times_2(8)
=> 16
Don’t forget that state mutation inside lambda does not affect the outer scope.
module MyModule
def a_method(a, b, &block)
a = a+1
b = b+1
block(a, b)
end
end
ret = MyModule.a_method(2, 3) {|a,b| a * b}
puts(ret)
Surely list comprehensions is the most appreciated thing coming from the Erlang “ancestor” side:
>> [x * 2 | x in 1..10]
=> [2,4,6,8,10,12,14,16,18,20]
We can also add multiple generators/filters:
>> [x * 2 | x in 1..10, x % 2 == 0]
=> [4,8,12,16,20]
Ok, maybe it’s enough for your curiosity. We’ll continue in a future post (maybe).
