marcelocamargo@linuxmail.org
github.com/haskellcamargo
× What in the world is FP?
× FP matters!
× FP concepts in Ruby
fun _ → b* programas e dados contidos no mesmo espaço de memória
OU
Funções de primeira classe
Funções de mais alta ordem
Closures
Funções puras e determinísticas
Funções de primeira classe
Transparência referencial
Imutabilidade
Pattern matching
Recursividade
Composição de funções
add = lambda { |a, b| a + b }
puts add[10, 20]Métodos, procedimentos e lambdas armazenados em variáveis
(1 .. 10) 
  .map { |x| x * 3 }
  .select { |x| x % 2 == 0 }
  .reduce { |acc, x| acc + x }Passe funções como parâmetros e retorne outras funções
def add(a, b)
  a + b
end
add_10 = method(:add).curry[10]
puts add_10[20]Acesse e preserve o escopo de execução anterior
def add(a)
  lambda { |b| a + b }
end
add_10 = add 10
puts add_10[20]Acesse e preserve o escopo de execução anterior
def double_me(n)
  n[0] = n[0] * 2
end
val = [20]
double_me val
puts val[0]f(x) = y. Sem efeitos colaterais. Se entra x agora e sai y, sempre sairá y quando entrar x. Exemplo impuro:
def double_me(n)
  n * 2
end
puts double_me 20f(x) = y. Sem efeitos colaterais. Se entra x agora e sai y, sempre sairá y quando entrar x. Exemplo puro:
a = Math.sin 70
b = 80 - 30
puts a * b
puts (Math.sin 70) * (80 - 30)Equivalência na substituição
example = "wow such example"
example.upcase!
puts example"Variáveis" não variáveis! Devem servir como aliases.
ERRADO:
example = "wow such example"
result = example.upcase
puts result"Variáveis" não variáveis! Devem servir como aliases. O estado deve trafegar, não ser alterado!
CORRETO:
require 'pattern-match'
using PatternMatch
def fact(n)
  match (n) do
    with(0) { 1 }
    with(n) { n * fact(n - 1) }
  end
endDefina o fluxo do programa através da forma dos seus valores
https://github.com/k-tsj/pattern-match
def fib(n)
  if (0..1).include? n
    then n
    else fib(n - 1) + fib(n - 2) if n > 1
  end
end
puts fib 20Esqueça os loops. Esqueça estruturas imperativas
class Proc
  def self.compose(f, g)
    lambda { |*args| f[g[*args]] }
  end
  
  def *(g)
    Proc.compose(self, g)
  end
endCombine funções e obtenha novas funções.
Vamos implementar composição na linguagem...
inc = lambda { |x| x + 1 }
double = lambda { |x| x * 2 }
double_inc = double * inc
# (20 + 1) * 2 = 42
puts double_inc[20]Combine funções e obtenha novas funções.
Vamos utilizar nossa implementação!
my_list = 1 .. 10
my_list_by_three = my_list.map do |x|
  x * 3
endmy_list = 1 .. 10
my_even_list = my_list.select do |x|
  x % 2 == 0
endmy_list = 1 .. 10
my_sum = my_list.reduce do |acc, x|
  acc + x
end
((((((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9) + 10
Pelo menos em relação à concorrência e ao paralelismo
1 core ≃ 1k cores
Questions?