Slide 1

Slide 1 text

Tutorial Phoenix Framework Arthur Braga Alfredo 1

Slide 2

Slide 2 text

O que será ensinado hoje? 2

Slide 3

Slide 3 text

1ª parte: Elixir História Conceitos de programação funcional Pattern Matching Tipos de dados Módulos e funções nomeadas Condicionais Loops Mix 3

Slide 4

Slide 4 text

2ª parte: Phoenix Criação do projeto Estrutura de arquivos Rotas e pipeline Controllers, Models, Templates e Views Ecto Geradores Channels 4

Slide 5

Slide 5 text

O que não vou falar OTP Nodes Supervisores Macros Protocolos 5

Slide 6

Slide 6 text

História 6

Slide 7

Slide 7 text

Teoria da Lógica combinatória - 1927. Base para o design das linguagens de programação funcionais. Higher-order functions. As linguagens funcionais Haskell, Brooks, Curry e o conceito currying foram homenagens a ele. Haskell Curry 7

Slide 8

Slide 8 text

Teoria das funções recursivas - 1931. Considerado um dos mais importantes lógicos que já existiu. Kurt Gödel 8

Slide 9

Slide 9 text

Teoria do cálculo lambda - 1936 Funções anônimas Influenciou o design do LISP e das linguagens de programação funcionais em geral. Conceitos de abstração. Linguagens de alto nível. Alonzo Church 9

Slide 10

Slide 10 text

LISP foi criado no MIT em 1960 ISWIM em 1966 SASL em 1973 Miranda e Erlang em 1986 Haskell em 1992 Primeiras Linguagens 10

Slide 11

Slide 11 text

Quais as vantagens das linguagens funcionais? 11

Slide 12

Slide 12 text

Imutabilidade 12

Slide 13

Slide 13 text

Poucos problemas de concorrência 13

Slide 14

Slide 14 text

Mais fácil de testar 14

Slide 15

Slide 15 text

Menos código = Facilidade de manutenção 15

Slide 16

Slide 16 text

Porque ficou mais nas universidades? 16

Slide 17

Slide 17 text

Criador da linguagem Fortran - 1950. Criada dentro da IBM. Primeira linguagem de alto nível. Dominou a área de programação. Continua sendo usada até hoje em super computadores. . John W. Backus 17

Slide 18

Slide 18 text

John W. Backus Turing award em 1977. “Linguagens de programação convencionais estão ficando cada vez maiores, mas não mais fortes.” 18

Slide 19

Slide 19 text

Memória era muito cara 19

Slide 20

Slide 20 text

Os computadores era lentos 20

Slide 21

Slide 21 text

Programação paralela estava engatinhando 21

Slide 22

Slide 22 text

Multi-processadores também 22

Slide 23

Slide 23 text

E Nem se falava em multi- core 23

Slide 24

Slide 24 text

Mas muita coisa mudou 24

Slide 25

Slide 25 text

Memória 25

Slide 26

Slide 26 text

Multi-core 26

Slide 27

Slide 27 text

Multi-processador 27

Slide 28

Slide 28 text

Mas tem um porém 28

Slide 29

Slide 29 text

The free lunch is over 29

Slide 30

Slide 30 text

Elixir 30

Slide 31

Slide 31 text

Brasileiro. Fez parte do core team do rails. Participou de muitos projetos open source. Decidiu criar a linguagem Elixir em 2013. José Valim 31

Slide 32

Slide 32 text

Objetivo Criar uma linguagem que que possibilitasse alta performance, extensibilidade e produtividade e que rodasse na VM do Erlang. 32

Slide 33

Slide 33 text

Porque Erlang? Criado em 1986 para resolver problemas na área de telefonia. Altamente tolerante a falhas. Altamente concorrente. Fácil de escalar. 33

Slide 34

Slide 34 text

Porque Erlang? https://blog.whatsapp.com/196/1-million-is-so-2011 34

Slide 35

Slide 35 text

Descobriu Elixir em 2013. Desenvolveu uma biblioteca de websockets. Viu a oportunidade de criar um framework com foco em produtividade no estilo do rails. Chris McCord 35

Slide 36

Slide 36 text

Timeline Dezembro de 2013: Início do desenvolvimento do Phoenix. Setembro de 2014: José Valim entra para o Core Team. Agosto de 2015: Lançada versão 1.0 36

Slide 37

Slide 37 text

O que é programação funcional? 37

Slide 38

Slide 38 text

É um paradigma de programação que trata a computação como uma avaliação de funções matemáticas e que evita estados ou dados mutáveis 38

Slide 39

Slide 39 text

Conceitos 39

Slide 40

Slide 40 text

Imutabilidade Uma vez que uma variável é criada, seu valor não pode mais ser alterado. 40

Slide 41

Slide 41 text

Imutabilidade Eshell V8.0.3 1> A = 10. 10 2> A = 20. ** exception error: no match of right hand side value 20 41

