SlideShare una empresa de Scribd logo
1 de 96
Descargar para leer sin conexión
elixir
!
"
#


!


elixir
Interactive Elixir (1.0.3)
iex(1)> "Hello World"
"Hello World"
defmodule HelloWorld do
def say_it do
IO.puts "Hello World"
end
end
Interactive Elixir (1.0.3)
iex(1)> a = 1
1
iex(2)> a
1
iex(3)> 1 = a
1
iex(4)> 1 = 1
1
iex(5)> 1 = 2
** (MatchError) no match of right hand side value: 2
iex(6)> a = 2
2
iex(7)> ^a = 3
** (MatchError) no match of right hand side value: 3
Interactive Elixir (1.0.3)
iex(1)> a = {1, 2, 3}
{1, 2, 3}
iex(2)> {a, b, c} = {1, 2, 3}
{1, 2, 3}
iex(3)> [a, b, c]
[1, 2, 3]
iex(4)> [a, b, c | _] = [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
iex(5)> %{:a => a, :b => b, :c => c}
%{:a => 1, :b => 2, :c => 3}
defmodule Factorial do
def of(0), do: 1
def of(n) when n > 0 do
n * of(n - 1)
end
end
Interactive Elixir (1.0.3)
iex(1)> c("factorial.ex")
[Factorial]
iex(2)> Factorial.of(42)
1405006117752879898543142606244511569936384000000000
defmodule Bowling.Game do
def score([]), do: 0
def score([x, y]), do: x + y
def score([x, y, z]), do: x + y + z
def score([10, x, y | rolls]) do
10 + x + y + score([x, y | rolls])
end
def score([x, y, z | rolls]) when x + y == 10 do:
10 + z + score([z | rolls])
end
def score([x, y | rolls]), do: x + y + score(rolls)
end
defmodule Poker.Hand do
# [{:ace, :diamonds},
# {3, :spades},
# {3, :hearts},
# {3, :diamonds},
# {3, :clubs}] => {:four_of_a_kind, 3}
def identify([{r1, s}, {r2, s}, {r3, s}, {r4, s}, {r5, s}])
when [r2-r1, r3-r2, r4-r3, r5-r4] == [1, 1, 1, 1],
do: {:straight_flush, r5}
def identify([{_, s}, {_, s}, {_, s}, {_, s}, {r5, s}]),
do: {:flush, r5}
end
Interactive Elixir (1.0.3)
iex(1)> <<1, 2>>
<<1, 2>>
iex(2)> byte_size <<1, 2>>
2
iex(3)> byte_size <<1::size(4), 2::size(4)>>
1
iex(4)> is_binary "Hello"
true
iex(5)> <<"Hello">> == "Hello"
true
iex(6)> <<"H", tail::binary>> = "Hello"
"Hello"
iex(7)> tail
"ello"
Interactive Elixir (1.0.3)
iex(3)> mp3
<<73, 68, 51, 4, 0, 0, 0, 1, 95, ...>>
iex(4)> <<_::binary-size(mp3 - 128), id3::binary>> = mp3
<<73, 68, 51, 4, 0, 0, 0, 1, 95, ...>>
iex(5)> <<"TAG",
title::binary-size(30),
artist::binary-size(30),
album::binary-size(30),
year::binary-size(4),
comment::binary-size(30),
_rest::binary>> = id3
...
iex(6)> title
"Nothing Else Matters"
Interactive Elixir (1.0.3)
iex(1)> for n <- [1, 2, 3, 4], do: n
[1, 2, 3, 4]
iex(2)> for n <- [1, 2, 3, 4], do: n * n
[1, 4, 9, 16]
iex(3)> for n <- 1..4, do: n * n
for n <- 1..4, do: n * n
iex(6)> for n <- 1..100, rem(n, 3) == 0, do: n
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51,
54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
defmodule Sorting do
def quicksort([]), do: []
def quicksort([pivot | t]) do
quicksort(for x <- t, x <= pivot, do: x)
++ [pivot] ++
quicksort(for x <- t, x > pivot, do: x)
end
end
Interactive Elixir (1.0.3)
iex(1)> suits = [:clubs, :diamonds, :hearts, :spades]
[:clubs, :diamonds, :hearts, :spades]
iex(2)> ranks = [:ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, ...]
[:ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king]
iex(3)> deck = for rank <- ranks, suit <- suits, do: {rank, suit}
[{2, :clubs}, {2, :diamonds}, {2, :hearts}, {2, :spades},
{3, :clubs}, {3, :diamonds}, {3, :hearts}, {3, :spades},
{4, :clubs}, {4, :diamonds}, {4, :hearts}, {4, :spades}, ...]
iex(4)> Enum.shuffle(deck)
[{8, :diamonds}, {:jack, :clubs}, {2, :hearts}, {3, :hearts},
{:king, :hearts}, {9, :hearts}, {:king, :diamonds}, {9, :spades},
{10, :clubs}, {10, :spades}, {:king, :spades}, {2, :diamonds}, ...]
defmodule Crunch do
def of(something) do
filtered = filter(something)
sorted = sort(filtered)
grouped = group(sorted)
count(grouped)
end
end
defmodule Crunch do
def of(something) do
count(group(sort(filter(something))))
end
end
defmodule Crunch do
def of(something) do
something
|> filter
|> sort
|> group
|> count
end
end
Interactive Elixir (1.0.3)
iex(1)> ~s(this is a string with "double" and 'single' quotes)
"this is a string with "double" and 'single' quotes"
iex(2)> ~w(foo bar bat)
["foo", "bar", "bat"]
iex(3)> "foo" =~ ~r/foo|bar/
true
iex(4)> string = """
...(4)> This is a
...(4)> multiline string
...(4)> properly indented
...(4)> """
"This is anmultiline stringnproperly indentedn"
defmodule SExpression do
use Paco # parser combinator library
parser expression do
one_of([Parser.number, expression])
|> separated_by(~l","w)
|> surrounded_by(~l"("w, ~l")"w)
end
end
Interactive Elixir (1.0.3)
iex(1)> SExpression.parse! "(1, 2, (3, 4))"
[1, 2, [3, 4]]
defmodule Paco do
# ...
def sigil_l(lexeme, [?w]) do
lexeme |> surrounded_by(maybe(whitespaces))
end
# ...
end
defmodule Control do
def unless(clause, [do: expression]) do
if (!clause) do
expression
end
end
end
defmodule Control do
def unless(clause, [do: expression]) do
if (!clause) do
expression
end
end
end
defmodule Sandbox do
import Control
def try_unless(clause) do
unless clause do
IO.puts "Clause is false"
end
end
end
defmodule Control do
def unless(clause, [do: expression]) do
if (!clause) do
expression
end
end
end
Interactive Elixir (1.0.3)
iex(1)> Sandbox.try_unless(false)
Clause is false
:ok
iex(2)> Sandbox.try_unless(true)
Clause is false
:ok
defmodule Sandbox do
import Control
def try_unless(clause) do
unless clause do
IO.puts "Clause is false"
end
end
end
defmodule Control do
defmacro unless(clause, [do: expression]) do
quote do
if (not unquote(clause)) do
unquote(expression)
end
end
end
end
defmodule Control do
defmacro unless(clause, [do: expression]) do
quote do
if (not unquote(clause)) do
unquote(expression)
end
end
end
end
defmodule Sandbox do
import Control
def try_unless(clause) do
unless clause do
IO.puts "Clause is false"
end
end
end
defmodule Control do
defmacro unless(clause, [do: expression]) do
quote do
if (not unquote(clause)) do
unquote(expression)
end
end
end
end
Interactive Elixir (1.0.3)
iex(1)> Sandbox.try_unless(false)
Clause is false
:ok
iex(2)> Sandbox.try_unless(true)
nil
defmodule Sandbox do
import Control
def try_unless(clause) do
unless clause do
IO.puts "Clause is false"
end
end
end
Interactive Elixir (1.0.3)
iex(1)> quote do: 40 + 2
{:+, [], [40, 2]}
iex(2)> quote do: IO.puts "Hello World"
{
{
:.,
[],
[:IO, :puts]
},
[],
["Hello World"]
}
Interactive Elixir (1.0.3)
iex(1)> String.upcase("Jalapeño")
"JALAPEÑO"
iex(2)> String.reverse("Noël")
"lëoN"
Interactive Ruby (2.1.4)
irb(2.1.4) :001 > "Jalapeño".upcase
=> "JALAPEñO"
irb(2.1.4) :002 > "Noël".reverse
=> "l̈eoN"
defmodule String.Unicode do
# ...
for {codepoint, upper, _, _} <- codes,
upper && upper != codepoint do
defp do_upcase(unquote(codepoint) <> rest) do
unquote(upper) ++ do_upcase(rest)
end
end
# ...
end
defmodule String.Unicode do
# ...
for {codepoint, upper, _, _} <- codes,
upper && upper != codepoint do
defp do_upcase(unquote(codepoint) <> rest) do
unquote(upper) ++ do_upcase(rest)
end
end
# ...
end
01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6;
01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5
01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8;
01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7
01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA;
01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9
01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC;
01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB
01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E
01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF;
01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE
01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1;
01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0
01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3;
01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2
01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5;
01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4
01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7;
01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6
01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9;
01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8
01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;
defmodule Example.Router do
use Phoenix.Router
pipeline :browser do
plug :accepts, ~w(html)
plug :protect_from_forgery
end
pipeline :api do
plug :accepts, ~w(json)
end
scope "/", Example do
pipe_through :browser
get "/", HomeController, :index
end
end
defmodule Weather do
use Ecto.Model
schema "weather" do
field :city, :string
field :temp_lo, :integer
field :temp_hi, :integer
field :prcp, :float, default: 0.0
end
def cities_where_it_rains
Repo.all(
from w in Weather,
where: w.prcp > 0 or is_nil(w.prcp),
select: w
)
end
end
defmodule Kernel do
# ...
!
!
!
!
!
!
!
!
# ...
end
defmodule Kernel do
# ...
!
!
!
!
!
!
!
!
# ...
end
defmacro if(condition, clauses) do # ...
defmodule Kernel do
# ...
!
!
!
!
!
!
!
!
# ...
end
defmacro if(condition, clauses) do # ...
defmacro defmodule(alias, do: block) do # ...
defmodule Kernel do
# ...
!
!
!
!
!
!
!
!
# ...
end
defmacro if(condition, clauses) do # ...
defmacro defmodule(alias, do: block) do # ...
defmacro def(call, expr  nil) do # ...
defmodule Kernel do
# ...
!
!
!
!
!
!
!
!
# ...
end
defmacro if(condition, clauses) do # ...
defmacro defmodule(alias, do: block) do # ...
defmacro def(call, expr  nil) do # ...
defmacro defmacro(call, expr  nil) do # ...
defmodule Control do
defmacro unless(clause, [do: expression]) do
quote do
if (not unquote(clause)) do
unquote(expression)
end
end
end
end
defmodule Control do
defmacro unless(clause, [do: expression]) do
quote do
if (not unquote(clause)) do
unquote(expression)
end
end
end
end
defmodule Sandbox do
import Kernel, except: [unless: 2]
import Control
def try_unless(clause) do
unless clause do
IO.puts "Clause is false"
end
end
end
defmodule Control do
defmacro unless(clause, [do: expression]) do
quote do
if (not unquote(clause)) do
unquote(expression)
end
end
end
end
defmodule Sandbox do
import Kernel, except: [unless: 2]
import Control
def try_unless(clause) do
unless clause do
IO.puts "Clause is false"
end
end
end
!
$ mix new bowling_game
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/bowling_game.ex
* creating test
* creating test/test_helper.exs
* creating test/bowling_game_test.exs
$ cd bowling_game
$ mix compile
Compiled lib/bowling_game.ex
Generated bowling_game.app
$ mix mix help
mix # Run the default task (current: mix run)
mix archive # List all archives
mix archive.build # Archive this project into a .ez file
mix archive.install # Install an archive locally
mix archive.uninstall # Uninstall archives
mix clean # Delete generated application files
mix cmd # Executes the given command
mix compile # Compile source files
mix compile.protocols # Consolidates all protocols in all paths
mix deps # List dependencies and their status
mix deps.clean # Remove the given dependencies' files
mix deps.compile # Compile dependencies
mix deps.get # Get all out of date dependencies
mix deps.unlock # Unlock the given dependencies
mix deps.update # Update the given dependencies
...
defmodule Bowling.Game.Test do
import Bowling.Game
use ExUnit.Case
!
test "score is 0 for all zeros" do
assert score(roll_many(20, 0)) == 0
end
!
test "score is 20 for all ones" do
assert score(roll_many(20, 1)) == 20
end
!
test "a throw counts twice after a spare" do
assert score([5, 5, 3 | roll_many(17, 0)]) == 16
assert score([0, 10, 3 | roll_many(17, 0)]) == 16
end
!
# ...
end
defmodule Bowling.Game.Test do
import Bowling.Game
use ExUnit.Case
!
test "score is 0 for all zeros" do
assert score(roll_many(20, 0)) == 0
end
!
test "score is 20 for all ones" do
assert score(roll_many(20, 1)) == 20
end
!
test "a throw counts twice after a spare" do
assert score([5, 5, 3 | roll_many(17, 0)]) == 16
assert score([0, 10, 3 | roll_many(17, 0)]) == 16
end
!
# ...
end
$ mix test
.......
!
Finished in 0.09 seconds (0.09s on load, 0.00s on tests)
7 tests, 0 failures
!
Randomized with seed 825783
defmodule Bowling.Game.Test do
import Bowling.Game
use ExUnit.Case
!
test "score is 0 for all zeros" do
assert score(roll_many(20, 0)) == 0
end
!
test "score is 20 for all ones" do
assert score(roll_many(20, 1)) == 20
end
!
test "a throw counts twice after a spare" do
assert score([5, 5, 3 | roll_many(17, 0)]) == 16
assert score([0, 10, 3 | roll_many(17, 0)]) == 16
end
!
# ...
end
$ mix test
.......
!
Finished in 0.09 seconds (0.09s on load, 0.00s on tests)
7 tests, 0 failures
!
Randomized with seed 825783
$ mix test
1) test score is 0 for all zeros (Bowling.Game.Test)
test/bowling_game_test.exs:5
Assertion with == failed
code: score(roll_many(20, 0)) == 1
lhs: 0
rhs: 1
stacktrace:
test/bowling_game_test.exs:6
!
......
!
Finished in 0.1 seconds (0.08s on load, 0.02s on tests)
7 tests, 1 failures
!
Randomized with seed 416239
defmodule Bowling.Game do
@spec score([0..10]) :: 0..300
def score([]), do: 0
def score([x, y]), do: x + y
def score([x, y, z]), do: x + y + z
# ...
end
defmodule Bowling.Game do
@spec score([0..10]) :: 0..300
def score([]), do: 0
def score([x, y]), do: x + y
def score([x, y, z]), do: x + y + z
# ...
end
$ mix dialyzer
Starting Dialyzer
Proceeding with analysis... done in 0m0.94s
done (passed successfully)
defmodule Bowling.Game do
def broke, do: score(:boom)
@spec score([0..10]) :: 0..300
def score([]), do: 0
def score([x, y]), do: x + y
def score([x, y, z]), do: x + y + z
# ...
end
defmodule Bowling.Game do
def broke, do: score(:boom)
@spec score([0..10]) :: 0..300
def score([]), do: 0
def score([x, y]), do: x + y
def score([x, y, z]), do: x + y + z
# ...
end
$ mix dialyzer
Starting Dialyzer
Proceeding with analysis...
bowling_game.ex:29: Function broke/0 has no local return
bowling_game.ex:30: The call 'Elixir.Bowling.Game':score('boom') will
never return since the success typing is ([number()]) -> number() and
the contract is ([0..10]) -> 0..300
done in 0m0.90s
done (warnings were emitted)
defmodule Bowling.Game do
@moduledoc """
Given a valid sequence of rolls for one line of American Ten-Pin Bowling ...
* We will not check for valid rolls.
* We will not check for correct number of rolls and frames.
* We will not provide scores for intermediate frames.
...
"""
@doc """
Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score
!
## Examples
iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4])
86
"""
@spec score([0..10]) :: 0..300
def score([]), do: 0
# ...
end
defmodule Bowling.Game do
@moduledoc """
Given a valid sequence of rolls for one line of American Ten-Pin Bowling ...
* We will not check for valid rolls.
* We will not check for correct number of rolls and frames.
* We will not provide scores for intermediate frames.
...
"""
@doc """
Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score
!
## Examples
iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4])
86
"""
@spec score([0..10]) :: 0..300
def score([]), do: 0
# ...
end
iex(1)> h Bowling.Game
!
Bowling.Game
!
Given a valid sequence of rolls for one line of American Ten-Pin
Bowling, produces the total score for the game. Here are some things
that the program will not do:
!
• We will not check for valid rolls.
• We will not check for correct number of rolls and frames.
• We will not provide scores for intermediate frames.
!
We can briefly summarize the scoring for this form of bowling:
...
defmodule Bowling.Game do
@moduledoc """
Given a valid sequence of rolls for one line of American Ten-Pin Bowling ...
* We will not check for valid rolls.
* We will not check for correct number of rolls and frames.
* We will not provide scores for intermediate frames.
...
"""
@doc """
Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score
!
## Examples
iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4])
86
"""
@spec score([0..10]) :: 0..300
def score([]), do: 0
# ...
end
iex(1)> h Bowling.Game
!
Bowling.Game
!
Given a valid sequence of rolls for one line of American Ten-Pin
Bowling, produces the total score for the game. Here are some things
that the program will not do:
!
• We will not check for valid rolls.
• We will not check for correct number of rolls and frames.
• We will not provide scores for intermediate frames.
!
We can briefly summarize the scoring for this form of bowling:
...
iex(2)> h Bowling.Game.score
!
def scrore(list)
!
Given a sequence of rolls for one line of American Ten-Pin Bowling
returns the total score for the game
!
Examples
!
┃ iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3,
┃ 87
defmodule Bowling.Game do
@moduledoc """
Given a valid sequence of rolls for one line of American Ten-Pin Bowling ...
* We will not check for valid rolls.
* We will not check for correct number of rolls and frames.
* We will not provide scores for intermediate frames.
...
"""
@doc """
Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score
!
## Examples
iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4])
86
"""
@spec score([0..10]) :: 0..300
def score([]), do: 0
# ...
end
defmodule Bowling.Game do
@moduledoc """
Given a valid sequence of rolls for one line of American Ten-Pin Bowling ...
* We will not check for valid rolls.
* We will not check for correct number of rolls and frames.
* We will not provide scores for intermediate frames.
...
"""
@doc """
Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score
!
## Examples
iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4])
86
"""
@spec score([0..10]) :: 0..300
def score([]), do: 0
# ...
end
$ mix docs
Docs successfully generated.
View them at "doc/index.html".
defmodule Bowling.Game do
@moduledoc """
Given a valid sequence of rolls for one line of American Ten-Pin Bowling ...
* We will not check for valid rolls.
* We will not check for correct number of rolls and frames.
* We will not provide scores for intermediate frames.
...
"""
@doc """
Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score
!
## Examples
iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4])
86
"""
@spec score([0..10]) :: 0..300
def score([]), do: 0
# ...
end
$ mix docs
Docs successfully generated.
View them at "doc/index.html".
defmodule Bowling.Game.Test do
import Bowling.Game
use ExUnit.Case
!
doctest Bowling.Game
!
test "score is 0 for all zeros" do
assert score(roll_many(20, 0)) == 0
end
!
test "score is 20 for all ones" do
assert score(roll_many(20, 1)) == 20
end
!
# ...
end
defmodule Bowling.Game.Test do
import Bowling.Game
use ExUnit.Case
!
doctest Bowling.Game
!
test "score is 0 for all zeros" do
assert score(roll_many(20, 0)) == 0
end
!
test "score is 20 for all ones" do
assert score(roll_many(20, 1)) == 20
end
!
# ...
end
$ mix test
1) test doc at Bowling.Game.score/1 (1) (Bowling.Game.Test)
test/bowling_game_test.exs:5
Doctest failed
code: Bowling.Game.score([10, 2, 3, 5, 5, ..., 4, 4]) === 86
lhs: 87
stacktrace:
lib/bowling_game.ex:31: Bowling.Game (module)
!
.......
!
Finished in 0.1 seconds (0.1s on load, 0.01s on tests)
8 tests, 1 failures
!
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
iex(2)> :timer.tc(Ring, :start, [10_000])
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
iex(2)> :timer.tc(Ring, :start, [10_000])
{12431, :ok}
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
iex(2)> :timer.tc(Ring, :start, [10_000])
{12431, :ok}
iex(3)> :timer.tc(Ring, :start, [1_000_000])
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
iex(2)> :timer.tc(Ring, :start, [10_000])
{12431, :ok}
iex(3)> :timer.tc(Ring, :start, [1_000_000])
{1512394, :ok}
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
iex(2)> :timer.tc(Ring, :start, [10_000])
{12431, :ok}
iex(3)> :timer.tc(Ring, :start, [1_000_000])
{1512394, :ok}
iex(4)> :timer.tc(Ring, :start, [10_000_000])
defmodule Ring do
def start(n) do
start(n, self)
end
!
def start(0, first) do
send(first, :ok)
end
!
def start(n, first) do
spawn(fn -> start(n - 1, first) end)
|> send(:ok)
receive do
:ok -> :ok
end
end
end
Interactive Elixir (1.0.3)
iex(1)> :timer.tc(Ring, :start, [1_000])
{1677, :ok}
iex(2)> :timer.tc(Ring, :start, [10_000])
{12431, :ok}
iex(3)> :timer.tc(Ring, :start, [1_000_000])
{1512394, :ok}
iex(4)> :timer.tc(Ring, :start, [10_000_000])
{15207638, :ok}
defmodule Counter do
def start(n) do
spawn(fn -> loop(n) end)
end
!
def down(pid), do: send(pid, :down)
!
defp loop(n) do
IO.puts "Counter at #{n}"
receive do
:down when n == 1 ->
IO.puts "That's it, bye!"
:down ->
loop(n - 1)
_ ->
loop(n)
end
end
end
defmodule Counter do
def start(n) do
spawn(fn -> loop(n) end)
end
!
def down(pid), do: send(pid, :down)
!
defp loop(n) do
IO.puts "Counter at #{n}"
receive do
:down when n == 1 ->
IO.puts "That's it, bye!"
:down ->
loop(n - 1)
_ ->
loop(n)
end
end
end
Interactive Elixir (1.0.3)
iex(1)> s = Counter.start(3)
Counter at 3
#PID<0.113.0>
iex(2)> Process.alive? s
true
iex(3)> Counter.down
Counter at 2
:down
iex(4)> Counter.down
Counter at 1
:down
iex(5)> Counter.down
That's it, bye!
:down
iex(2)> Process.alive? s
false


