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
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.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: Funções puras e imutabilidade.
Os objetivos desta aula. 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.
Veja o essencial, parte por parte.
O que torna uma função pura. Uma função pura depende só dos argumentos e não causa efeitos colaterais.
Por que a pureza facilita a vida. Deixe o núcleo da lógica em funções puras que só transformam dados.
Imutabilidade na prática. A imutabilidade anda de mãos dadas com a pureza.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
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 foracom_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] mudousorted 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.