Slide 42

Slide 42 text

Imutabilidade Interactive Elixir (1.3.2) iex(1)> a = 10 10 iex(2)> a = 20 20 42

Slide 43

Slide 43 text

Imutável? 43

Slide 44

Slide 44 text

Single matching A variável não pode mais ser reutilizada. 44

Slide 45

Slide 45 text

Imutabilidade Interactive Elixir (1.3.2) iex(4)> a = 10 10 iex(5)> ^a = 20 ** (MatchError) no match of right hand side value: 20 45

Slide 46

Slide 46 text

Rebinding O valor na memória continua imutável, mas a variável pode ser reutilizada. 46

Slide 47

Slide 47 text

Imutabilidade iex(12)> soma = 25 25 iex(13)> func_soma = fn -> "A soma é #{ soma }" end #Function<20.52032458/0 in :erl_eval.expr/5> iex(14)> soma = 100 100 iex(17)> func_soma.() "A soma é 25" 47

Slide 48

Slide 48 text

Funções anônimas São funções que podem ser tratadas como valores e que podem ser manipuladas ou retornadas por outras funções. 48

Slide 49

Slide 49 text

Funções anônimas soma10 = fn (x) -> x + 10 end soma10.(20) # => 30 multiplica = fn x,y -> x * y end multiplica.(10,10) # => 100 lista = [1,2,3,4,5] Enum.map(lista, soma10) [11, 12, 13, 14, 15, 16] 49

Slide 50

Slide 50 text

Funções puras São aquelas que não causam efeitos colaterais, ou seja, não interagem com recursos externos. 50

Slide 51

Slide 51 text

Higher-order functions São funções que recebem ou retornam outras funções. 51

Slide 52

Slide 52 text

Higher-order functions lista = [1,2,3,4,5] [1, 2, 3, 4, 5] Enum.map(lista, fn x -> x * x end) [1, 4, 9, 16, 25] Enum.reduce(lista, 0, fn(x,y) -> x + y end) 15 Enum.reduce(lista, 0, &(&1 + &2)) 15 Enum.filter(lista, fn x -> x > 2 end) [3, 4, 5] 52

Slide 53

Slide 53 text

Recursão São funções que chamam elas mesmas. 53

Slide 54

Slide 54 text

Recursão defmodule Fatorial do def de(1), do: 1 def de(n) when n > 0 do n * de(n-1) end end 54

Slide 55

Slide 55 text

Pattern Matching iex> {a, b, c} = {:hello, "world", 42} {:hello, "world", 42} iex> a :hello iex> b "world" iex> {a, _, c} = {:hello, "world", 42} {:hello, "world", 42} iex> a :hello iex> c 42 55

Slide 56

Slide 56 text

Pattern Matching iex> {a, b, c} = {:hello, "world"} ** (MatchError) no match of right hand side value: {:hello, "world"} 56

Slide 57

Slide 57 text

Pattern Matching iex> {:ok, result} = {:ok, 13} {:ok, 13} iex> result 13 iex> {:ok, result} = {:error, :oops} ** (MatchError) no match of right hand side value: {:error, :oops} 57

Slide 58

Slide 58 text

Pattern Matching iex> [head | tail] = [1, 2, 3] [1, 2, 3] iex> head 1 iex> tail [2, 3] 58

Slide 59

Slide 59 text

Pattern Matching defmodule Math do def sum_list([head | tail], accumulator) do sum_list(tail, head + accumulator) end def sum_list([], accumulator) do accumulator end end IO.puts Math.sum_list([1, 2, 3], 0) #=> 6 59

Slide 60

Slide 60 text

Pattern Matching - Pin operator iex> x = 1 1 iex> ^x = 2 ** (MatchError) no match of right hand side value: 2 iex> {y, ^x} = {2, 1} {2, 1} iex> y 2 iex> {y, ^x} = {2, 2} ** (MatchError) no match of right hand side value: {2, 2} 60

Slide 61

Slide 61 text

Pipe operator ( |> ) Transforma o valor anterior como primeiro argumento da próxima função. 61

Slide 62

Slide 62 text

Operador Pipe (|>) foo(bar(baz(new_function(other_function())))) 62

Slide 63

Slide 63 text

Operador Pipe (|>) other_function() |> new_function() |> baz() |> bar() |> foo() "Elixir rocks" |> String.upcase |> String.split ["ELIXIR", "ROCKS"] "elixir" |> String.ends_with?("ixir") true 63

Slide 64

Slide 64 text

Elixir 64

Slide 65

Slide 65 text

Tipos de dados iex> 1 # integer iex> 0x1F # integer iex> 1.0 # float iex> true # boolean iex> :atom # atom / symbol iex> "elixir" # string iex> 'elixir' # char list iex> [1, 2, 3] # list iex> {1, 2, 3} # tuple 65