⚠
#
Elixir introduction with examples
Elixir introduction with examples
Elixir introduction with examples

Más contenido relacionado

La actualidad más candente

Ruby closures, how are they possible?
Ruby closures, how are they possible?Ruby closures, how are they possible?
Ruby closures, how are they possible?Carlos Alonso Pérez
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlordsheumann
 
The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189Mahmoud Samir Fayed
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type Systemabrummett
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPaweł Dawczak
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monadJarek Ratajski
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redispauldix
 
Python tutorialfeb152012
Python tutorialfeb152012Python tutorialfeb152012
Python tutorialfeb152012Shani729
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of SmartmatchAndrew Shitov
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin IGuixing Bai
 
Python tutorial
Python tutorialPython tutorial
Python tutorialRajiv Risi
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Try Redis - interactive Tutorial
Try Redis - interactive TutorialTry Redis - interactive Tutorial
Try Redis - interactive TutorialEdward Lee
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?Nikita Popov
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194Mahmoud Samir Fayed
 
Swift에서 꼬리재귀 사용기 (Tail Recursion)
Swift에서 꼬리재귀 사용기 (Tail Recursion)Swift에서 꼬리재귀 사용기 (Tail Recursion)
Swift에서 꼬리재귀 사용기 (Tail Recursion)진성 오
 

