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

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
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
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
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
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 

Último (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
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
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
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
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 

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. ⚠ #