<commit_before>---
layout: post
title: "24 dias de Hackage, 2015 - dia 11 - monad-loops: Refatorando para evitar escrever funções recursivas"
author: <NAME>
author_url: "http://conscientiousprogrammer.com/"
translator: <NAME>
translator_url: "https://github.com/lucastadeu"
excerpt_separator: "<!-- more -->"
---
Esse é um artigo escrito por Franklin Chen e traduzido para o português.
[Ler original](http://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/)_

## Índice de toda a série
O índice de toda a série está no topo do artigo para o [dia 1](/2015/12/08/aperitivos-de-haskell-24-dias-de-hackage-2015-dia-1-introducao-e-stack.html).

- - -

## Dia 11

Desgosto, frequentemente, escrever funções recursivas. Recursão é uma forma
de `goto` e, portanto, recursão é (conceitualmente) a infraestrutura
baixo-nível de linguagem de montagem de programação funcional: um bloco
fundamental para construção mas que, não necessariamente, quero ver todos os
dias.

<!-- more -->

Uma analogia: programação imperativa nos anos 1960 foi alterada
significativamente quando novas estruturas de controle como laços `for` e
`while` modificaram sua aparência ao remover o _boilerplate_ de utilizar-se
a instrução de baixo-nível `goto` em todos os lugares; `for` e `while` são
as estruturas de controle de alta ordem da programação imperativa.

Em programação funcional, o _boilerplate_ da recursão é evitado por meio
da escrita e utilização de funções (de alta ordem) como `map`, `filter`,
`foldr` e `traverse`. A parte legal é que, em programação funcional,
essas são funções ordinárias disponíveis em espaço de usuário; já em
programação imperativa, estruturas de controle são embutidas na linguagem
e, geralmente, não é tão simples criar suas próprias estruturas.

Por que você gostaria de definir suas próprias estruturas de controle?
Vou mostrar alguns exemplos e uma pequena biblioteca muito útil, `monad-loops`,
que você pode usar para evitar reinventar a roda.

## Um exemplo de tarefa

Vamos escrever uma função que simula o processo de _login_ de um usuário, no qual

- é requisitada senha do usuário
- um laço é iniciado, no qual
    - a tentativa de senha é lida
    - se não estiver correta, a senha é requisitada novamente e reiniciamos o laço
    - se estiver correta, saímos do laço
    - imprimimos parabéns

Abaixo está a tradução literal do pseudocódigo para Haskell, usando recursão para
o laço:

{% highlight haskell %}
logIn :: IO ()
logIn = do
  putStrLn "% Digite a senha:"
  go
  putStrLn "$ Parabéns!"

  where
    -- Utilização de recursão para o laço
    go = do
      guess <- getLine
      if guess /= "segredo"
        then do
          putStrLn "% Senha incorreta!"
          putStrLn "% Tente novamente:"
          go
        else
          return ()
{% endhighlight %}

Você gosta deste código? Eu me irrito com o fato de precisar escrever uma
função recursiva apenas para fazer um laço de repetição.


### Comparação com típico estilo imperativo


Compare com um código Python típico:

{% highlight Python %}
def log_in():
  print "% Digite a senha"
  while raw_input() != 'segredo:
    print "% Senha incorreta!"
    print "% Tente novamente:"
  print "% Parabéns!"
{% endhighlight %}

Há um motivo pelo qual [laços de repetição
`while`](https://en.wikipedia.org/wiki/While_loop) foram criados nos anos 1960
para programação imperativa. Era um modo de melhorar a expressão de
_padrões de fluxo de controle_ desse tipo. Seria um retrocesso voltar a
programar apenas no "estilo" `goto`. (Porém, isso não siginifca que `goto`
e recursão são coisas ruins. Knuth escreveu um
[famoso artigo em 1974](https://en.wikipedia.org/wiki/While_loop) defendendo
o uso cuidadoso de `goto` contra o que ele, corretamente, apontou como
dogma que foi longe demais contra o `goto`. O mesmo pode ser dito contra
qualquer dogma anti-recursão)

Quando eu ensino Haskell, me sinto envergonhado quando pessoas imaginam
o que é tão "errado" com Haskell que você não consegue escrever código 
tão intuitivo como o código Python acima - é necessário usar a tal da recursão
para fazer algo tão simples. O dilema que enfrento ao ensinar é o
pensamento na minha mente "Mas, mas, você também pode ter laços de repetição,
eles só não foram embutidos na linguagem e pode até escrever seus próprios
usando funções de alta ordem!", enquanto eu sei que muitos estão pensando "Mas
que porcaria de linguagem acadêmica, torre de marfim, imprática, ela nem ao
menos tem laços" e, enquanto isso, sei que não posso me precipitar para
funções de alta ordem na primeira hora.


### Fazendo seu próprio laço<commit_msg>Very minor changes in phrasing<commit_after>---
layout: post
title: "24 dias de Hackage, 2015 - dia 11 - monad-loops: Refatorando para evitar escrever funções recursivas"
author: <NAME>
author_url: "http://conscientiousprogrammer.com/"
translator: <NAME>
translator_url: "https://github.com/lucastadeu"
excerpt_separator: "<!-- more -->"
---
Esse é um artigo escrito por <NAME> e traduzido para o português.
[Ler original](http://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/)_

## Índice de toda a série
O índice de toda a série está no topo do artigo para o [dia 1](/2015/12/08/aperitivos-de-haskell-24-dias-de-hackage-2015-dia-1-introducao-e-stack.html).

- - -

## Dia 11

Desgosto, frequentemente, escrever funções recursivas. Recursão é uma forma
de `goto` e, portanto, recursão é (conceitualmente) a infraestrutura
baixo-nível de linguagem de montagem da programação funcional: um bloco
fundamental para construção mas que, não necessariamente, quero ver todos os
dias.

<!-- more -->

Uma analogia: programação imperativa nos anos 1960 foi alterada
significativamente quando novas estruturas de controle como laços `for` e
`while` modificaram sua aparência ao remover o _boilerplate_ de utilizar-se
a instrução de baixo-nível `goto` em todos os lugares; `for` e `while` são
as estruturas de controle de alta ordem da programação imperativa.

Em programação funcional, o _boilerplate_ da recursão é evitado por meio
da escrita e utilização de funções (de alta ordem) como `map`, `filter`,
`foldr` e `traverse`. A parte legal é que, em programação funcional,
essas são funções ordinárias disponíveis em espaço de usuário; já em
programação imperativa, estruturas de controle são embutidas na linguagem
e, geralmente, não é tão simples criar suas próprias estruturas.

Por que você gostaria de definir suas próprias estruturas de controle?
Vou mostrar alguns exemplos e uma pequena biblioteca muito útil, `monad-loops`,
que você pode usar para evitar reinventar a roda.

## Um exemplo de tarefa

Vamos escrever uma função que simula o processo de _login_ de um usuário, no qual

- é requisitada senha do usuário
- um laço é iniciado, no qual
    - a tentativa de senha é lida
    - se não estiver correta, a senha é requisitada novamente e reiniciamos o laço
    - se estiver correta, saímos do laço
    - imprimimos parabéns

Abaixo está a tradução literal do pseudocódigo para Haskell, usando recursão para
o laço:

{% highlight haskell %}
logIn :: IO ()
logIn = do
  putStrLn "% Digite a senha:"
  go
  putStrLn "$ Parabéns!"

  where
    -- Utilização de recursão para o laço
    go = do
      guess <- getLine
      if guess /= "segredo"
        then do
          putStrLn "% Senha incorreta!"
          putStrLn "% Tente novamente:"
          go
        else
          return ()
{% endhighlight %}

Você gosta deste código? Eu me irrito com o fato de precisar escrever uma
função recursiva apenas para fazer um laço de repetição.


### Comparação com típico estilo imperativo


Compare com um código Python típico:

{% highlight Python %}
def log_in():
  print "% Digite a senha"
  while raw_input() != 'segredo:
    print "% Senha incorreta!"
    print "% Tente novamente:"
  print "% Parabéns!"
{% endhighlight %}

Há um motivo pelo qual [laços de repetição
`while`](https://en.wikipedia.org/wiki/While_loop) foram criados nos anos 1960
para programação imperativa. Era um modo de melhorar a expressão de
_padrões de fluxo de controle_ desse tipo. Seria um retrocesso voltar a
programar apenas no "estilo" `goto`. (Porém, isso não siginifca que `goto`
e recursão são coisas ruins. Knuth escreveu um
[famoso artigo em 1974](https://en.wikipedia.org/wiki/While_loop) defendendo
o uso cuidadoso de `goto` contra o que ele, corretamente, apontou como
dogma que foi longe demais contra o `goto`. O mesmo pode ser dito contra
qualquer dogma anti-recursão)

Quando eu ensino Haskell, me sinto envergonhado quando pessoas imaginam
o que há de tão "errado" com Haskell que você não consegue escrever código tão
intuitivo como o código Python acima - é necessário usar a tal da recursão para
fazer algo tão simples. O dilema que enfrento ao ensinar é o pensamento na
minha mente "Mas, mas, você também pode ter laços de repetição, eles só não
foram embutidos na linguagem e pode até escrever seus próprios usando funções
de alta ordem!", enquanto eu sei que muitos estão pensando "Mas que porcaria de
linguagem acadêmica, torre de marfim, imprática, ela nem ao menos tem laços" e,
enquanto isso, sei que não posso me precipitar para funções de alta ordem na
primeira hora.


### Fazendo seu próprio laço
{'fraction_non_alphanumeric': 0.07094918504314478, 'fraction_numerical': 0.011505273250239693, 'mean_word_length': 4.041890440386681, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 12, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3639844', 'n_tokens_mistral': 3363, 'n_tokens_neox': 3164, 'n_words': 1267}