La actualidad más candente (20)

Ruby closures, how are they possible?
Ruby closures, how are they possible?Ruby closures, how are they possible?
Ruby closures, how are they possible?
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Pure kotlin
Pure kotlinPure kotlin
Pure kotlin
 
The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to Elixir
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monad
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redis
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
Python tutorialfeb152012
Python tutorialfeb152012Python tutorialfeb152012
Python tutorialfeb152012
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
PubNative Tracker
PubNative TrackerPubNative Tracker
PubNative Tracker
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin I
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Try Redis - interactive Tutorial
Try Redis - interactive TutorialTry Redis - interactive Tutorial
Try Redis - interactive Tutorial
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194
 
Swift에서 꼬리재귀 사용기 (Tail Recursion)
Swift에서 꼬리재귀 사용기 (Tail Recursion)Swift에서 꼬리재귀 사용기 (Tail Recursion)
Swift에서 꼬리재귀 사용기 (Tail Recursion)
 

Destacado

Professional Programmer (3 Years Later)
Professional Programmer (3 Years Later)Professional Programmer (3 Years Later)
Professional Programmer (3 Years Later)Gabriele Lana
 
Professional Programmer
Professional ProgrammerProfessional Programmer
Professional ProgrammerGabriele Lana
 
Elixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding themElixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding themDan Janowski
 
