Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CatWhale's Guide to Elixir

Zander Hill
September 07, 2013

CatWhale's Guide to Elixir

A humorous, historical, hasty introduction to the Elixir programming language.

Zander Hill

September 07, 2013
Tweet

Transcript

  1. defmodule Say do def hello(thing) do IO.puts "Hello #{thing}" end

    end Say.hello("PGHRb") ================== iex(1)> Say.hello("PGHrb") Hello PGHrb :ok Friday, September 6, 13
  2. JOSE VALIM AUTHOR OF ELIXIR 2010 RUBY HERO RAILS CORE,

    SIMPLE_FORM, DEVISE ALL AROUND SHARP RUBYIST Friday, September 6, 13
  3. DAVE THOMAS I’m a language nut. I love trying them

    out, and I love thinking about their design and implementation. (I know, it’s sad.) I came across Ruby in 1998 because I was an avid reader of comp.lang.misc (ask your parents). I downloaded it, compiled it, and fell in love. As with any time you fall in love, it’s difficult to explain why. It just worked the way I work, and it had enough depth to keep me interested. ... - Foreword to Programming Elixir Friday, September 6, 13
  4. Fast forward 15 years. All that time I’d been looking

    for something new that gave me the same feeling. I came across Elixir a while back, but for some reason never got sucked in. But a few months ago I was chatting with Corey Haines. I was bemoaning the fact that I wanted to find a way to show people functional programming concepts without the kind of academic trappings those books seem to attract. He told me to look again at Elixir. I did, and I felt the same way I felt when I first saw Ruby. ... - Foreword to Programming Elixir DAVE THOMAS Friday, September 6, 13
  5. DAVE THOMAS So now I’m dangerous. I want other people

    to see just how great this is. I want to evangelize. So my first step is to write a book. - Foreword to Programming Elixir Friday, September 6, 13
  6. DEVELOPED ERLANG FOR ERICSSON RELEASED FIRST VERSION OF ERLANG IN

    1986. ERICSSON OPEN-SOURCED ERLANG IN 1998. JOE ARMSTRONG Friday, September 6, 13
  7. “With both Pragmatic Press and O'Reilly racing to get into

    Elixir I knew something was happening on the Erlang VM, and I didn’t know about this. Boy am I out of touch.” - Blog Post - http://joearms.github.io/2013/05/31/a-week-with-elixir.html JOE ARMSTRONG Friday, September 6, 13
  8. JOE ARMSTRONG “I downloaded elixir last week and started playing

    … It didn’t take long, but pretty soon my gut feeling kicked in. This is good shit.” - Blog Post - http://joearms.github.io/2013/05/31/a-week-with-elixir.html Friday, September 6, 13
  9. “What Elixir brings to the table is a complete different

    surface syntax, inspired by Ruby. What you might call a ‘non-scary’ syntax, and a load of extra goodies.” - Blog Post - http://joearms.github.io/2013/05/31/a-week-with-elixir.html JOE ARMSTRONG Friday, September 6, 13
  10. “I’ll just say that Elixir has got a heck of

    lot of things right, and the good things far outweigh the bad things.” “This has been my first week with Elixir, and I’m pretty excited.” - Blog Post - http://joearms.github.io/2013/05/31/a-week-with-elixir.html JOE ARMSTRONG Friday, September 6, 13
  11. WEBSCALE? DISTRIBUTED, RELIABLE, SOFT REAL-TIME CONCURRENT SYSTEMS. TELECOMMUNICATION SYSTEMS, E.G.

    CONTROLLING A SWITCH OR CONVERTING PROTOCOLS. SERVERS FOR INTERNET APPLICATIONS, E.G. A MAIL TRANSFER AGENT, AN IMAP-4 SERVER, AN HTTP SERVER OR A WAP STACK. TELECOMMUNICATION APPLICATIONS, E.G. HANDLING MOBILITY IN A MOBILE NETWORK OR PROVIDING UNIFIED MESSAGING. DATABASE APPLICATIONS WHICH REQUIRE SOFT REALTIME BEHAVIOUR. HTTP://WWW.ERLANG.ORG/FAQ/INTRODUCTION.HTML#ID49576 Friday, September 6, 13
  12. ELIXIR BASICS LIKE JRUBY, NOT LIKE COFFEESCRIPT NAMESPACING VIA MODULES

    AND FUNCTIONS IMMUTABLE RECURSIVE 1 defmodule JsonParsing do 2 3 def get_score(username) do 4 get(username) |> extract_types |> Count.sum 5 end 6 7 # Helper Methods 8 def get(username) do 9 get_request(username) |> process_response_body 10 end 11 12 def process_url(username) do 13 "https://example.com/#{username}.json" 14 end 15 16 def get_request(username) do 17 HTTPotion.start 18 HTTPotion.get process_url(username) 19 end 20 21 def process_response_body(response) do 22 JSON.decode(response.body) 23 end 24 25 26 def extract_types(hash) do 27 {_, h2} = hash 28 Enum.map(h2, fn(x) -> Count.points HashDict.get(x, "type") end ) 29 end 30 end 31 32 defmodule Count do 33 def points(type) do 34 converter = fn 35 "EventA" -> 5 36 "EventB" -> 3 37 _ -> 1 38 end 39 converter.(type) 40 end 41 42 def sum([], total // 0), do: total 43 def sum([ head | tail ], total), do: sum(tail, head+total) 44 end Friday, September 6, 13
  13. ELIXIR IS EVERYTHING GOOD ABOUT ERLANG AND NONE — ALMOST

    NONE — OF THE BAD. THAT’S A BOLD STATEMENT, RIGHT? ELIXIR IS WHAT WOULD HAPPEN IF ERLANG, CLOJURE, AND RUBY SOMEHOW HAD A BABY AND IT WASN’T AN ACCIDENT. -- DEVIN TORRES HTTP://DEVINTORR.ES/BLOG/2013/01/22/THE- EXCITEMENT-OF-ELIXIR/ Friday, September 6, 13
  14. PIPE OPERATOR 3 # Without Pipe Operator 4 def get_score(username)

    do 5 Count.sum(extract_types(get(username))) 6 end 7 8 # With Pipe Operator 9 def get_score(username) do 10 get(username) |> extract_types |> Count.sum 11 end Friday, September 6, 13
  15. PATTERN MATCHING 1 converter = fn 2 "EventA" -> 5

    3 "EventB" -> 3 4 _ -> 1 5 end 6 converter.(“EventA”) #=> 5 Friday, September 6, 13
  16. USE ERLANG LIBRARIES defmodule GitHub do ... def process_response_body(body) do

    json = :jsx.decode to_binary(body) json2 = Enum.map json, fn ({k, v}) -> { binary_to_atom(k), v } end :orddict.from_list json2 end end Friday, September 6, 13
  17. ELIXIR INSTALLATION # OSX brew tap homebrew/versions brew install erlang-r16

    ....wait.... brew link erlang-r16 brew install elixir # Arch yaourt -S elixir # Fedora sudo yum -y install elixir http://elixir-lang.org/getting_started/1.html Friday, September 6, 13
  18. ELIXIR WORKFLOW (IN VIM & TMUX) # Install vim-elixir #

    Add to .vimrc nnoremap <leader>e :!elixir %<CR> nnoremap <leader>ee :!iex -r % -S mix<CR> # Use this in shell for repl $ iex -r lib/concurrency.ex -S mix # Use this in shell for tests $ elixir test/concurrency_test.ex $ mix test Friday, September 6, 13
  19. PSEUDO-LIVE CODING #Calculate the area of a rectangle #create a

    function and assign to variable area = fn(w, h) -> w * h end # call function area.(3, 5) #=> 15 Friday, September 6, 13
  20. Code.load_file("lib/concurrency_pre.ex") ExUnit.start defmodule AreaTest do use ExUnit.Case, async: true test

    "area" do area = fn(w, h) -> w * h end assert area.(3,5) == 15 end end beastie:concurrency elixir test/concurrency_pre_test.exs . Finished in 0.08 seconds (0.08s on load, 0.00s on tests) 1 tests, 0 failures TESTS (VERSION 1) Friday, September 6, 13
  21. # http://learnxinyminutes.com/docs/elixir/ defmodule Concurrency do def area_loop do receive do

    {:rectangle, w, h} -> IO.puts("Area = #{w * h}") area_loop() {:circle, r} -> IO.puts("Area = #{ :math.pi * r*r }") area_loop() end end def start do spawn(fn -> Concurrency.area_loop() end) end end Friday, September 6, 13
  22. pid = Concurrency.start pid <- {:rectangle, 3, 5} pid <-

    {:circle, 5} beastie:concurrency iex -r "lib/concurrency.ex" iex(1)> pid = Concurrency.start #PID<0.45.0> iex(2)> pid <- {:rectangle, 3, 5} Area = 15 {:rectangle, 3, 5} iex(3)> pid <- {:circle, 5} {:circle, 5} Area = 78.53981633974483 IEX - INTERACTIVE ELIXIR REPL Friday, September 6, 13
  23. defmodule Concurrency do def area_loop do receive do {:die} ->

    IO.puts “Bye cruel world!” input -> IO.puts Geometry.area(input) area_loop() end end def start do spawn(fn -> Concurrency.area_loop() end) end end defmodule Geometry do def area({ :rectangle, w, h }) do w * h end def area({ :circle, r }) do :math.pi * r * r end def area({ :cone, r, h }) do :math.pi * r * :math.sqrt( r * r + h * h) end end Friday, September 6, 13
  24. iex(1)> pid = Concurrency.start #PID<0.48.0> iex(2)> pid <- {:rectangle, 3,

    5} 15 {:rectangle, 3, 5} iex(3)> pid <- {:cone, 5, 10} {:cone, 5, 10} 175.62036827601816 iex(3)> pid <- {:die} {:die} Bye cruel World REFACTOR pid = Concurrency.start pid <- {:rectangle, 3, 5} pid <- {:cone, 5, 10} pid <- {:die} Friday, September 6, 13
  25. # Tuples - all the way down {:rectangle, 4, 5}

    # Linked Lists - Yay recursion! [head | tail] # Records - like structs defrecord FileInfo, atime: nil, accesses: 0 # Protocols - for polymorphism defprotocol Blank do @doc "Returns true if data is considered blank/empty" def blank?(data) end # Homoiconic - turtles all the way down Elixir is written in Elixir (esp macros) OTHER GOODIES Friday, September 6, 13
  26. LIBRARIES OF NOTE Ruby Elixir Link Rails Dynamo https://github.com/elixir-lang/dynamo Active

    Record Atlas https://github.com/chrismccord/atlas TestUnit ExUnit http://elixir-lang.org/getting_started/ex_unit/1.html Bundler & Rake Mix http://elixir-lang.org/getting_started/mix/1.html vim-ruby vim-elixir https://github.com/elixir-lang/vim-elixir Friday, September 6, 13
  27. UPCOMING BOOK - BECOMING AND LEVELING UP AS A DEVELOPER:

    FOLLOW @_ZPH ON TWITTER FOR UPDATES :) Friday, September 6, 13