AULA 27 MÓDULO 2 programação funcional ⏱ 50 min

Composição de Funções

pipe() e compose(). Dividir funções grandes em pequenas e testáveis. Middlewares Express como pipeline funcional.

pipecomposecomposiçãomiddlewarepipelineUnix philosophy

O que é composição

Composição é combinar funções simples para criar funções complexas. Em vez de uma função grande que faz tudo, você encadeia funções pequenas, cada uma com uma responsabilidade.

🔧
Unix philosophy
"Faça uma coisa e faça bem. Conecte componentes simples com interfaces limpas." É exatamente isso que composição de funções implementa.
// Sem composição — função gigante
processOrder(order) // valida, desconto, imposto, formata...
// 80 linhas, difícil de testar

// Com composição
validate → applyDiscount → addTax → format
// 4 funções de 5 linhas cada, testáveis individualmente

pipe() e compose()

pipe executa da esquerda para a direita (mais natural). compose da direita para a esquerda (matemático). Na prática do JS moderno, pipe é mais usado.

🔗
operador pipeline
TC39 está adicionando o operador |> ao JavaScript (pipeline operator). Enquanto não está estável, use uma implementação de pipe com reduce.

Pipeline de middlewares

O middleware do Express É composição funcional. Cada middleware recebe (req, res, next) e decide se passa para o próximo (next) ou não. É um pipeline.

⛓️
chain de middlewares
app.use(cors()).use(auth).use(validate).use(handler) é literalmente pipe(cors, auth, validate, handler)(request). Express implementa composição funcional como seu core.
javascript
// Implementando pipe e compose
const pipe    = (...fns) => x => fns.reduce((v,f) => f(v), x)
const compose = (...fns) => x => fns.reduceRight((v,f) => f(v), x)

// Funções simples e testáveis
const trim       = s => s.trim()
const toLowerCase = s => s.toLowerCase()
const removeSpaces= s => s.replace(/\s+/g, '-')
const slugify     = pipe(trim, toLowerCase, removeSpaces)

slugify("  Hello World  ") // "hello-world"

// Pipeline para processar pedido
const validate      = order => { if (!order.items?.length) throw Error('Sem itens'); return order }
const applyDiscount  = order => ({ ...order, total: order.total * 0.9 })
const addTax         = order => ({ ...order, total: order.total * 1.12 })
const processOrder   = pipe(validate, applyDiscount, addTax)

processOrder({ items: [1], total: 100 })
// { items: [1], total: 100.8 } — 10% desc + 12% tax
quiz · aula 27
Teste seus conhecimentos
0/3 respondidas
QUESTÃO 01
Qual a diferença entre pipe e compose?
QUESTÃO 02
Por que dividir uma função grande em funções menores compostas?
QUESTÃO 03
O sistema de middlewares do Express é um exemplo de...
0/3