Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 59 additions & 40 deletions posts/9.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,97 +2,116 @@
title: "9 - Schönfinkelisação e Aplicação Parcial"
author: "Kjetil Valle"
translatedBy: "Andrei Macedo"
date: "2020-12-09"
date: "09 de dezembro de 2020"
published: false
description: "Como discutimos em um artigo anterior, uma das coisas que podemos fazer com uma função é chamá-la com menos argumentos do que ela espera. Isso irá resultar em uma nova função onde os argumentos que nós providenciamos estão ligados a valores, e os argumentos restantes ainda são esperados como parâmetros. Como nós aplicamos a função para apenas alguns de seus argumentos, chamamos essa técnica de aplicação parcial."
---

## Schönfinkelisation and Partial Application
## Schönfinkelisação e Aplicação Parcial

As we discussed in a previous article, one of the things we can do with a function is to call it with fewer arguments than it is expecting. This will result in a new function where the arguments we did provide are bound to values, and the remaining arguments are still expected as parameters. Since we apply the function to only some of its arguments, we call this technique partial application.
Como discutimos em um artigo anterior, uma das coisas que podemos fazer com uma função é chamá-la com menos argumentos do que ela espera. Isso irá resultar em uma nova função onde os argumentos que nós providenciamos estão ligados a valores, e os argumentos restantes ainda são esperados como parâmetros. Como nós aplicamos a função para apenas alguns de seus argumentos, chamamos essa técnica de aplicação parcial.

Let's see how this works in Elm:
Vamos ver como isso funciona em Elm:

-- A simple function, adding together two arguments.
-- If you find the type signature confusing, don't worry
-- about that for now.
```elm
-- Uma função simples, que soma 2 argumentos.
-- Se você acha a assinatura de tipos confusa, não se preocupe
--- com isso agora.
add : number -> number -> number
add a b =
a + b

-- A relatively useless function, used to illustrate
-- partial application
-- Uma função relativamente inútil, usada para ilustrar
-- aplicação parcial
incrementByFive : number -> number
incrementByFife =
-- Here we partially apply the `add` function. By
-- only providing the first argument, we get a new
-- function in return, which will accept another
-- number, which it will always add 5 to!
-- Aqui nós aplicamos parcialmente a função `add`. Ao
-- providenciar apenas o primeiro argumento,
-- nós temos uma nova função em retorno, que vai
-- aceitar outro número, o qual sempre irá ser adicionado a 5.
add 5

-- Yes, this would return 42
-- Sim, isso nos retornaria 42
incrementByFive 37
```

Currying
## Currying

It might surprise you that we are able to call the function add with only one argument. But, in fact, it is possible to turn a function of any number of arguments into a function of only one by using a process called currying.
O fato de que podemos chamar a função `add` com apenas um argumento pode te surpreender. Mas, de fato, é possível transformar uma função com qualquer número de argumentos em uma função com apenas um ao usar um processo chamado currying.

Say we have this little JavaScript function:
Digamos que temos essa pequena função em JavaScript:

```js
function add(a, b) {
return a + b
}
```

We can't just simply partially apply this function. In JavaScript you need to provide all the arguments when applying a function. However, we might define this function instead:
Nós não podemos simplesmente aplicar parcialmente essa função. Em JavaScript você precisa providenciar todos os argumentos quando aplicar uma função. Contudo, nós podemos definir essa função no lugar:

```js
function curriedAdd(a) {
return function(b) {
return a + b
}
}
```

By using currying, we can convert add into curriedAdd. And this process will work with functions of any number of arguments. And with this new function, we're free to do things like this again:
Ao usar currying, nós podemos converter `add` em `curriedAdd`. E esse processo vai trabalhar com funções de qualquer número de argumentos. E com essa nova função, nós estamos livres para fazer coisas como essa novamente:

```js
incrementByFive = curriedAdd(5)
```

But why didn't we have to do this in Elm? That's because in Elm, like many other functional programming languages, functions are curried by default. This means that all functions can easily be partially applied! And that's also why the type signature we saw in the first example looks like this:
Mas por quê nós não precisamos fazer isso em Elm? Isso é porque em Elm, assim como muitas outras linguagens de programação funcional, o currying das funções é feito por padrão. Isso significa que todas as funções podem ser facilmente parcialmente aplicadas! E isso é também o motivo pelo qual a assinatura de tipos que vimos no primeiro exemplo se parece com isso:

```elm
add : number -> number -> number
```

A different way to read this type is like this:
Uma maneira diferente de ler esse tipo seria assim:

```elm
add : number -> (number -> number)
```

So, as you see, add is in fact a function which takes only one argument (a number) and returns a function (with the type number -> number).
Why is this useful?
Então, como pode ver, `add` é de fato uma função que toma apenas um argumento (um `number`) e retorna uma função (com o tipo `number -> number`).

