🚀 Programação Funcional

Funções como valores, composição e conceitos funcionais!

🔮

O que é programação funcional?

Programação funcional trata funções como cidadãos de primeira classe: você pode passar funções como argumentos, retornar funções, e compor funções.

Características

Funções anônimas (lambdas)

-- Função anônima simples
local dobro = função(x) retorne x * 2 fim
exiba(dobro(5))  -- 10

-- Passando função como argumento
função aplique(f, valor)
    retorne f(valor)
fim

exiba(aplique(função(x) retorne x ^ 2 fim, 5))  -- 25

Funções de alta ordem

Map (transformar lista)

função map(lista, f)
    local resultado = {}
    para i, valor em obtenha_pares_indexados(lista) faça
        tabela.insira(resultado, f(valor))
    fim
    retorne resultado
fim

local numeros = {1, 2, 3, 4, 5}
local quadrados = map(numeros, função(x) retorne x ^ 2 fim)
-- quadrados = {1, 4, 9, 16, 25}

Filter (filtrar lista)

função filter(lista, predicado)
    local resultado = {}
    para i, valor em obtenha_pares_indexados(lista) faça
        se predicado(valor) então
            tabela.insira(resultado, valor)
        fim
    fim
    retorne resultado
fim

local numeros = {1, 2, 3, 4, 5, 6}
local pares = filter(numeros, função(x) retorne x % 2 == 0 fim)
-- pares = {2, 4, 6}

Reduce (agregar lista)

função reduce(lista, f, inicial)
    local acumulador = inicial
    para i, valor em obtenha_pares_indexados(lista) faça
        acumulador = f(acumulador, valor)
    fim
    retorne acumulador
fim

local numeros = {1, 2, 3, 4, 5}
local soma = reduce(numeros, função(a, b) retorne a + b fim, 0)
-- soma = 15

local produto = reduce(numeros, função(a, b) retorne a * b fim, 1)
-- produto = 120

Composição de funções

-- Compor duas funções
função componha(f, g)
    retorne função(x)
        retorne f(g(x))
    fim
fim

local dobro = função(x) retorne x * 2 fim
local incremento = função(x) retorne x + 1 fim

local dobro_e_incremento = componha(incremento, dobro)
exiba(dobro_e_incremento(5))  -- 11 (5*2 + 1)

Currying (aplicação parcial)

-- Função que retorna função
função some(a)
    retorne função(b)
        retorne a + b
    fim
fim

local some_5 = some(5)
exiba(some_5(3))   -- 8
exiba(some_5(10))  -- 15

-- Currying genérico
função curry(f, a)
    retorne função(b)
        retorne f(a, b)
    fim
fim

local multiplique = função(a, b) retorne a * b fim
local dobre = curry(multiplique, 2)
exiba(dobre(7))  -- 14

Recursão com TCO (Tail Call Optimization)

Sol otimiza chamadas de cauda (tail calls) - quando a última operação é chamar outra função.

Fatorial com TCO

-- Versão com TCO (não estoura pilha)
função fatorial(n, acumulador)
    acumulador = acumulador ou 1
    se n <= 1 então
        retorne acumulador
    fim
    retorne fatorial(n - 1, n * acumulador)  -- Tail call!
fim

exiba(fatorial(5))     -- 120
exiba(fatorial(10000))  -- Não estoura a pilha!

Fibonacci com TCO

função fibonacci(n, a, b)
    a = a ou 0
    b = b ou 1
    se n == 0 então
        retorne a
    fim
    retorne fibonacci(n - 1, b, a + b)  -- Tail call!
fim

exiba(fibonacci(10))  -- 55
exiba(fibonacci(50))  -- 12586269025

Exemplo completo: Pipeline funcional

-- Funções utilitárias
função map(lista, f)
    local resultado = {}
    para i, v em obtenha_pares_indexados(lista) faça
        tabela.insira(resultado, f(v))
    fim
    retorne resultado
fim

função filter(lista, pred)
    local resultado = {}
    para i, v em obtenha_pares_indexados(lista) faça
        se pred(v) então tabela.insira(resultado, v) fim
    fim
    retorne resultado
fim

função reduce(lista, f, inicial)
    local acc = inicial
    para i, v em obtenha_pares_indexados(lista) faça
        acc = f(acc, v)
    fim
    retorne acc
fim

-- Pipeline: pegar números, filtrar pares, dobrar, somar
local numeros = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

local resultado = reduce(
    map(
        filter(numeros, função(x) retorne x % 2 == 0 fim),
        função(x) retorne x * 2 fim
    ),
    função(a, b) retorne a + b fim,
    0
)

exiba(resultado)  -- 60 (2+4+6+8+10 = 30, dobrado = 60)

Closures (captura de variáveis)

função crie_contador()
    local count = 0
    retorne função()
        count = count + 1
        retorne count
    fim
fim

local contador1 = crie_contador()
local contador2 = crie_contador()

exiba(contador1())  -- 1
exiba(contador1())  -- 2
exiba(contador2())  -- 1 (contador independente)

Vantagens da programação funcional

TCO: Sol otimiza tail calls automaticamente! Use recursão de cauda para evitar estouro de pilha.
Sol suporta programação funcional completa: funções de alta ordem, closures, composição e TCO!
```