How Elixir helped us scale our Video User Profile Service for the Olympics
How Elixir helped us scale our Video User Profile Service for the OlympicsHow Elixir helped us scale our Video User Profile Service for the Olympics
How Elixir helped us scale our Video User Profile Service for the OlympicsEmerson Macedo
 
Elixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and SupervisorsElixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and SupervisorsBenjamin Tan
 
Learn Elixir at Manchester Lambda Lounge
Learn Elixir at Manchester Lambda LoungeLearn Elixir at Manchester Lambda Lounge
Learn Elixir at Manchester Lambda LoungeChi-chi Ekweozor
 
Building a Network IP Camera using Erlang
Building a Network IP Camera using ErlangBuilding a Network IP Camera using Erlang
Building a Network IP Camera using ErlangFrank Hunleth
 
Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to ElixirDiacode
 
Spark as a distributed Scala
Spark as a distributed ScalaSpark as a distributed Scala
Spark as a distributed ScalaAlex Fruzenshtein
 
ELIXIR Webinar: Introducing TeSS
ELIXIR Webinar: Introducing TeSSELIXIR Webinar: Introducing TeSS
ELIXIR Webinar: Introducing TeSSNiall Beard
 
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011Mustafa TURAN
 
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발Changwook Park
 
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov Elixir Club
 
Control flow in_elixir
Control flow in_elixirControl flow in_elixir
Control flow in_elixirAnna Neyzberg
 
Minimum Viable Product
Minimum Viable ProductMinimum Viable Product
Minimum Viable ProductGabriele Lana
 

Destacado (20)

Professional Programmer (3 Years Later)
Professional Programmer (3 Years Later)Professional Programmer (3 Years Later)
Professional Programmer (3 Years Later)
 
API Over HTTP
API Over HTTPAPI Over HTTP
API Over HTTP
 
Professional Programmer
Professional ProgrammerProfessional Programmer
Professional Programmer
 
Elixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding themElixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding them
 
How Elixir helped us scale our Video User Profile Service for the Olympics
How Elixir helped us scale our Video User Profile Service for the OlympicsHow Elixir helped us scale our Video User Profile Service for the Olympics
How Elixir helped us scale our Video User Profile Service for the Olympics
 
Elixir basics-2
Elixir basics-2Elixir basics-2
Elixir basics-2
 
Elixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and SupervisorsElixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and Supervisors
 
Learn Elixir at Manchester Lambda Lounge
Learn Elixir at Manchester Lambda LoungeLearn Elixir at Manchester Lambda Lounge
Learn Elixir at Manchester Lambda Lounge
 
Building a Network IP Camera using Erlang
Building a Network IP Camera using ErlangBuilding a Network IP Camera using Erlang
Building a Network IP Camera using Erlang
 
Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to Elixir
 
Spark as a distributed Scala
Spark as a distributed ScalaSpark as a distributed Scala
Spark as a distributed Scala
 
ELIXIR Webinar: Introducing TeSS
ELIXIR Webinar: Introducing TeSSELIXIR Webinar: Introducing TeSS
ELIXIR Webinar: Introducing TeSS
 
Big Data eBook
Big Data eBookBig Data eBook
Big Data eBook
 
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
 
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
 
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
 
Control flow in_elixir
Control flow in_elixirControl flow in_elixir
Control flow in_elixir
 
Spring IO for startups
Spring IO for startupsSpring IO for startups
Spring IO for startups
 
Minimum Viable Product
Minimum Viable ProductMinimum Viable Product
Minimum Viable Product
 
Magic of Ruby
Magic of RubyMagic of Ruby
Magic of Ruby
 

Similar a Elixir introduction with examples

A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
python chapter 1
python chapter 1python chapter 1
python chapter 1Raghu nath
 
Python chapter 2
Python chapter 2Python chapter 2
Python chapter 2Raghu nath
 
C Code and the Art of Obfuscation
C Code and the Art of ObfuscationC Code and the Art of Obfuscation
C Code and the Art of Obfuscationguest9006ab
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語ikdysfm
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixirKent Ohashi
 
