Python e Programação Funcional
Tags: python, funcional, ptbr
Published: 2020-06-18 02:21:47

---
title: Python e Programação Funcional
published: true
description: Vamos entender um pouco sobre os principais conceitos do paradigma funcional e como aplicá-los em python!
tags: python, funcional, ptbr
cover_image: https://cdn.pixabay.com/photo/2020/06/08/03/55/feather-5272833_960_720.jpg
---

A programação funcional pode nos ajudar a reduzir efeitos colaterais e tornar nosso código mais simples de manter. Nesse post, explicarei um pouco sobre os seus principais conceitos e como podemos aplicá-los em Python!

## O que é Programação Funcional?

Programação funcional é um **paradigma de programação**.
Resumidamente, paradigma de programação é uma forma de classificar linguagens baseando-se em suas funcionalidades e estilo de código. Normalmente, isso vai te guiar na forma que você vai estruturar seu código e desenvolver soluções.

Na programação funcional, funções são utilizadas para resolver problemas, buscando evitar mutabilidade de dados e estados.

Talvez essa definição seja um pouco confusa de início, mas existem alguns conceitos importantes que farão as coisas terem mais sentido!

## Funções de primeira classe

Como dito acima, na programação funcional resolvemos problemas usando funções. Nesse paradigma, elas são tratadas como funções de primeira classe.
Isso significa que uma função pode ser atribuída a uma variável, ser passada como argumento para outra função ou devolvida como resultado.

Esse é um exemplo simples, mostrando que conseguimos atribuir a função embutida `print` a uma variável chamada `escreve`:
```bash
>>> escreve = print
>>> escreve
<built-in function print>
>>> escreve("abc")
abc
```

## Imutabilidade de dados

Os dados usados na programação funcional não devem ser modificados após a sua criação. Por exemplo, se quisermos modificar um dado em uma lista, nós devemos criar uma cópia da lista com a modificação desejada ao invés de alterar diretamente a lista original.

Um exemplo de tipo de dado imutável em Python é a `tupla`. No exemplo a seguir, utilizamos a classe collections para definir a tupla nomeada Pessoa:

```python
import collections
Pessoa = collections.namedtuple('Pessoa', ['nome', 'personagem'])

elenco_bacurau = (Pessoa(nome='Sonia Braga', personagem='Domingas'),
                  Pessoa(nome='Barbara Colen', personagem='Teresa'),
                  Pessoa(nome='Silvero Pereira', personagem='Lunga'))
```

Aqui, estamos garantindo que os atributos `nome` e `personagem` não serão alterados diretamente e nenhum item de `elenco_bacurau` será excluído.

```bash
>>> elenco_bacurau[0].nome = 'Kleber'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
```
```bash
>>> del elenco_bacurau[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object doesn't support item deletion
```

<!-- ## Independente de estado

Programas escritos seguindo esse paradigma devem ser independentes de estado. Dessa forma, uma função só precisa depender dos dados passados para ela e não de dados externos.
-->
## Funções puras

As funções ditas como puras são as que não produzem efeitos colaterais, ou seja, não alteram o estado do programa. Um novo valor é criado e retornado.

Se quiséssemos remover o último item de uma lista, o jeito não funcional seria alterar a lista utilizando, por exemplo, o método `pop`. Uma solução funcional retornaria uma cópia dessa lista alterada, como vemos no exemplo:

```python
def remove_ultimo(lista):
    """Remove item, alterando a lista original"""
    lista.pop(-1)

def lista_sem_ultimo(lista):
    """Retorna cópia da lista sem o último item"""
    return lista[:-1]
```

## Funções de ordem superior

Funções de ordem superior podem aceitar outra função como argumento e podem retornar uma função como saída.

Python possui algumas funções embutidas de ordem superior (como `map` e `filter`) que nos permitem escrever códigos seguindo a programação funcional, de forma concisa e sem efeitos colaterais.

Abaixo, um exemplo de uso da função `map` que aplica uma `lambda` (função anônima) para cada item do iterável:

```python
>>> integers = [1, 2, 3, 4, 5]
>>> list(map(lambda x: x * x, integers))
[1, 4, 9, 16, 25]
>>> integers
[1, 2, 3, 4, 5]
```

## Conclusão

Python não é uma linguagem puramente funcional, mas, por ser **multiparadigma**, ela dá suporte ao paradigma funcional e existem diversas vantagens em utilizá-lo.

Testar um programa funcional pode ser mais simples (tudo o que você precisa é de um conjunto de entradas e um conjunto esperado de saídas). Além disso, facilita a reutilização de código — como a função não depende de nenhuma variável ou estado externo, é fácil chamá-la de outro contexto.

É interessante ter visões diferentes de como resolver determinado problema, e dependendo do contexto, a programação funcional pode nos ajudar a chegar a uma solução simples e eficiente. :sparkles:

### Referências

- [Functional Programming HOWTO](https://docs.python.org/3/howto/functional.html)

- [An Introduction to Functional Programming with Python](https://julien.danjou.info/python-and-functional-programming/)

- [Functional Programming in Python
](https://stackabuse.com/functional-programming-in-python/)

- [Elements of Functional Programming in Python](https://towardsdatascience.com/elements-of-functional-programming-in-python-1b295ea5bbe0)

Esse post é baseado na palestra que apresentei no Python Day 2019, realizado pelo Grupy RN. Os slides podem ser vistos [aqui](https://github.com/elmasantos/talks/tree/master/python-day-2019)

---
*Imagem de [James Lee](https://pixabay.com/pt/users/picsbyjameslee-13643653) por [Pixabay](https://pixabay.com)*