defmodule Fibonacci do
def of(0), do: 0
def of(1), do: 1
def of(n), do: of(n-2) + of(n-1)
end
defmodule Fibonacci do
def of(n) when n < 2, do: n
def of(n), do: of(n-2) + of(n-1)
end
defmodule Fibonacci do
def of(n), do: fib_of(n, 0, 1)
defp fib_of(0, curr_fib, _), do: curr_fib
defp fib_of(limit, curr_fib, next_fib) do
fib_of(limit-1, next_fib, curr_fib + next_fib)
end
end
defmodule Factorial do
def of(n), do: facto_of(n, 1)
defp facto_of(0, acc), do: acc
defp facto_of(1, acc), do: acc
defp facto_of(n, acc), do: facto_of(n-1, acc*n)
end
defmodule Sum do
def of(list), do: sum_of(list, 0)
defp sum_of([], acc), do: acc
defp sum_of([x|xs], acc), do: sum_of(xs, x+acc)
end
const squared = (x) => Math.pow(x, 2);
squared(4); //=> 16
squared = fn x -> :math.pow(x, 2) end
squared.(4) #=> 16.0
const squared = _.partial(Math.pow, _, 2);
squared(4); //=> 16
squared = &:math.pow(&1, 2)
squared.(4) #=> 16.0
const pow = Math.pow;
pow(4, 2); //=> 16
pow = &:math.pow/2
pow.(4, 2) #=> 16.0
$$ 19 \rightarrow 1^2 + 9^2 = 82 \\ 82 \rightarrow 8^2 + 2^2 = 68 \\ 68 \rightarrow 6^2 + 8^2 = 100 \\ 100 \rightarrow 1^2 + 0^2 + 0^2 = 1 \\ $$
defmodule Happy do
def is_happy(n) do
do_is_happy(n, [])
end
defp do_is_happy(1, _), do: true
defp do_is_happy(n, past), do: ???
defp do_is_happy(n, past) do
if n in past do
false
else
n
|> digits
|> Enum.reduce(0, &sum_of_squares/2)
|> do_is_happy([n|past])
end
end
defp digits(num) do
num
|> to_string
|> String.split("", trim: true)
|> Enum.map(&Integer.parse/1)
end
defp sum_of_squares({digit, _}, acc) do
(:math.pow(digit, 2) |> trunc) + acc
end
iex> for x <- 1..5, y <- 1..5, x < y, do: {x,y}
[{1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3},
{2, 4}, {2, 5}, {3, 4}, {3, 5}, {4, 5}]
defmodule PrimeNumbers do
def upto(n) do
sieve = :math.sqrt(n) |> trunc
non_primes = (for i <- 2..sieve do
multiples_of(i, i*i, n, [])
end) |> List.flatten
for i <- 1..n, !(i in non_primes), do: i
end
defp multiples_of(_, curr, limit, acc)
when curr > limit, do: acc
defp multiples_of(multiple, curr, limit, acc) do
multiples_of(multiple, curr+multiple, limit, [curr|acc])
end
Programming Elixir
defmodule Greeter do
def start do
receive do
{sender, {:greet, name}} ->
send sender, {:ok, "Hello, #{name}!"}
start
end
end
end
pid = spawn(Greeter, :start, [])
send pid, {self, {:greet, "World"}}
receive do
{:ok, greetings} ->
IO.puts greetings #=> "Hello, World!"
after 5000 ->
IO.puts "timed out"
end
Elixir documentation
Elixir documentation
defmodule Greeter do
use GenServer
def init(greeting) do
{:ok, %{greeting: greeting}}
end
def handle_call({:greet, name}, _sender, state) do
{:reply, "#{state.greeting}, #{name}!", state}
end
end
{:ok, pid} = GenServer.start_link(Greeter, "Hello")
GenServer.call(pid, {:greet, "World"}) #=> "Hello, World!"
defmodule Greeter do
use GenServer
# client api...
def start_link(greeting) do
GenServer.start_link(__MODULE__, greeting)
end
def greet(pid, name) do
GenServer.call(pid, {:greet, name})
end
# server implementation...
defmodule SearchIndexer do
use GenEvent
def handle_event({:new_entry, entry}, state) do
# actually do indexing...
{:ok, state}
end
end
{:ok, pid} = GenEvent.start_link
GenEvent.add_handler(pid, SearchIndexer, [])
GenEvent.notify(pid, {:new_entry, %{id: 1}})
# GenEvent.ack_notify...
# GenEvent.sync_notify...
Programming Elixir
worker = Task.async(Mod, :expensive_call, [])
# do other things...
result = Task.await(worker)
(for i <- 1..10_000, into: [], do: i)
|> Enum.map(&Task.async(Mod, :expensive_call, [&1]))
|> Enum.map(&Task.await/1)
Programming Elixir
Say.it("Bonjour")
|> Say.it("le")
|> Say.it("monde!")
|> Say.it()
"Bonjour le monde!"
def it(term) when is_binary(term) do
start_link |> it(term)
end
defp start_link do
{:ok, agent_pid} = Agent.start_link fn -> [] end
agent_pid
end
def it(agent_pid, word) do
Agent.update(agent_pid, &([word|&1]))
agent_pid
end
def it(term) when is_pid(term) do
sentence = Agent.get(term, &(&1))
|> Enum.reverse
|> Enum.join(" ")
Agent.stop(term)
sentence
end
Programming Elixir
Programming Elixir
defmodule GreeterSupervisor do
use Supervisor
def start_link do
Supervisor.start_link(
__MODULE__, [], name: __MODULE__)
end
defmodule GreeterSupervisor do
use Supervisor
# def start_link...
def init(_args) do
children = [ worker(Greeter, ["Hello"]) ]
supervise(children, strategy: :one_for_one)
end
end
:one_for_oneWhen a process crashes, restart it.
:one_for_allWhen one process crashes, restart all of them.
:rest_for_allWhen one crashes, restart it and all others that depend on it.
:simple_one_for_oneLike :one_for_one but only when dynamically adding children.
Programming Elixir
$ iex --sname one greeter.exs
iex(one@myhost)1> GenServer.start_link(
...(one@myhost)1> Greeter,
...(one@myhost)1> "Hello",
...(one@myhost)1> name: {:global, :greeter})
$ iex --sname two
iex(two@myhost)1> Node.connect :"one@myhost"
true
iex(two@myhost)2> Node.list
[:one@myhost]
iex(two@myhost)3> GenServer.call(
...(two@myhost)3> {:global, :greeter},
...(two@myhost)3> {:greet, "World"})
"Hello, World!"
$ iex --sname one
iex(one@myhost)1> Node.connect(:"two@myhost")
iex(one@myhost)2> Node.spawn(:"two@myhost",
...(one@myhost)2> GenServer, :start_link,
...(one@myhost)2> [Greeter, "Hello",
...(one@myhost)2> [name: :hello]])
$ iex --sname two greeter.exs
iex(two@myhost)1> GenServer.call(:hello,
...(two@myhost)1> {:greet, "World"})
"Hello, World!"
<html>
<head>
<script>
var re = /^<%= someExpression() %>\$/;
</script>
</head>
</html>
param = "world"
"Hello, #{param[0].toUpperCase() + param[1..-1]}!"
#=> "Hello, World!"
(+ 1 2) ;=> 3
'(+ 1 2) ;=> (+ 1 2)
`(+ 1 ,(+ 2 2)) ;=> (+ 1 4)
(let ((param 2))
`(+ 1 ,(expt param 3))) ;=> (+ 1 8)
iex(1)> 1 + 2
3
iex(2)> quote do 1 + 2 end
{:+, [...], [1, 2]}
param = 2
a_quoted_expr = quote do
1 + unquote(:math.pow(param, 3))
end
#=> {:+, [...], [1, 8.0]}
Macro.to_string(a_quoted_expr)
#=> "1 + 8.0"
{ id: 'name', type: 'string' }
{ id: 'age', type: 'integer', minimum: '18' }
{ id: 'contact', type: 'object',
properties: {
name: { '$ref': 'name' },
age: { '$ref': 'age' }
}
}
def valid?(:age, candidate)
when is_integer(candidate)
and candidate >= 18, do: true
def valid?(:contact, %{"name"=>n, "age"=>a}) do
valid?(:name, n) and valid?(:age, a)
end
defmodule ContactSchema do
use JSONSchema
schema id: :name, type: :string
schema id: :age, type: :integer, minimum: 18
schema id: :contact, type: :object, properties:
%{"age" => :age, "name" => :name}
end
defmodule JSONSchema do
defmacro schema(opts) do
do_schema(opts[:type], opts)
end
def do_schema(:string, opts) do ... end
def do_schema(:integer, opts) do ... end
def do_schema(:object, opts) do ... end
end
def do_schema(:string, opts) do
quote do
def valid?(unquote(opts[:id]), candidate)
when is_binary(candidate), do: true
end
end
def do_schema(:object, opts) do
quote do
def valid?(unquote(opts[:id]), candidate) do
props = unquote(opts[:properties])
Enum.all? props, fn {prop_name, sch_id} ->
valid?(sch_id, candidate[prop_name])
end
end
end
end
defmodule ContactSchema
use JSONSchema
end
defmodule JSONSchema do
defmacro __using__(opts) do
quote do
import unquote(__MODULE__)
end
end
end