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