Nullcon HackIM 2012 Solutions
Nullcon HackIM 2012 SolutionsNullcon HackIM 2012 Solutions
Nullcon HackIM 2012 SolutionsNilanjan De
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009Jordan Baker
 
Extending Operators in Perl with Operator::Util
Extending Operators in Perl with Operator::UtilExtending Operators in Perl with Operator::Util
Extending Operators in Perl with Operator::UtilNova Patch
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a ElixirSvet Ivantchev
 
The Ring programming language version 1.5.2 book - Part 24 of 181
The Ring programming language version 1.5.2 book - Part 24 of 181The Ring programming language version 1.5.2 book - Part 24 of 181
The Ring programming language version 1.5.2 book - Part 24 of 181Mahmoud Samir Fayed
 
Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School ProgrammersSiva Arunachalam
 
Thinking Functionally In Ruby
Thinking Functionally In RubyThinking Functionally In Ruby
Thinking Functionally In RubyRoss Lawley
 
Ecto DSL Introduction - Yurii Bodarev
Ecto DSL Introduction - Yurii BodarevEcto DSL Introduction - Yurii Bodarev
Ecto DSL Introduction - Yurii BodarevElixir Club
 
Yurii Bodarev - Ecto DSL
Yurii Bodarev - Ecto DSLYurii Bodarev - Ecto DSL
Yurii Bodarev - Ecto DSLElixir Club
 

Similar a Elixir introduction with examples (20)

Basics
BasicsBasics
Basics
 
Elixir @ Paris.rb
Elixir @ Paris.rbElixir @ Paris.rb
Elixir @ Paris.rb
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
python chapter 1
python chapter 1python chapter 1
python chapter 1
 
Python chapter 2
Python chapter 2Python chapter 2
Python chapter 2
 
Term Rewriting
Term RewritingTerm Rewriting
Term Rewriting
 
C Code and the Art of Obfuscation
C Code and the Art of ObfuscationC Code and the Art of Obfuscation
C Code and the Art of Obfuscation
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
Nullcon HackIM 2012 Solutions
Nullcon HackIM 2012 SolutionsNullcon HackIM 2012 Solutions
Nullcon HackIM 2012 Solutions
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Extending Operators in Perl with Operator::Util
Extending Operators in Perl with Operator::UtilExtending Operators in Perl with Operator::Util
Extending Operators in Perl with Operator::Util
 
Into Clojure
Into ClojureInto Clojure
Into Clojure
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a Elixir
 
The Ring programming language version 1.5.2 book - Part 24 of 181
The Ring programming language version 1.5.2 book - Part 24 of 181The Ring programming language version 1.5.2 book - Part 24 of 181
The Ring programming language version 1.5.2 book - Part 24 of 181
 
7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School Programmers
 
Thinking Functionally In Ruby
Thinking Functionally In RubyThinking Functionally In Ruby
Thinking Functionally In Ruby
 
Ecto DSL Introduction - Yurii Bodarev
Ecto DSL Introduction - Yurii BodarevEcto DSL Introduction - Yurii Bodarev
Ecto DSL Introduction - Yurii Bodarev
 
Yurii Bodarev - Ecto DSL
Yurii Bodarev - Ecto DSLYurii Bodarev - Ecto DSL
Yurii Bodarev - Ecto DSL
 

Más de Gabriele Lana

Microservice Architectures
Microservice ArchitecturesMicroservice Architectures
Microservice ArchitecturesGabriele Lana
 
Professional Programmer 2018
Professional Programmer 2018Professional Programmer 2018
Professional Programmer 2018Gabriele Lana
 
Resource Oriented Design
Resource Oriented DesignResource Oriented Design
Resource Oriented DesignGabriele Lana
 
Agileday Coderetreat 2013
Agileday Coderetreat 2013Agileday Coderetreat 2013
Agileday Coderetreat 2013Gabriele Lana
 
Milano Legacy Coderetreat 2013
Milano Legacy Coderetreat 2013Milano Legacy Coderetreat 2013
Milano Legacy Coderetreat 2013Gabriele Lana
 
It is not supposed to fly but it does
It is not supposed to fly but it doesIt is not supposed to fly but it does
It is not supposed to fly but it doesGabriele Lana
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to NodejsGabriele Lana
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with ExamplesGabriele Lana
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartGabriele Lana
 
Erlang: the language and the platform
Erlang: the language and the platformErlang: the language and the platform
Erlang: the language and the platformGabriele Lana
 
Resource Oriented Architectures
Resource Oriented ArchitecturesResource Oriented Architectures
Resource Oriented ArchitecturesGabriele Lana
 
Sustainable Agile Development
Sustainable Agile DevelopmentSustainable Agile Development
Sustainable Agile DevelopmentGabriele Lana
 
Introduction to Erlang
Introduction to ErlangIntroduction to Erlang
Introduction to ErlangGabriele Lana
 

Más de Gabriele Lana (20)

Microservice Architectures
Microservice ArchitecturesMicroservice Architectures
Microservice Architectures
 
Professional Programmer 2018
Professional Programmer 2018Professional Programmer 2018
Professional Programmer 2018
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Resource Oriented Design
Resource Oriented DesignResource Oriented Design
Resource Oriented Design
 
Agileday Coderetreat 2013
Agileday Coderetreat 2013Agileday Coderetreat 2013
Agileday Coderetreat 2013
 
Milano Legacy Coderetreat 2013
Milano Legacy Coderetreat 2013Milano Legacy Coderetreat 2013
Milano Legacy Coderetreat 2013
 
coderetreat
coderetreatcoderetreat
coderetreat
 
It is not supposed to fly but it does
It is not supposed to fly but it doesIt is not supposed to fly but it does
It is not supposed to fly but it does
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to Nodejs
 
MongoDB With Style
MongoDB With StyleMongoDB With Style
MongoDB With Style
 
Nosql
NosqlNosql
Nosql
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 
Why couchdb is cool
Why couchdb is coolWhy couchdb is cool
Why couchdb is cool
 
ProgrammingKatas
ProgrammingKatasProgrammingKatas
ProgrammingKatas
 
CouchDB Vs MongoDB
CouchDB Vs MongoDBCouchDB Vs MongoDB
CouchDB Vs MongoDB
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
 
Erlang: the language and the platform
Erlang: the language and the platformErlang: the language and the platform
Erlang: the language and the platform
 
Resource Oriented Architectures
Resource Oriented ArchitecturesResource Oriented Architectures
Resource Oriented Architectures
 
Sustainable Agile Development
Sustainable Agile DevelopmentSustainable Agile Development
Sustainable Agile Development
 
Introduction to Erlang
Introduction to ErlangIntroduction to Erlang
Introduction to Erlang
 

Último

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 

Último (20)

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 