Slide 66

Slide 66 text

Controles de fluxo 66

Slide 67

Slide 67 text

If iex> lang = "Elixir" "Elixir" ...> if lang do ...> IO.puts lang ...> end Elixir :ok iex> lang = "Phyton" "Phyton" iex> if lang == "Elixir" do ...> IO.puts lang ...> else ...> IO.puts "Não é elixir" ...> end Não é elixir :ok 67

Slide 68

Slide 68 text

Unless iex> lang = "Elixir" "Elixir" ...> unless lang do ...> IO.puts lang ...> end nil :ok iex> lang = "Phyton" "Phyton" iex> unless lang == "Elixir" do ...> IO.puts lang ...> end Python :ok 68

Slide 69

Slide 69 text

Cond iex> cond do ...> 2 + 2 == 5 -> ...> "Falso" ...> 2 * 2 == 3 -> ...> "Falso" ...> 1 + 1 == 2 -> ...> "Verdadeiro" ...> true -> ...> "Se nada der certo chega aqui" ...> end "Verdadeiro" 69

Slide 70

Slide 70 text

Case case {1, 2, 3} do {4, 5, 6} -> "Não vai dar match" {1, x, 3} -> "Vai dar match e o x vai receber o valor 2" _ -> "Essa clausula vai dar match em qualquer valor" end "Vai dar match e o x vai receber o valor 2" 70

Slide 71

Slide 71 text

Case case {1, 2, 3} do {4, 5, 6} -> "Não vai dar match" {1, ^x, 3} -> "Vai dar match e o x vai receber o valor 2" _ -> "Essa clausula vai dar match em qualquer valor" end "Essa clausula vai dar match em qualquer valor" 71

Slide 72

Slide 72 text

Case calcular = fn expressao -> case expressao do {:+, num1, num2} -> num1 + num2 {:-, num1, num2} -> num1 - num2 {:*, num1, num2} -> num1 * num2 {:/, num1, num2} -> num1 / num2 end end calcular.({:+, 2 ,2}) 4 calcular.({:-, 2 ,2}) 0 calcular.({:/, 2 ,0}) ** (ArithmeticError) bad argument in arithmetic expression :erlang./(2, 0) 72

Slide 73

Slide 73 text

Módulos e funções 73

Slide 74

Slide 74 text

Módulos iex> defmodule Math do ...> def sum(a, b) do ...> a + b ...> end ...> end Math.sum(1,2) #=> 3 74

Slide 75

Slide 75 text

Funções defmodule Math do def sum(a, b) do do_sum(a, b) end defp do_sum(a, b) do a + b end end IO.puts Math.sum(1, 2) #=> 3 IO.puts Math.do_sum(1, 2) #=> ** (UndefinedFunctionError) 75

Slide 76

Slide 76 text

Funções defmodule Math do def zero?(0), do: true def zero?(x) when is_integer(x), do: false end 76

Slide 77

Slide 77 text

Guard clauses calcular = fn expressao -> case expressao do {:+, num1, num2} -> num1 + num2 {:-, num1, num2} -> num1 - num2 {:*, num1, num2} -> num1 * num2 {:/, num1, num2} when num2 != 0 -> num1 / num2 {:/, num1, num2} when num2 == 0 -> IO.puts "Não é possível dividir por 0" end end calcular.({:/, 2, 0}) Não é possível dividir por 0 :ok calcular.({:/, 2, 1}) 2.0 77

Slide 78

Slide 78 text

Fatorial defmodule Fatorial do def de(1), do: 1 def de(n) when n > 0 do n * de(n-1) end end 78

Slide 79

Slide 79 text

Fatorial defmodule Fatorial do def de(1, acc), do: acc def de(n, acc) when n > 0 do de(n-1, acc * n) end end 79

Slide 80

Slide 80 text

Tail call optimization 80

Slide 81

Slide 81 text

Tail call optimization 81

Slide 82

Slide 82 text

Arquivos ex e exs .ex: Arquivos que serão compilados. .exs: Arquivos que serão interpretados. 82

Slide 83

Slide 83 text

Arquivos ex e exs Se o arquivo precisar ser muito rápido, use o ex pois arquivo exs é compilado em tempo de execução. Os arquivos de teste normalmente utilizam .exs para não precisar compilar toda vez que os testes rodarem 83

Slide 84

Slide 84 text

Mix Fornece ferramentas e utilidades para trabalhar com Elixir 84

Slide 85

Slide 85 text

Hex.pm 85

Slide 86

Slide 86 text

Live coding: Chat com phoenix 86

Slide 87

Slide 87 text

Onde aprender mais 87

Slide 88

Slide 88 text

Onde aprender mais 88

Slide 89

Slide 89 text

Onde aprender mais #myelixirstatus 89

Slide 90

Slide 90 text

Onde aprender mais 90

Slide 91

Slide 91 text

Muito obrigado 91