Skip to content

Instantly share code, notes, and snippets.

@tiagopog
Last active October 27, 2016 18:33
Show Gist options
  • Select an option

  • Save tiagopog/08c3a241000e2ee9232a to your computer and use it in GitHub Desktop.

Select an option

Save tiagopog/08c3a241000e2ee9232a to your computer and use it in GitHub Desktop.
Elixir - Code Samples
defmodule Demo do
def greet(name) do
IO.puts "Hello #{name} from Elixir"
end
def api_call do
{:ok, "foo"}
end
end
# Function call
Demo.greet("Tiago")
# Pattern matching
{:ok, res} = Demo.api_call
IO.inspect(res)
# Pipe operator
IO.inspect Enum.reverse(Enum.sort([2, 3, 1]))
[2, 3, 1] |> Enum.sort |> Enum.reverse |> IO.inspect
[6, 3, 2, 1, 7]
# |> Enum.filter(&Integer.is_odd/1)
|> Enum.map(fn i -> i * 2 end)
|> Enum.reduce(&+/2)
|> IO.inspect
# Anonimous function
add = fn a, b -> a + b end
IO.inspect is_function(add, 2) #=> true
IO.inspect is_function(add, 1) #=> false
IO.inspect add.(2, 2) #=> 4
# Clojure
add_two = fn a -> add.(a, 3) end
IO.inspect add_two.(2) #=> 5
# Example of lexic scope in clojure
x = 42
(fn -> x = 0 end).()
IO.inspect x
# Lists
a = [1, 2, 3]
b = [2, 3, 4, true]
IO.inspect length(a) #=> 3
IO.inspect a ++ b #=> [1, 2, 3, 2, 3, 4, true]
IO.inspect a -- b #=> [1]
IO.inspect hd(a)
IO.inspect tl(a)
IO.inspect [1|[2|[3|[]]]] #=> [1, 2, 3]
# hd [] or tl [], returns an ArgumentError
# Tuples
foobar = {:foo, :bar}
IO.inspect tuple_size(foobar) #=> 2
IO.inspect elem(foobar, 1) #=> :bar
IO.inspect put_elem(foobar, 1, :baz) #=> {:foo, :baz}
list_to_tuple = fn(list, tuple) -> [head|tail] = list; list_to_tuple.(tail, Tuple.append(tuple, head)) end
# Pattern matching
{x, y, z} = {:hello, "world", 42}
IO.inspect x
IO.inspect y
IO.inspect z
[a, b, c] = [1, 2, 3]
IO.inspect a
# Pin operator
x = 42
IO.inspect ^x = 42 # applies the pattern matching without assigning any value
# Case
case {1, 2, 3} do
{4, 5, 6} -> "This won't match"
{1, x, 3} -> "This will match and bind #{x} to x"
_ -> "This would match any value"
end |> IO.inspect
# Case + pin operator
x = 1
case 10 do
^x -> "This won't match"
_ -> "This will match"
end |> IO.inspect
# Case + guard
case {1, 2, 3} do
{1, x, 3} when x > 2 -> "This won't match"
{1, x, 3} -> "This will match"
end |> IO.inspect
# Case + anonimous funcion
f = fn
x, y when x > 0 -> x + y
x, y -> x * y
end
IO.inspect f.(1, 3) #=> 4
IO.inspect f.(0, 2) #=> 0
# Cond
cond do
1 + 1 == 3 -> "This is not true"
2 * 2 < 4 -> "This is not true"
rem(9, 3) == 0 -> "This is true (displayed)"
true -> "This is true (not displayed)"
end |> IO.inspect
# If/else and unless
if nil do
"This won't execute"
else
"This will execute"
end
is_number(if true do
1 + 2
end) |> IO.inspect #=> true
# If (keyword list)
if true, do: :foo, else: :bar #=> :foo
if true, [do: :foo, else: :bar] #=> :foo
if(true, do: :foo, else: :bar) |> IO.inspect #=> :foo
# Binaries
IO.puts "\n Binaries: \n"
IO.inspect <<0, 1, 2, 3>>
byte_size(<<0, 1, 2, 3>>) |> IO.inspect
IO.inspect "foobar" <> <<0>> # Check String binary concatenating a byte
IO.inspect <<256>> #=> truncated: <<0>>
IO.inspect <<256 :: size(16)>> #=> 16-bit
IO.inspect bit_size(<<256 :: size(16)>>) #=> 16
IO.inspect <<256 :: utf8>> #=> code point: Ã
<<1, 2, x>> = <<1, 2, 3>>
IO.inspect x
<<1, 2, x :: binary>> = <<1, 2, 3, 4>>
IO.puts x
# Keyword list
IO.puts "\n Keyword lists: \n"
list = [{:foo, :bar}]
IO.puts list[:foo] #=> :bar
IO.puts list == [foo: :bar] #=> true
# Map
IO.puts "\n Maps: \n"
map = %{a: 1, b: 2}
IO.puts map.a #=> 1
IO.puts map.a #=> 2
IO.inspect %{map | b: 3}
n = 1
map = %{n => 1}
IO.puts map[n]
%{^n => 2} = %{n => 2, a: 2}
IO.puts n
# Nested data structure
IO.puts "\n Nested data structure: \n"
users = [
john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]},
james: %{name: "James", age: 29, languages: ["Elixir", "F#", "Clojure"]}
]
IO.puts users[:john].name #=> "John"
users = put_in users[:john].name, "Joe"
IO.inspect users
users = update_in users[:john].languages, &List.delete(&1, "Erlang")
IO.inspect users
# Modules
IO.puts "\n Modules: \n"
defmodule Math do
def sum(a, b) do
do_sum(a, b)
end
defp do_sum(a, b) do
a + b
end
def zero?(0) do
true
end
# def + guard:
def zero?(x) when is_number(x) do
true
end
# The same could be achieved with the following syntaxe:
def one?(1), do: true
def one?(x) when is_number(x), do: false
end
IO.puts Math.sum(1, 2) #=> 3
IO.puts Math.zero?(0) #=> true
IO.puts Math.zero?(1) #=> false
IO.puts Math.one?(0) #=> false
IO.puts Math.one?(1) #=> true
# Capture functions:
IO.puts "\n Capture functions: \n"
fun = &Math.zero?/1
IO.puts fun.(0) #=> true
(&:erlang.is_function/1).(fun) #=> true
sum_one = &(&1 + 1) # the same as sum_one = fun x -> x + 1
IO.puts sum_one.(1) #=> 2
sum = &Math.sum(&1, &2) #=> the same as &Math.sum/2 or fun(a, b) -> Math.sum(a, b) end
IO.puts sum.(2, 2) #=> 4
sum = fn(a, b) -> Math.sum(a, b) end
IO.puts sum.(2, 3) #=> 5
# Default params:
IO.puts "\n Default params: \n"
defmodule Greeting do
def say(foo \\ "Hello!") do
foo
end
end
IO.puts Greeting.say #=> "Hello!"
IO.puts Greeting.say("Foobar!") #=> "Foobar!"
defmodule Concat do
def join(a, b \\ nil, sep \\ " ")
def join(a, b, _sep) when is_nil(b) do
a
end
def join(a, b, sep) do
a <> sep <> b
end
end
IO.puts Concat.join("Hello", "world") #=> Hello world
IO.puts Concat.join("Hello", "world", "_") #=> Hello_world
IO.puts Concat.join("Hello") #=> Hello
# Recursion:
IO.puts "\n Recursion: \n"
defmodule Recursion do
# Base base:
def print_n_times(msg, n) when n <= 1 do
IO.puts msg
end
# Other:
def print_n_times(msg, n) do
IO.puts msg
print_n_times(msg, n - 1)
end
end
Recursion.print_n_times('Hey!', 3)
# Reduce:
IO.puts "\n Reduce: \n"
defmodule Reduce do
def sum_list([head|tail], accumulator) do
sum_list(tail, head + accumulator)
end
def sum_list([], accumulator) do
accumulator
end
end
IO.puts Reduce.sum_list([1, 2, 3], 0) #=> 6
IO.puts Enum.reduce([1, 2, 3], 0, fn (x, acc) -> x + acc end)
IO.puts Enum.reduce([1, 2, 3], 0, &+/2)
# Map:
IO.puts "\n Map: \n"
defmodule Map do
def double_list([head|tail]) do
[head * 2|double_list(tail)]
end
def double_list([]) do
[]
end
end
IO.inspect Map.double_list([1, 2, 3]) #=> [2, 4, 6]
IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end)
IO.inspect Enum.map([1, 2, 3], &(&1 * 2))
Enum.map_reduce(%{a: 1, b: 2}, %{}, fn({key, value}, acc) -> {%{key => value * 2}, Map.merge(acc, %{key => value * 2})} end)
#=> {[%{a: 2}, %{b: 4}], %{a: 2, b: 4}}
# Enumerable:
IO.puts "\n Enumerable: \n"
IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end)
IO.inspect Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end)
[1, 2, 3] |> Enum.map(&(&1 * 2)) |> Enum.sum |> IO.puts
%{1 => 2, 3 => 4} |> Enum.map(fn {k, v} -> k * v end) |> Enum.sum |> IO.puts
1..3 |> Enum.reduce(&+/2) |> IO.puts
# use UseMe
defmodule UseImportRequire.UseMe do
defmacro __using__(_) do
quote do
def use_test do
IO.puts "use_test"
end
end
end
end
# Working with files:
File.open(file_path, [:read, :utf8], fn(file) ->
IO.read(file, :line)
end)
path_to_file |> File.stream! |> Stream.map(&String.split/1) |> Enum.take(2) |> IO.inspect
defmodule Fibonacci do
def calculate(count) do
calculate(1, 1, count - 1)
end
def calculate(a, _b, 0) do
IO.puts a
end
def calculate(a, b, count) do
calculate(b, a + b, count - 1)
end
end
Fibonacci.calculate(4)
defmodule Demo do
def greet(name) do
IO.puts "Hello #{name} from Elixir"
end
def api_call do
{:ok, "foo"}
end
end
# Function call
Demo.greet("Tiago")
# Pattern matching
{:ok, res} = Demo.api_call
IO.inspect(res)
# Pipe operator
IO.inspect Enum.reverse(Enum.sort([2, 3, 1]))
[2, 3, 1] |> Enum.sort |> Enum.reverse |> IO.inspect
[6, 3, 2, 1, 7]
# |> Enum.filter(&Integer.is_odd/1)
|> Enum.map(fn i -> i * 2 end)
|> Enum.reduce(&+/2)
|> IO.inspect
# Anonimous function
add = fn a, b -> a + b end
IO.inspect is_function(add, 2) #=> true
IO.inspect is_function(add, 1) #=> false
IO.inspect add.(2, 2) #=> 4
# Clojure
add_two = fn a -> add.(a, 3) end
IO.inspect add_two.(2) #=> 5
# Example of lexic scope in clojure
x = 42
(fn -> x = 0 end).()
IO.inspect x
# Lists
a = [1, 2, 3]
b = [2, 3, 4, true]
IO.inspect length(a) #=> 3
IO.inspect a ++ b #=> [1, 2, 3, 2, 3, 4, true]
IO.inspect a -- b #=> [1]
IO.inspect hd(a)
IO.inspect tl(a)
IO.inspect [1|[2|[3|[]]]] #=> [1, 2, 3]
# hd [] or tl [], returns an ArgumentError
# Tuples
foobar = {:foo, :bar}
IO.inspect tuple_size(foobar) #=> 2
IO.inspect elem(foobar, 1) #=> :bar
IO.inspect put_elem(foobar, 1, :baz) #=> {:foo, :baz}
list_to_tuple = fn(list, tuple) -> [head|tail] = list; list_to_tuple.(tail, Tuple.append(tuple, head)) end
# Pattern matching
{x, y, z} = {:hello, "world", 42}
IO.inspect x
IO.inspect y
IO.inspect z
[a, b, c] = [1, 2, 3]
IO.inspect a
# Pin operator
x = 42
IO.inspect ^x = 42 # applies the pattern matching without assigning any value
# Case
case {1, 2, 3} do
{4, 5, 6} -> "This won't match"
{1, x, 3} -> "This will match and bind #{x} to x"
_ -> "This would match any value"
end |> IO.inspect
# Case + pin operator
x = 1
case 10 do
^x -> "This won't match"
_ -> "This will match"
end |> IO.inspect
# Case + guard
case {1, 2, 3} do
{1, x, 3} when x > 2 -> "This won't match"
{1, x, 3} -> "This will match"
end |> IO.inspect
# Case + anonimous funcion
f = fn
x, y when x > 0 -> x + y
x, y -> x * y
end
IO.inspect f.(1, 3) #=> 4
IO.inspect f.(0, 2) #=> 0
# Cond
cond do
1 + 1 == 3 -> "This is not true"
2 * 2 < 4 -> "This is not true"
rem(9, 3) == 0 -> "This is true (displayed)"
true -> "This is true (not displayed)"
end |> IO.inspect
# If/else and unless
if nil do
"This won't execute"
else
"This will execute"
end
is_number(if true do
1 + 2
end) |> IO.inspect #=> true
# If (keyword list)
if true, do: :foo, else: :bar #=> :foo
if true, [do: :foo, else: :bar] #=> :foo
if(true, do: :foo, else: :bar) |> IO.inspect #=> :foo
# Binaries
IO.puts "\n Binaries: \n"
IO.inspect <<0, 1, 2, 3>>
byte_size(<<0, 1, 2, 3>>) |> IO.inspect
IO.inspect "foobar" <> <<0>> # Check String binary concatenating a byte
IO.inspect <<256>> #=> truncated: <<0>>
IO.inspect <<256 :: size(16)>> #=> 16-bit
IO.inspect bit_size(<<256 :: size(16)>>) #=> 16
IO.inspect <<256 :: utf8>> #=> code point: Ã
<<1, 2, x>> = <<1, 2, 3>>
IO.inspect x
<<1, 2, x :: binary>> = <<1, 2, 3, 4>>
IO.puts x
# Keyword list
IO.puts "\n Keyword lists: \n"
list = [{:foo, :bar}]
IO.puts list[:foo] #=> :bar
IO.puts list == [foo: :bar] #=> true
# Map
IO.puts "\n Maps: \n"
map = %{a: 1, b: 2}
IO.puts map.a #=> 1
IO.puts map.a #=> 2
IO.inspect %{map | b: 3}
n = 1
map = %{n => 1}
IO.puts map[n]
%{^n => 2} = %{n => 2, a: 2}
IO.puts n
# Nested data structure
IO.puts "\n Nested data structure: \n"
users = [
john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]},
james: %{name: "James", age: 29, languages: ["Elixir", "F#", "Clojure"]}
]
IO.puts users[:john].name #=> "John"
users = put_in users[:john].name, "Joe"
IO.inspect users
users = update_in users[:john].languages, &List.delete(&1, "Erlang")
IO.inspect users
# Modules
IO.puts "\n Modules: \n"
defmodule Math do
def sum(a, b) do
do_sum(a, b)
end
defp do_sum(a, b) do
a + b
end
def zero?(0) do
true
end
# def + guard:
def zero?(x) when is_number(x) do
true
end
# The same could be achieved with the following syntaxe:
def one?(1), do: true
def one?(x) when is_number(x), do: false
end
IO.puts Math.sum(1, 2) #=> 3
IO.puts Math.zero?(0) #=> true
IO.puts Math.zero?(1) #=> false
IO.puts Math.one?(0) #=> false
IO.puts Math.one?(1) #=> true
# Capture functions:
IO.puts "\n Capture functions: \n"
fun = &Math.zero?/1
IO.puts fun.(0) #=> true
(&:erlang.is_function/1).(fun) #=> true
sum_one = &(&1 + 1) # the same as sum_one = fun x -> x + 1
IO.puts sum_one.(1) #=> 2
sum = &Math.sum(&1, &2) #=> the same as &Math.sum/2 or fun(a, b) -> Math.sum(a, b) end
IO.puts sum.(2, 2) #=> 4
sum = fn(a, b) -> Math.sum(a, b) end
IO.puts sum.(2, 3) #=> 5
# Default params:
IO.puts "\n Default params: \n"
defmodule Greeting do
def say(foo \\ "Hello!") do
foo
end
end
IO.puts Greeting.say #=> "Hello!"
IO.puts Greeting.say("Foobar!") #=> "Foobar!"
defmodule Concat do
def join(a, b \\ nil, sep \\ " ")
def join(a, b, _sep) when is_nil(b) do
a
end
def join(a, b, sep) do
a <> sep <> b
end
end
IO.puts Concat.join("Hello", "world") #=> Hello world
IO.puts Concat.join("Hello", "world", "_") #=> Hello_world
IO.puts Concat.join("Hello") #=> Hello
# Recursion:
IO.puts "\n Recursion: \n"
defmodule Recursion do
# Base base:
def print_n_times(msg, n) when n <= 1 do
IO.puts msg
end
# Other:
def print_n_times(msg, n) do
IO.puts msg
print_n_times(msg, n - 1)
end
end
Recursion.print_n_times('Hey!', 3)
# Reduce:
IO.puts "\n Reduce: \n"
defmodule Reduce do
def sum_list([head|tail], accumulator) do
sum_list(tail, head + accumulator)
end
def sum_list([], accumulator) do
accumulator
end
end
IO.puts Reduce.sum_list([1, 2, 3], 0) #=> 6
IO.puts Enum.reduce([1, 2, 3], 0, fn (x, acc) -> x + acc end)
IO.puts Enum.reduce([1, 2, 3], 0, &+/2)
# Map:
IO.puts "\n Map: \n"
defmodule Map do
def double_list([head|tail]) do
[head * 2|double_list(tail)]
end
def double_list([]) do
[]
end
end
IO.inspect Map.double_list([1, 2, 3]) #=> [2, 4, 6]
IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end)
IO.inspect Enum.map([1, 2, 3], &(&1 * 2))
Enum.map_reduce(%{a: 1, b: 2}, %{}, fn({key, value}, acc) -> {%{key => value * 2}, Map.merge(acc, %{key => value * 2})} end)
#=> {[%{a: 2}, %{b: 4}], %{a: 2, b: 4}}
# Enumerable:
IO.puts "\n Enumerable: \n"
IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end)
IO.inspect Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end)
[1, 2, 3] |> Enum.map(&(&1 * 2)) |> Enum.sum |> IO.puts
%{1 => 2, 3 => 4} |> Enum.map(fn {k, v} -> k * v end) |> Enum.sum |> IO.puts
1..3 |> Enum.reduce(&+/2) |> IO.puts
# use UseMe
defmodule UseImportRequire.UseMe do
defmacro __using__(_) do
quote do
def use_test do
IO.puts "use_test"
end
end
end
end
# Working with files:
File.open(file_path, [:read, :utf8], fn(file) ->
IO.read(file, :line)
end)
path_to_file |> File.stream! |> Stream.map(&String.split/1) |> Enum.take(2) |> IO.inspect
defmodule Example.User do
defstruct name: "Tiago", last_name: "Guedes", roles: [:admin, :owner]
end
IO.inspect %Example.User{}
IO.inspect %Example.User{name: "Foobar"}
foo = %Example.User{}
foo = %{foo | name: "Foo"}
IO.inspect foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment