Upgrade to Pro — share decks privately, control downloads, hide ads and more …

O Essencial da Programação Funcional em Elixir 1.1

O Essencial da Programação Funcional em Elixir 1.1

Versão Elixir Brasil

O mundo está caminhando cada vez mais para o paradigma funcional. Lançamento de linguagens de programação acontece frequentemente, porém adoção de um novo paradigma é algo mais raro. Precisamos entender essa mudança para estar preparado para o desenvolvimento de novos softwares da próximas décadas. Sou desenvolvedor há 9 anos que embarcou no paradigma funcional recentemente e autor no livro "Learn Functional Programming with Elixir" pela Pragmatic Programmers.

Nesta talk você vai aprender o porque a programação funcional importa para as demandas modernas. Iremos explorar os três conceitos essenciais de programação funcional em Elixir: imutabilidade, código declarativo e funções puras.

Esta é uma talk para iniciantes em programação funcional. Iremos discutir como é importante criar programas que sejam altamente paralelizáveis para os hardwares atuais. Será discutido como os conceitos de programação funcional suprem essas demandas de maneira melhor do que as linguagens convencionais.

Ulisses Almeida

October 28, 2017
Tweet

More Decks by Ulisses Almeida

Other Decks in Programming

Transcript

  1. Me

  2. Your Erlang program should just run N times faster on

    an N core processor https://pragprog.com/articles/erlang
  3. !

  4. class MySet attr_reader :items def initialize @items = [] end

    def push(item) items.push(item) unless items.include?(item) end end
  5. defmodule MySet do defstruct items: [] def push(set = %{items:

    items}, item) do if Enum.member?(items, item) do set else %{set | items: items ++ [item]} end end end
  6. set = %MySet{} set = MySet.push(set, "apple") new_set = %MySet{}

    new_set = MySet.push(new_set, "pie") IO.inspect MySet.push(set, "apple") # => ["apple"] IO.inspect MySet.push(new_set, "apple") # => ["pie", "apple"]
  7. function capitalizeAll(list) { var newList = []; for (var i

    = 0; i < list.length; i++) { newList.push(capitalize(list[i])); } return newList; } function capitalize(string) { return string.charAt(0).toUpperCase() + string.slice(1); }
  8. defmodule StringList do def capitalize_all([]), do: [] def capitalize_all([first |

    rest]) do [String.capitalize(first) | capitalize_all(rest)] end end
  9. list = [1, 2, 3, 4] list.pop puts list.inspect #

    => [1, 2, 3] list.push(1) puts list.inspect # => [1, 2, 3, 1]
  10. Account = Struct.new(:amount) do def deposit(value) new_amount = amount +

    value sleep(1) self.amount = new_amount end def withdraw(value) new_amount = amount - value sleep(1) self.amount = new_amount end end
  11. ilisses = Account.new(100) 5.times.map { Thread.new { ilisses.deposit(20) } }

    + 5.times.map { Thread.new { ilisses.withdraw(20) } }
  12. ilisses = Account.new(100) threads = 5.times.map { Thread.new { ilisses.deposit(20)

    } } + 5.times.map { Thread.new { ilisses.withdraw(20) } } threads.each(&:join) puts ilisses.amount
  13. ilisses = Account.new(100) 5.times { threads = 5.times.map { Thread.new

    { ilisses.deposit(20) } } + 5.times.map { Thread.new { ilisses.withdraw(20) } } threads.each(&:join) puts ilisses.amount ilisses = Account.new(100) }
  14. list = [1, 2, 3] # A ordem não importa

    List.delete_at(list, -1) list ++ [4] IO.inspect(list) # => [1, 2, 3]
  15. list = [1, 2, 3] # A ordem importa list

    = List.delete_at(list, -1) list = list ++ [4] IO.inspect(list) # => [1, 2, 4]
  16. {:ok, ulice_account} = Agent.start_link(fn -> 100 end) deposit_20 = fn

    -> Agent.update(ulice_account, fn amount -> Process.sleep(100) amount + 20 end) end withdraw_20 = fn -> Agent.update(ulice_account, fn amount -> Process.sleep(100) amount - 20 end) end
  17. deposits = for _i <- 1..5, do: Task.async(deposit_20) withdraws =

    for _i <- 1..5, do: Task.async(withdraw_20) Enum.each(deposits ++ withdraws, &(Task.await/1)) IO.inspect Agent.get(ulice_account, fn amount -> amount end)
  18. for _i <- 1..5 do deposits = for _i <-

    1..5, do: Task.async(deposit_20) withdraws = for _i <- 1..5, do: Task.async(withdraw_20) Enum.each(deposits ++ withdraws, &(Task.await/1)) IO.inspect Agent.get(ulice_account, fn amount -> amount end) end Agent.stop(ulice_account)
  19. User = Struct.new(:name) list = [User.new("Bob"), User.new("Anna")] list.freeze list.push(User.new("July")) #

    => RuntimeError: can't modify frozen Array list[0].name = "Ted" puts list.inspect # => [#<struct User name="Ted">, # <struct User name="Anna">]