# Programação funcional
## Currying
**Currying** é o processo de transformar uma função que espera vários argumentos em uma que, quando chamada com menos argumentos, retorna uma nova função que recebe os argumentos restantes. Nesse contexto, **aplicação parcial** de uma função que sofreu currying é o ato de chamar a função passando menos argumentos, obtendo como resultado uma outra função.
Por exemplo, considere a função `produto`:
```javascript
function produto(a, b) {
return a * b;
}
```
Do jeito que a função está definida, não faz sentido realizar uma aplicação parcial:
A chamada `produto(2)` equivale à chamada `produto(2, undefined)`, resultado na multiplicação `2 * undefined`, cujo resultado é `NaN` (not a number).
Uma versão **curried** da função (i.e., função resultante do currying) pode ser escrita usando-se *closures*:
Vamos escrever uma versão *curried* dessa função? Essa versão deve receber `a` e retornar uma função que recebe `b`, que retorna uma função que recebe `x` e retorna a resposta.
Dá pra ver que, na versao curried, a maneira de chamar a função fica diferente: usamos `(3)(2)(42)` em vez de `(3, 2, 42)`. Isso porque cada chamada exceto a última retorna uma função, e por precisamos fazer 3 chamadas em vez de uma.
A vantagem de escrever uma função *curried* é que fica mais fácil construir funções com base nas funções curried fixando alguns argumentos. Por exemplo, a função `celsiusParaFahrenheit` pode ser escrita assim:
Até agora nós realizamos o currying the funções de forma manual, reescrevendo o código das funções. Em algumas linguagens, como Haskell, todas as funções são curried (e, portanto, admitem aplicação parcial). Isso não acontece com Javascript, mas há bibliotecas capazes de realizar o currying de qualquer função.
A biblioteca [Ramda](http://ramdajs.com/) possui uma função, `curry`, que recebe uma função e retorna uma versão curried dessa função. Como um bônus, é possível passar mais de um argumento em cada chamada
Currying é útil em conjunção de funções de alta ordem. Considere a função `arr.map(f)`, que retorna um array resultante da aplicação da função `f` a cada elemento de `arr`. A função `map` chama `f` passando um único argumento; como podemos então usar nossa função `primeiroGrau` para mapear elementos de um array? Usando currying:
Se você quer criar funções que podem ser curried, vale a pena pensar na ordem dos seus argumentos. O ideal é deixar concentrar os argumentos que tendem a ser fixados no início, e deixar os argumentos que variam mais no final da lista de argumentos. Note o exemplo da função `primeiroGrau(a, b, x)`: normalmente, quando chamamos a função várias, fixamos `a` e `b` e variamos `x`; por isso `x` foi colocado como último argumento.
## Composição de funções
(Baseado em https://medium.com/@collardeau/intro-to-functional-programming-concepts-in-javascript-b0650773139c e https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch5.html)
Uma forma mais legível de escrever `getPrimeiraInicial` é usando a função de alta ordem `pipe` (da biblioteca Ramda), que realiza a composição de funções.
Esse estilo de programar é chamado de pointfree, pois a função `getPrimeiraInicial` é definida sem declarar quais são os seus parâmetros.
Agora é com você. Crie uma função para retornar a quantidade de elementos de um array cujo quadrado é ímpar.
Note que as funções passadas para `pipe`, com exceção da primeira, devem receber apenas um argumento; por isso que, no exemplo anterior, foi necessário criar funções auxiliares. Em vez de criar essas funções explicitamente, no entanto, poderíamos usar currying para obter funções de um argumento. Escreva uma nova versão do código abaixo, considerando que as funções `R.filter` e `R.map` já são curried (todas as funções da biblioteca Ramda são curried):
A biblioteca Ramda também possui a função `compose`, que faz a mesma coisa que a função `pipe`, porém recebendo os argumentos na ordem inversa.
Exercícios: https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch5.html