Date post: | 28-May-2015 |
Category: |
Technology |
Upload: | danni-friedland |
View: | 542 times |
Download: | 0 times |
elixir for Rubyists
The lovechild of ruby & erlang
+ =
What’s similar
Syntaxdefmodule Underscore.Enum do!! def pull(list, other) do!! ! Enum.reject(list, fn(item)-> item in other end)!! end!end!
Meta-Programmingdefmodule MyMacro do! defmacro unless(clause, options) do! quote do: if(!unquote(clause), unquote(options))! end!end!
And other fun stuff• Huge, expressive standard lib
• Heredocs, Multiline Strings, String Interpolation
• Sigils(i.e %w/%c etc)
• Great documentation
• ITS FUN(C) TO WORK WITH
Whats different
Functional• Functions are first level citizens
!
!
• List Comprehensions
iex> square = fn x -> x * x end!#Function<6.17052888 in :erl_eval.expr/5>!iex> Enum.map(1..10, square)![1, 4, 9, 16, 25, 36, 49, 64, 81, 100]!
iex> lc x inlist [1, 2], y inlist [3, 4], do: x * y![3, 4, 6, 8]!
Immutableiex> list = [:a, :b, :c]![:a, :b, :c]!iex> List.delete(list, :b)![:a, :c]!iex> list![:a, :b, :c]!iex> list = List.delete(list, :b)![:a, :c]!iex> list![:a, :c]!
Pattern matchingiex> {[head | tail], {:atom, msg}} = !! ! ! ! {[1, 2, 3], {:atom, "PATTERN MATCHING FTW!"}} !{[1, 2, 3], {:atom, "PATTERN MATCHING FTW!"}}!
iex> head!1!iex> tail![2, 3]!iex> msg!"PATTERN MATCHING FTW!"!
Pattern matching functions are amazing
defmodule MyEnum do! def sum([]), do: 0! def sum([head | tail]), do: head + sum(tail)!end!
Whats AMAZING
The pipe operatorWe all wrote code like this from time to time:
!
!
Or worse, this:
people = DB.find_customers!orders = Orders.for_customers(people)!tax = sales_tax(orders, 2013)!filing = prepare_filing(tax)!
filing = prepare_filing(sales_tax(Orders.for_customers(DB.find_customers)))!
Ta daa
filing = DB.find_customers!! |> Orders.for_customers!! |> sales_tax(2013)!! |> prepare_filing!
Function captureEnum.map [1,2,3], fn(x) -> x * x end!!!!Enum.map [1,2,3], &(&1 * &1)!
Guard clausesdefmodule Factorial do! def of(0), do: 1! def of(n) when n > 0 do! n * of(n-1)! end!end!
Optional(!) type checking@spec add(integer, integer), do: integer!def add(a, b), do: a + b!
Concurrency
Actor baseddefmodule Greeter do! def greet do ! receive do ! {:english, name} -> ! IO.puts "Hello, #{name}."! greet! {:chinese, name} -> ! IO.puts "你½ 好¥½, #{name}."! greet! {:spanish, name} -> ! IO.puts "¡Hola!, #{name}."! greet! :exit -> ! IO.puts "Bye bye!"! _ -> ! IO.puts "I don't understand ... but Hello anyway!"! greet! end! end!end
!iex> greeter = spawn(Greeter, :greet, [])!#PID<0.52.0>!!iex> greeter <- {:english, 'Amy'}!Hello, Amy.!{:english, ‘Amy'}!!iex> greeter <- {:chinese, 'Ben'}!{:chinese, 'Ben'}!你½ 好¥½, Ben.!!iex> greeter <- {:spanish, 'Charlie'}!{:spanish, 'Charlie'}!¡Hola!, Charlie.!!iex(31)> greeter <- {:klingon, 'David'}!I don't understand ... but Hello anyway!!
Few notes about actors
• They’re fast & lightweight - you can have 10,000 of them on a tiny machine.
• The queue is managed by the VM
• Support hot-swapping
Native support for multi machine distribution
• Actors can be on a local or remote VM, and it’s transparent to you!
on machine1!~> iex --name [email protected] --cookie a_cookie_string!on machine2!~> iex --name [email protected] --cookie a_cookie_string!!iex([email protected])1> Node.connect :"[email protected]"!true!!iex([email protected])2> print_node_name = fn -> IO.puts Node.self end!#Function<erl_eval.20.80484245>!!iex([email protected])3> Node.spawn(:"[email protected]", print_node_name)[email protected]!#PID<7789.49.0> !
The OTPOpen Telecom Platform - but nobody cares
Reliability• Linked processes/Supervisor tree
• Failover nodes
• Hot code reload
• 20 years of battle-tested code, it’s VERY hard to break.
• used by a very huge scale applications:
• Facebook Messages/ WhatsApp
• Riak/ CouchDB/ RabbitMQ
Summery• Functional and fun
• FAST
• Low/high level language
• Mature VM/young language
• Scalable