Módulo 4 - Programação funcional

Funções puras e imutabilidade

9 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

Velocidade

O que você vai aprender

  • Identificar o que torna uma função pura e por que isso ajuda.
  • Reconhecer efeitos colaterais e quando evitá-los.
  • Entender como a imutabilidade reduz bugs de estado.
  • Preferir transformar dados a alterá-los no lugar.

O que torna uma função pura

A programação funcional gira em torno de uma ideia simples: tratar funções como valores e preferir funções puras. Uma função é pura quando seu resultado depende apenas dos argumentos que recebe e ela não muda nada fora de si. Chame-a mil vezes com os mesmos dados e o resultado será sempre o mesmo, sem surpresas. Ela não mexe em variáveis globais, não escreve em arquivos, não altera a lista que recebeu. Toda a sua ação é devolver um valor.

# Pura: so depende dos argumentos, nao altera nada fora.
def com_desconto(preco: float, taxa: float) -> float:
    return preco * (1 - taxa)

print(com_desconto(100.0, 0.1))  # 90.0
print(com_desconto(100.0, 0.1))  # 90.0 sempre

# Impura: altera uma lista recebida (efeito colateral).
def adicionar_item(carrinho: list[str], item: str) -> None:
    carrinho.append(item)  # muda o argumento por fora

com_desconto é pura; adicionar_item causa efeito colateral ao mudar a lista recebida.

A função com_desconto é pura: dois preços iguais e duas taxas iguais dão sempre o mesmo resultado, e nada mais no programa muda. Já adicionar_item é impura, porque altera a lista que recebeu, um efeito colateral. Isso não é proibido, e às vezes é exatamente o que você quer, mas funções impuras são mais difíceis de entender e testar, porque o resultado passa a depender de coisas fora dos argumentos. A recomendação prática é manter pura a maior parte da lógica e isolar os efeitos colaterais em poucos pontos.

Por que a pureza facilita a vida

Funções puras trazem vantagens concretas. Testar fica trivial: você passa argumentos e confere o retorno, sem precisar preparar um estado global nem limpar nada depois. Entender fica mais fácil: para saber o que a função faz, basta olhar para ela, sem rastrear o que ela altera pelo programa. E reaproveitar fica seguro: como ela não depende de contexto externo, você a move para outro lugar sem medo. Muito da dor de manter software vem de efeitos colaterais espalhados; concentrá-los é um alívio.

Função pura

  • Resultado depende só dos argumentos
  • Mesma entrada, mesma saída, sempre
  • Testar é passar valores e conferir o retorno
  • Fácil de mover e reaproveitar

Função impura

  • Resultado depende de estado externo
  • Pode variar conforme o que mudou por fora
  • Testar exige montar e limpar o contexto
  • Move junto as dependências ocultas

Imutabilidade na prática

A imutabilidade anda de mãos dadas com a pureza. Em vez de alterar uma estrutura no lugar, você gera uma nova a partir dela. Ordenar uma lista com sorted devolve uma lista nova, sem tocar na original; usar o método sort altera a lista existente. Somar um item a uma tupla cria outra tupla, pois tuplas não mudam. Trabalhar assim evita o bug em que uma parte do código altera um dado que outra parte ainda usava, esperando o valor antigo. O dado passa a ser previsível.

numeros = [3, 1, 2]

# Imutavel: cria uma lista nova, preserva a original.
ordenados = sorted(numeros)
print(ordenados)  # [1, 2, 3]
print(numeros)    # [3, 1, 2]  intacta

# Mutavel: altera a lista no lugar.
numeros.sort()
print(numeros)    # [1, 2, 3]  mudou

sorted devolve uma lista nova; sort altera a original. A imutabilidade preserva o dado.

Nenhum estilo é o certo em absoluto; Python é uma linguagem multiparadigma e mistura os dois com naturalidade. O ponto é ter a escolha consciente. Quando você prefere transformar em vez de alterar, e mantém a lógica em funções puras, o código fica mais fácil de raciocinar, testar e paralelizar. As próximas aulas trazem ferramentas que apoiam esse estilo: o functools, com reduce, partial e cache, e o itertools, com geradores e combinadores prontos.

Teste rápido

O que caracteriza uma função pura?

Perguntas frequentes

Preciso escrever todo o programa só com funções puras?
Não, e nem seria possível: ler entrada, gravar arquivos e mostrar resultados são efeitos colaterais necessários. A ideia é manter pura a maior parte da lógica e concentrar os efeitos em poucos pontos, nas bordas. Assim o núcleo difícil de testar fica pequeno e o resto, simples de verificar.
Imutabilidade não desperdiça memória criando cópias?
Cria objetos novos, sim, mas na maioria dos programas isso é insignificante perto do ganho em clareza e segurança. Quando o volume de dados é grande e o desempenho importa, você mede e decide onde vale mutar no lugar. Para o dia a dia, transformar em vez de alterar compensa.
Qual a diferença entre sorted e o método sort?
sorted devolve uma lista nova ordenada e deixa a original intacta, um estilo imutável. O método sort ordena a própria lista no lugar e não devolve nada útil. Use sorted quando quiser preservar a lista de origem, e sort quando realmente quiser alterá-la.
Tuplas ajudam com imutabilidade?
Ajudam bastante. Uma tupla não pode ser alterada depois de criada, então usá-la no lugar de uma lista sinaliza e garante que aquele dado não muda. Para coleções que representam um valor fixo, como uma coordenada ou uma configuração, a tupla é uma escolha natural de imutabilidade.
Efeito colateral é sempre ruim?
Não. Salvar um arquivo, enviar uma resposta e registrar um log são efeitos colaterais desejados; sem eles o programa não faria nada útil. O problema é quando estão espalhados e escondidos, dificultando entender o código. A meta é torná-los explícitos e concentrados, não eliminá-los.
Por que funções puras são mais fáceis de testar?
Porque o resultado depende só dos argumentos. O teste vira passar valores e conferir o retorno, sem preparar estado global, sem simular arquivos, sem limpar nada depois. Uma função impura, que depende de contexto externo, exige montar esse contexto no teste, o que dá mais trabalho e mais chance de erro.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.