Elixir introduction with examples

  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8. !
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 18.
  • 19. Interactive Elixir (1.0.3) iex(1)> "Hello World" "Hello World" defmodule HelloWorld do def say_it do IO.puts "Hello World" end end
  • 20. Interactive Elixir (1.0.3) iex(1)> a = 1 1 iex(2)> a 1 iex(3)> 1 = a 1 iex(4)> 1 = 1 1 iex(5)> 1 = 2 ** (MatchError) no match of right hand side value: 2 iex(6)> a = 2 2 iex(7)> ^a = 3 ** (MatchError) no match of right hand side value: 3
  • 21. Interactive Elixir (1.0.3) iex(1)> a = {1, 2, 3} {1, 2, 3} iex(2)> {a, b, c} = {1, 2, 3} {1, 2, 3} iex(3)> [a, b, c] [1, 2, 3] iex(4)> [a, b, c | _] = [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6] iex(5)> %{:a => a, :b => b, :c => c} %{:a => 1, :b => 2, :c => 3}
  • 22. defmodule Factorial do def of(0), do: 1 def of(n) when n > 0 do n * of(n - 1) end end Interactive Elixir (1.0.3) iex(1)> c("factorial.ex") [Factorial] iex(2)> Factorial.of(42) 1405006117752879898543142606244511569936384000000000
  • 23. defmodule Bowling.Game do def score([]), do: 0 def score([x, y]), do: x + y def score([x, y, z]), do: x + y + z def score([10, x, y | rolls]) do 10 + x + y + score([x, y | rolls]) end def score([x, y, z | rolls]) when x + y == 10 do: 10 + z + score([z | rolls]) end def score([x, y | rolls]), do: x + y + score(rolls) end
  • 24. defmodule Poker.Hand do # [{:ace, :diamonds}, # {3, :spades}, # {3, :hearts}, # {3, :diamonds}, # {3, :clubs}] => {:four_of_a_kind, 3} def identify([{r1, s}, {r2, s}, {r3, s}, {r4, s}, {r5, s}]) when [r2-r1, r3-r2, r4-r3, r5-r4] == [1, 1, 1, 1], do: {:straight_flush, r5} def identify([{_, s}, {_, s}, {_, s}, {_, s}, {r5, s}]), do: {:flush, r5} end
  • 25. Interactive Elixir (1.0.3) iex(1)> <<1, 2>> <<1, 2>> iex(2)> byte_size <<1, 2>> 2 iex(3)> byte_size <<1::size(4), 2::size(4)>> 1 iex(4)> is_binary "Hello" true iex(5)> <<"Hello">> == "Hello" true iex(6)> <<"H", tail::binary>> = "Hello" "Hello" iex(7)> tail "ello"
  • 26. Interactive Elixir (1.0.3) iex(3)> mp3 <<73, 68, 51, 4, 0, 0, 0, 1, 95, ...>> iex(4)> <<_::binary-size(mp3 - 128), id3::binary>> = mp3 <<73, 68, 51, 4, 0, 0, 0, 1, 95, ...>> iex(5)> <<"TAG", title::binary-size(30), artist::binary-size(30), album::binary-size(30), year::binary-size(4), comment::binary-size(30), _rest::binary>> = id3 ... iex(6)> title "Nothing Else Matters"
  • 27. Interactive Elixir (1.0.3) iex(1)> for n <- [1, 2, 3, 4], do: n [1, 2, 3, 4] iex(2)> for n <- [1, 2, 3, 4], do: n * n [1, 4, 9, 16] iex(3)> for n <- 1..4, do: n * n for n <- 1..4, do: n * n iex(6)> for n <- 1..100, rem(n, 3) == 0, do: n [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
  • 28. defmodule Sorting do def quicksort([]), do: [] def quicksort([pivot | t]) do quicksort(for x <- t, x <= pivot, do: x) ++ [pivot] ++ quicksort(for x <- t, x > pivot, do: x) end end
  • 29. Interactive Elixir (1.0.3) iex(1)> suits = [:clubs, :diamonds, :hearts, :spades] [:clubs, :diamonds, :hearts, :spades] iex(2)> ranks = [:ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, ...] [:ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king] iex(3)> deck = for rank <- ranks, suit <- suits, do: {rank, suit} [{2, :clubs}, {2, :diamonds}, {2, :hearts}, {2, :spades}, {3, :clubs}, {3, :diamonds}, {3, :hearts}, {3, :spades}, {4, :clubs}, {4, :diamonds}, {4, :hearts}, {4, :spades}, ...] iex(4)> Enum.shuffle(deck) [{8, :diamonds}, {:jack, :clubs}, {2, :hearts}, {3, :hearts}, {:king, :hearts}, {9, :hearts}, {:king, :diamonds}, {9, :spades}, {10, :clubs}, {10, :spades}, {:king, :spades}, {2, :diamonds}, ...]
  • 30. defmodule Crunch do def of(something) do filtered = filter(something) sorted = sort(filtered) grouped = group(sorted) count(grouped) end end
  • 31. defmodule Crunch do def of(something) do count(group(sort(filter(something)))) end end
  • 32. defmodule Crunch do def of(something) do something |> filter |> sort |> group |> count end end
  • 33. Interactive Elixir (1.0.3) iex(1)> ~s(this is a string with "double" and 'single' quotes) "this is a string with "double" and 'single' quotes" iex(2)> ~w(foo bar bat) ["foo", "bar", "bat"] iex(3)> "foo" =~ ~r/foo|bar/ true iex(4)> string = """ ...(4)> This is a ...(4)> multiline string ...(4)> properly indented ...(4)> """ "This is anmultiline stringnproperly indentedn"
  • 34. defmodule SExpression do use Paco # parser combinator library parser expression do one_of([Parser.number, expression]) |> separated_by(~l","w) |> surrounded_by(~l"("w, ~l")"w) end end Interactive Elixir (1.0.3) iex(1)> SExpression.parse! "(1, 2, (3, 4))" [1, 2, [3, 4]]
  • 35. defmodule Paco do # ... def sigil_l(lexeme, [?w]) do lexeme |> surrounded_by(maybe(whitespaces)) end # ... end
  • 36. defmodule Control do def unless(clause, [do: expression]) do if (!clause) do expression end end end
  • 37. defmodule Control do def unless(clause, [do: expression]) do if (!clause) do expression end end end defmodule Sandbox do import Control def try_unless(clause) do unless clause do IO.puts "Clause is false" end end end
  • 38. defmodule Control do def unless(clause, [do: expression]) do if (!clause) do expression end end end Interactive Elixir (1.0.3) iex(1)> Sandbox.try_unless(false) Clause is false :ok iex(2)> Sandbox.try_unless(true) Clause is false :ok defmodule Sandbox do import Control def try_unless(clause) do unless clause do IO.puts "Clause is false" end end end
  • 39. defmodule Control do defmacro unless(clause, [do: expression]) do quote do if (not unquote(clause)) do unquote(expression) end end end end
  • 40. defmodule Control do defmacro unless(clause, [do: expression]) do quote do if (not unquote(clause)) do unquote(expression) end end end end defmodule Sandbox do import Control def try_unless(clause) do unless clause do IO.puts "Clause is false" end end end
  • 41. defmodule Control do defmacro unless(clause, [do: expression]) do quote do if (not unquote(clause)) do unquote(expression) end end end end Interactive Elixir (1.0.3) iex(1)> Sandbox.try_unless(false) Clause is false :ok iex(2)> Sandbox.try_unless(true) nil defmodule Sandbox do import Control def try_unless(clause) do unless clause do IO.puts "Clause is false" end end end
  • 42. Interactive Elixir (1.0.3) iex(1)> quote do: 40 + 2 {:+, [], [40, 2]} iex(2)> quote do: IO.puts "Hello World" { { :., [], [:IO, :puts] }, [], ["Hello World"] }
  • 43. Interactive Elixir (1.0.3) iex(1)> String.upcase("Jalapeño") "JALAPEÑO" iex(2)> String.reverse("Noël") "lëoN" Interactive Ruby (2.1.4) irb(2.1.4) :001 > "Jalapeño".upcase => "JALAPEñO" irb(2.1.4) :002 > "Noël".reverse => "l̈eoN"
  • 44. defmodule String.Unicode do # ... for {codepoint, upper, _, _} <- codes, upper && upper != codepoint do defp do_upcase(unquote(codepoint) <> rest) do unquote(upper) ++ do_upcase(rest) end end # ... end
  • 45. defmodule String.Unicode do # ... for {codepoint, upper, _, _} <- codes, upper && upper != codepoint do defp do_upcase(unquote(codepoint) <> rest) do unquote(upper) ++ do_upcase(rest) end end # ... end 01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6; 01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5 01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8; 01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7 01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA; 01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9 01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC; 01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB 01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E 01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF; 01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE 01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; 01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3; 01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2 01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; 01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; 01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6 01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9; 01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8 01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;
  • 46. defmodule Example.Router do use Phoenix.Router pipeline :browser do plug :accepts, ~w(html) plug :protect_from_forgery end pipeline :api do plug :accepts, ~w(json) end scope "/", Example do pipe_through :browser get "/", HomeController, :index end end
  • 47. defmodule Weather do use Ecto.Model schema "weather" do field :city, :string field :temp_lo, :integer field :temp_hi, :integer field :prcp, :float, default: 0.0 end def cities_where_it_rains Repo.all( from w in Weather, where: w.prcp > 0 or is_nil(w.prcp), select: w ) end end
  • 48. defmodule Kernel do # ... ! ! ! ! ! ! ! ! # ... end
  • 49. defmodule Kernel do # ... ! ! ! ! ! ! ! ! # ... end defmacro if(condition, clauses) do # ...
  • 50. defmodule Kernel do # ... ! ! ! ! ! ! ! ! # ... end defmacro if(condition, clauses) do # ... defmacro defmodule(alias, do: block) do # ...
  • 51. defmodule Kernel do # ... ! ! ! ! ! ! ! ! # ... end defmacro if(condition, clauses) do # ... defmacro defmodule(alias, do: block) do # ... defmacro def(call, expr nil) do # ...
  • 52. defmodule Kernel do # ... ! ! ! ! ! ! ! ! # ... end defmacro if(condition, clauses) do # ... defmacro defmodule(alias, do: block) do # ... defmacro def(call, expr nil) do # ... defmacro defmacro(call, expr nil) do # ...
  • 53. defmodule Control do defmacro unless(clause, [do: expression]) do quote do if (not unquote(clause)) do unquote(expression) end end end end
  • 54. defmodule Control do defmacro unless(clause, [do: expression]) do quote do if (not unquote(clause)) do unquote(expression) end end end end defmodule Sandbox do import Kernel, except: [unless: 2] import Control def try_unless(clause) do unless clause do IO.puts "Clause is false" end end end
  • 55. defmodule Control do defmacro unless(clause, [do: expression]) do quote do if (not unquote(clause)) do unquote(expression) end end end end defmodule Sandbox do import Kernel, except: [unless: 2] import Control def try_unless(clause) do unless clause do IO.puts "Clause is false" end end end
  • 56.
  • 57. !
  • 58. $ mix new bowling_game * creating README.md * creating .gitignore * creating mix.exs * creating config * creating config/config.exs * creating lib * creating lib/bowling_game.ex * creating test * creating test/test_helper.exs * creating test/bowling_game_test.exs $ cd bowling_game $ mix compile Compiled lib/bowling_game.ex Generated bowling_game.app
  • 59. $ mix mix help mix # Run the default task (current: mix run) mix archive # List all archives mix archive.build # Archive this project into a .ez file mix archive.install # Install an archive locally mix archive.uninstall # Uninstall archives mix clean # Delete generated application files mix cmd # Executes the given command mix compile # Compile source files mix compile.protocols # Consolidates all protocols in all paths mix deps # List dependencies and their status mix deps.clean # Remove the given dependencies' files mix deps.compile # Compile dependencies mix deps.get # Get all out of date dependencies mix deps.unlock # Unlock the given dependencies mix deps.update # Update the given dependencies ...
  • 60. defmodule Bowling.Game.Test do import Bowling.Game use ExUnit.Case ! test "score is 0 for all zeros" do assert score(roll_many(20, 0)) == 0 end ! test "score is 20 for all ones" do assert score(roll_many(20, 1)) == 20 end ! test "a throw counts twice after a spare" do assert score([5, 5, 3 | roll_many(17, 0)]) == 16 assert score([0, 10, 3 | roll_many(17, 0)]) == 16 end ! # ... end
  • 61. defmodule Bowling.Game.Test do import Bowling.Game use ExUnit.Case ! test "score is 0 for all zeros" do assert score(roll_many(20, 0)) == 0 end ! test "score is 20 for all ones" do assert score(roll_many(20, 1)) == 20 end ! test "a throw counts twice after a spare" do assert score([5, 5, 3 | roll_many(17, 0)]) == 16 assert score([0, 10, 3 | roll_many(17, 0)]) == 16 end ! # ... end $ mix test ....... ! Finished in 0.09 seconds (0.09s on load, 0.00s on tests) 7 tests, 0 failures ! Randomized with seed 825783
  • 62. defmodule Bowling.Game.Test do import Bowling.Game use ExUnit.Case ! test "score is 0 for all zeros" do assert score(roll_many(20, 0)) == 0 end ! test "score is 20 for all ones" do assert score(roll_many(20, 1)) == 20 end ! test "a throw counts twice after a spare" do assert score([5, 5, 3 | roll_many(17, 0)]) == 16 assert score([0, 10, 3 | roll_many(17, 0)]) == 16 end ! # ... end $ mix test ....... ! Finished in 0.09 seconds (0.09s on load, 0.00s on tests) 7 tests, 0 failures ! Randomized with seed 825783 $ mix test 1) test score is 0 for all zeros (Bowling.Game.Test) test/bowling_game_test.exs:5 Assertion with == failed code: score(roll_many(20, 0)) == 1 lhs: 0 rhs: 1 stacktrace: test/bowling_game_test.exs:6 ! ...... ! Finished in 0.1 seconds (0.08s on load, 0.02s on tests) 7 tests, 1 failures ! Randomized with seed 416239
  • 63. defmodule Bowling.Game do @spec score([0..10]) :: 0..300 def score([]), do: 0 def score([x, y]), do: x + y def score([x, y, z]), do: x + y + z # ... end
  • 64. defmodule Bowling.Game do @spec score([0..10]) :: 0..300 def score([]), do: 0 def score([x, y]), do: x + y def score([x, y, z]), do: x + y + z # ... end $ mix dialyzer Starting Dialyzer Proceeding with analysis... done in 0m0.94s done (passed successfully)
  • 65. defmodule Bowling.Game do def broke, do: score(:boom) @spec score([0..10]) :: 0..300 def score([]), do: 0 def score([x, y]), do: x + y def score([x, y, z]), do: x + y + z # ... end
  • 66. defmodule Bowling.Game do def broke, do: score(:boom) @spec score([0..10]) :: 0..300 def score([]), do: 0 def score([x, y]), do: x + y def score([x, y, z]), do: x + y + z # ... end $ mix dialyzer Starting Dialyzer Proceeding with analysis... bowling_game.ex:29: Function broke/0 has no local return bowling_game.ex:30: The call 'Elixir.Bowling.Game':score('boom') will never return since the success typing is ([number()]) -> number() and the contract is ([0..10]) -> 0..300 done in 0m0.90s done (warnings were emitted)
  • 67. defmodule Bowling.Game do @moduledoc """ Given a valid sequence of rolls for one line of American Ten-Pin Bowling ... * We will not check for valid rolls. * We will not check for correct number of rolls and frames. * We will not provide scores for intermediate frames. ... """ @doc """ Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score ! ## Examples iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4]) 86 """ @spec score([0..10]) :: 0..300 def score([]), do: 0 # ... end
  • 68. defmodule Bowling.Game do @moduledoc """ Given a valid sequence of rolls for one line of American Ten-Pin Bowling ... * We will not check for valid rolls. * We will not check for correct number of rolls and frames. * We will not provide scores for intermediate frames. ... """ @doc """ Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score ! ## Examples iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4]) 86 """ @spec score([0..10]) :: 0..300 def score([]), do: 0 # ... end iex(1)> h Bowling.Game ! Bowling.Game ! Given a valid sequence of rolls for one line of American Ten-Pin Bowling, produces the total score for the game. Here are some things that the program will not do: ! • We will not check for valid rolls. • We will not check for correct number of rolls and frames. • We will not provide scores for intermediate frames. ! We can briefly summarize the scoring for this form of bowling: ...
  • 69. defmodule Bowling.Game do @moduledoc """ Given a valid sequence of rolls for one line of American Ten-Pin Bowling ... * We will not check for valid rolls. * We will not check for correct number of rolls and frames. * We will not provide scores for intermediate frames. ... """ @doc """ Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score ! ## Examples iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4]) 86 """ @spec score([0..10]) :: 0..300 def score([]), do: 0 # ... end iex(1)> h Bowling.Game ! Bowling.Game ! Given a valid sequence of rolls for one line of American Ten-Pin Bowling, produces the total score for the game. Here are some things that the program will not do: ! • We will not check for valid rolls. • We will not check for correct number of rolls and frames. • We will not provide scores for intermediate frames. ! We can briefly summarize the scoring for this form of bowling: ... iex(2)> h Bowling.Game.score ! def scrore(list) ! Given a sequence of rolls for one line of American Ten-Pin Bowling returns the total score for the game ! Examples ! ┃ iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, ┃ 87
  • 70. defmodule Bowling.Game do @moduledoc """ Given a valid sequence of rolls for one line of American Ten-Pin Bowling ... * We will not check for valid rolls. * We will not check for correct number of rolls and frames. * We will not provide scores for intermediate frames. ... """ @doc """ Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score ! ## Examples iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4]) 86 """ @spec score([0..10]) :: 0..300 def score([]), do: 0 # ... end
  • 71. defmodule Bowling.Game do @moduledoc """ Given a valid sequence of rolls for one line of American Ten-Pin Bowling ... * We will not check for valid rolls. * We will not check for correct number of rolls and frames. * We will not provide scores for intermediate frames. ... """ @doc """ Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score ! ## Examples iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4]) 86 """ @spec score([0..10]) :: 0..300 def score([]), do: 0 # ... end $ mix docs Docs successfully generated. View them at "doc/index.html".
  • 72. defmodule Bowling.Game do @moduledoc """ Given a valid sequence of rolls for one line of American Ten-Pin Bowling ... * We will not check for valid rolls. * We will not check for correct number of rolls and frames. * We will not provide scores for intermediate frames. ... """ @doc """ Given a sequence of rolls for one line of American Ten-Pin Bowling returns the score ! ## Examples iex> Bowling.Game.score([10, 2, 3, 5, 5, 4, 3, 2, 1, 5, 5, 7, 2, 3, 3, 2, 1, 4, 4]) 86 """ @spec score([0..10]) :: 0..300 def score([]), do: 0 # ... end $ mix docs Docs successfully generated. View them at "doc/index.html".
  • 73. defmodule Bowling.Game.Test do import Bowling.Game use ExUnit.Case ! doctest Bowling.Game ! test "score is 0 for all zeros" do assert score(roll_many(20, 0)) == 0 end ! test "score is 20 for all ones" do assert score(roll_many(20, 1)) == 20 end ! # ... end
  • 74. defmodule Bowling.Game.Test do import Bowling.Game use ExUnit.Case ! doctest Bowling.Game ! test "score is 0 for all zeros" do assert score(roll_many(20, 0)) == 0 end ! test "score is 20 for all ones" do assert score(roll_many(20, 1)) == 20 end ! # ... end $ mix test 1) test doc at Bowling.Game.score/1 (1) (Bowling.Game.Test) test/bowling_game_test.exs:5 Doctest failed code: Bowling.Game.score([10, 2, 3, 5, 5, ..., 4, 4]) === 86 lhs: 87 stacktrace: lib/bowling_game.ex:31: Bowling.Game (module) ! ....... ! Finished in 0.1 seconds (0.1s on load, 0.01s on tests) 8 tests, 1 failures !
  • 75.
  • 76. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end
  • 77. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end
  • 78. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3)
  • 79. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000])
  • 80. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok}
  • 81. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok} iex(2)> :timer.tc(Ring, :start, [10_000])
  • 82. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok} iex(2)> :timer.tc(Ring, :start, [10_000]) {12431, :ok}
  • 83. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok} iex(2)> :timer.tc(Ring, :start, [10_000]) {12431, :ok} iex(3)> :timer.tc(Ring, :start, [1_000_000])
  • 84. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok} iex(2)> :timer.tc(Ring, :start, [10_000]) {12431, :ok} iex(3)> :timer.tc(Ring, :start, [1_000_000]) {1512394, :ok}
  • 85. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok} iex(2)> :timer.tc(Ring, :start, [10_000]) {12431, :ok} iex(3)> :timer.tc(Ring, :start, [1_000_000]) {1512394, :ok} iex(4)> :timer.tc(Ring, :start, [10_000_000])
  • 86. defmodule Ring do def start(n) do start(n, self) end ! def start(0, first) do send(first, :ok) end ! def start(n, first) do spawn(fn -> start(n - 1, first) end) |> send(:ok) receive do :ok -> :ok end end end Interactive Elixir (1.0.3) iex(1)> :timer.tc(Ring, :start, [1_000]) {1677, :ok} iex(2)> :timer.tc(Ring, :start, [10_000]) {12431, :ok} iex(3)> :timer.tc(Ring, :start, [1_000_000]) {1512394, :ok} iex(4)> :timer.tc(Ring, :start, [10_000_000]) {15207638, :ok}
  • 87. defmodule Counter do def start(n) do spawn(fn -> loop(n) end) end ! def down(pid), do: send(pid, :down) ! defp loop(n) do IO.puts "Counter at #{n}" receive do :down when n == 1 -> IO.puts "That's it, bye!" :down -> loop(n - 1) _ -> loop(n) end end end
  • 88. defmodule Counter do def start(n) do spawn(fn -> loop(n) end) end ! def down(pid), do: send(pid, :down) ! defp loop(n) do IO.puts "Counter at #{n}" receive do :down when n == 1 -> IO.puts "That's it, bye!" :down -> loop(n - 1) _ -> loop(n) end end end Interactive Elixir (1.0.3) iex(1)> s = Counter.start(3) Counter at 3 #PID<0.113.0> iex(2)> Process.alive? s true iex(3)> Counter.down Counter at 2 :down iex(4)> Counter.down Counter at 1 :down iex(5)> Counter.down That's it, bye! :down iex(2)> Process.alive? s false
  • 89.
  • 90.
  • 91.
  • 92.
  • 93. ⚠ #