The incrementByFive example above is obviously quite contrived. But you'd be surprised how often partial application turns out to be useful when writing code in a functional language.
## Por que isso é útil?

This often occurs when we're using functions like map or filter. These functions expects an argument which is a function that can be applied to every element of a list, and which must thus take exactly one argument. It is often convenient to create this function by using partial application.
O exemplo `incrementByFive` acima é obviamente artificial. Mas você se surpreenderia com o quão frequentemente a aplicação parcial acaba sendo útil ao escrever código em uma linguagem funcional.

Here are a couple of examples, again using Elm.
Isso ocorre frequentemente quando estamos usando funções como map ou filter. Essas funções esperam um argumento que é uma função que pode ser aplicada a todos os elementos de uma lista, e que deve então tomar exatamente um argumento. É conveniente criar essa função utilizando a aplicação parcial.

-- Convert a list of `Maybe String` into something that
-- can be displayed to the user, using "n/a" where we
-- don't have a value.
Aqui estão alguns exemplos, novamente usando Elm.

```elm
-- Converte uma lista de `Maybe String` em algo que
-- Pode ser mostrado ao usuário, usando "n/a" onde
-- não temos um valor.
displayNames = List.map (Maybe.withDefault "n/a") [ Just "NBN", Nothing, Just "Jinteki", Just "Wayland"]
-- Result: [ "NBN", "n/a", "Jinteki", "Wayland" ]
-- Resultado: [ "NBN", "n/a", "Jinteki", "Wayland" ]

-- Filter a list of names to include only the people
-- named "John".
-- Filtra uma lista de nomes para incluir apenas as pessoas
-- chamadas "John"
johns = List.filter (String.startsWith "John") [ "John Snow", "John Rambo", "James Bond", "John McClane", "Jack Bauer"]
-- Result: [ "John Snow", "John Rambo", "John McClane" ]
-- Resultado: [ "John Snow", "John Rambo", "John McClane" ]
```

Both Maybe.withDefault and String.startsWith expect to get two arguments, but by only applying them partially we get exactly what we need.
Ambos [Maybe.withDefault](https://package.elm-lang.org/packages/elm/core/latest/Maybe#withDefault) e [String.startsWith](https://package.elm-lang.org/packages/elm/core/latest/String#startsWith) esperam receber 2 argumentos, mas apenas ao aplicá-los parcialmente nós recebemos o que precisamos.

As another example, say we have a function with the following type signature in our Elm application.
Como outro exemplo, digamos que nós temos uma função com a seguinte assinatura de tipo em nossa aplicação Elm.

```elm
log : LogConfig -> Message -> Cmd msg
```

A função pecisa de um tipo de configuração e uma mensagem. A depender da configuração, a mensagem pode ser usada como log em um serviço de backend ou talvez ao console de um browser. Especificar a configuraçao em todos os lugares em que precisamos de um log seria incômodo. No lugar disso nós podemos apenas aplicar parcialmente o log para a configuração uma vez, e usar a função resultante no resto da aplicação!

The function requires a configuration type and a message. Depending on the configuration, the message might be logged to a backend service or maybe to the browser console. To specify the configuration everywhere we need to log something would be rather cumbersome. Instead we can just partially apply log to the configuration once, and use the resulting function in the rest of the application!
Quanto mais acostumado você fica com programação funcional, mais lugares você irá encontrar onde uma função parcialmente aplicada é exatamente o que você precisa.

The more used you get to functional programming, the more places you will find where a partially applied function is exactly what you need.
Schönfinkeli-what-now?
## Schönfinkeli-o-quê?

The name currying is a reference to the American logician Haskell Brooks Curry. (If the name sounds familiar, that's no coincidence: Mr. Curry is quite popular among computer scientists, and has in fact three languages named after him: Haskell, Brook and Curry…)
O nome currying é uma referência ao matemático Americano Haskell Brooks Curry. (Se o nome parece familiar, não é coincidência: O Sr. Curry é bastante popular entre os cientistas da computação, e tem de fato três linguagens nomeadas em homenagem a ele: [Haskell](https://www.haskell.org/), [Brook](http://graphics.stanford.edu/projects/brookgpu/) e [Curry](https://www-ps.informatik.uni-kiel.de/currywiki/)…)

However, he was not the one to first discover the technique of currying. The Russian logician and mathematician Moses Ilyich Schönfinkel had already described the concept previously, and was in fact also attributed by Curry for doing so. So, maybe we should start to refer to it as schönfinkelisation instead?
No entando, ele não foi o responsável por descobrir a técnica de currying. O matemático Russo Moses Ilyich Schönfinkel já havia descrito o conceito previamente, e foi também atribuído por Curry por isso. Então, talvez nós devêssemos começar a referenciar isso como *schönfinkelisation*?