Slide 1

Slide 1 text

Getting Started with Elixir. for Erlang, Ruby programmer 2015-11-02 / Sohei Takeno

Slide 2

Slide 2 text

About Elixir • Run on Erlang VM. • Its mechanism is same as Erlang. • Basic data types, module system etc. • Syntax is very similar to Ruby. • Following slides is a digest of Getting Started which assumes readers to know Erlang mechanism and Ruby syntax.

Slide 3

Slide 3 text

Setup • Install: `brew install elixir` • Start intreactive shell: `iex` # Let’s eval codes! • Run Script: `elixir <file>` • Compile: `elixirc <file>`

Slide 4

Slide 4 text

Data Types

Slide 5

Slide 5 text

Basic Data Types • integer, float, atom, byte, list, tuple • string: as byte string or list of integers. • boolean: as atom’s syntax sugar. • There are same built-in function as Erlang. • is_boolean/1, is_float/1 etc.

Slide 6

Slide 6 text

# integer 1 # float 1.0 # atom :atom # boolean true # list [1,2,3] # tuple {:ok,200} # byte string “Hello World” # list of integers ‘Hello World’ # byte data <<72, 101, 108, 108, 111, 32, 87>> true == :true #=> ? is_byte(“Hello”) #=> ? <<72, 101, 108, 108, 111, 32, 87>> == “Hello” #=> ? hd(‘Hello’) #=> ?

Slide 7

Slide 7 text

Keyword List • List of pairs of atom and value. • [{:a, 1}, {:b, 2}] • There is convenient syntax: • Create: [a: 1, b: 2] • Access: keywords[:a] #=> 1

Slide 8

Slide 8 text

Map (1) • General key-value data structure. • There is convenient syntax: • Create: %{1 => 'a', 2 => ‘b’} • Access: map[1] # => ‘a’ • Update: %{map | :a => 2} • Pattern matching: %{1 => value} = map

Slide 9

Slide 9 text

Map (2) • Syntax for map using atom for keys: • Initialize: %{a: 1, b: 2} • Access: map.a #=> 1 • Map and keyword list implement Dict behavior. • (Behavior is like interface of Java)

Slide 10

Slide 10 text

Function • Syntax: • Initialize: fn a, b -> a + b end • For pattern matching, write multiple 
 “ -> ”. • Get value o module function: &Enum.map/2 • Call: function_value.(1, 2) #=> 3

Slide 11

Slide 11 text

Boolean • There are two types of operators. • and, or accept only boolean. • &&, || accept any types. • nil and false are recognized as false value.

Slide 12

Slide 12 text

Control-Flow • case, cond, if, unless • To check a value, use case. • To check a condition generally, use cond. • Use if and unless for simple cases.

Slide 13

Slide 13 text

case {1, 2, 3} do {4, 5, 6} -> "won't match" {1, x, 3} -> "will match, and bind x to 2" _ -> "Would match any value" end cond do 1 + 1 == 0 -> “won’t match” 1 + 1 == 2 -> “will match” true -> “default” end if var == 2 do “true clause” else “false clause end

Slide 14

Slide 14 text

Keyword List as Arguments • Block is implemented as keyword list. • For example, is equals to: if 1 == 2 do “foo” else “bar” end if( 1 == 2, do: ”foo”, else: “bar” )

Slide 15

Slide 15 text

Note: Variable • Variable is beginning lowercase like foo = 1 • Reassigning new value is valid operation. • To use existing variable as value for pattern matching(e.g. right-hand side of =), Use pin-operator. • ^foo = 2 raise MatchError because foo binds to 1. • foo = 2 binds 2 to foo.

Slide 16

Slide 16 text

Module System

Slide 17

Slide 17 text

Module • Syntax: defmodule do … end • Define function: def sum(a,b) do … end • Write multiple def for pattern matching. • Use defp for private function.

Slide 18

Slide 18 text

# Define a module defmodule MyString do def lowercase(str) do # convert to lowercase string end # default value of `sep` is “,” def join(str_list, sep \\ “,") do # joins strings using the separator end end # Call module functions MyString.lowercase("Foo") #=> “foo" MyString.lowercase “Foo" #=> “foo" MyString.join(["Foo", "Bar", "Baz"]) #=> “Foo,Bar,Baz”

Slide 19

Slide 19 text

About Name Spaces • There are some operation to control naming. • alias Math.List as: List • import List, only: [duplicate: 2] • Mechanism of alias and import: • Module name is a atom(That’s all): is_atom(List) #=> true • Elixir add prefix “Elixir.” to module name: List == :”Elixir.List” => ? • So List.last(l) calls last function of module named :”Elixir.List”. • (alias and import simply manipulates these atom)

Slide 20

Slide 20 text

Protocol • Mechanism for polymorphism • Define: defprotocol Blank do … end • Use: defimpl Blank for: String do … end • for: Any add default implementation.

Slide 21

Slide 21 text

## Define a protocol defprotocol Blank do def blank?(data) end ## Implement a protocol defimpl Blank, for: List do def blank?([]), do: true def blank?(_), do: false end defimpl Blank, for: Any do def blank?(_), do: false end

Slide 22

Slide 22 text

Behavior • List of functions to implement(from Erlang). • Define: write like @callback parse(String.t) :: any in the behavior module (e.g. Parser). • We can use type specification also. • Use: write @behavior Parser in a module
 like JSONParser module. • Then compiler checks the behavior.

Slide 23

Slide 23 text

Error Handling

Slide 24

Slide 24 text

try-rescue and raise • Syntax: • Define exception: defexception in a module. • Generate exception: raise ErrorModule • Catch: try do … rescue … end • Use try-catch and throw for control-flow

Slide 25

Slide 25 text

# Define error module defmodule ParseError do defexception message: “This is default message” end # Use try do raise ParseError, message: “This is custom message” rescue e in ParseError -> IO.puts “Parse error(#{e.message}) was raised.” end

Slide 26

Slide 26 text

Other Mechanism from Erlang • Pattern-matching tuple • {:ok, value} or {:error, message} • This is major way in Erlnag/Elixir API. • Supervisor tree • exit notify error to supervisor.

Slide 27

Slide 27 text

Convenient Syntax

Slide 28

Slide 28 text

Sigils • Mechanism which realizes reg-exp literal. • Like this: ~r/https?/i • Interpreted as: sigil_r(“https?”, ‘i’) • Other example: • ~w(foo bar baz) #=> [“foo”, “bar”, “baz”]

Slide 29

Slide 29 text

Comprehensions • Popular understandable syntax. • Works for Enumerable values and byte strings(!). • Functions: Generator, Filter, Collector • Collector works with Collectable values.

Slide 30

Slide 30 text

# List comprehensions for dir <- dirs, # Generate from a list file <- File.ls!(dir), # Generate from a list(for each `dir`) path = Path.join(dir, file), # Binds values File.regular?(path) do # Filter by a predicate File.rm!(path) end # => [:ok, :ok, :ok, :ok, :ok] ## Note: In binding sections, you can filter by pattern-matching. # Bit comprehensions pixels = <<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>> for <>, do: {r, g, b} # => [{213,45,132},{64,76,32},{76,0,0},{234,32,15}] # Collect result to the stdio stream(echo program) stream = IO.stream(:stdio, :line) for line <- stream, into: stream do "#{line}\n" end

Slide 31

Slide 31 text

Rest Contents • This slides don’t include some specific contents: • Concrete modules like Enum, Stream, IO, File • Structs …like Maps but more robust. • Module Attributes(written like @foo) • Type Specificaton …via module attribute.