Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Essa função não faz nenhum sentido!

Olá a todos!

Devo dizer que meu entendimento sobre a programação funcional estava indo relativamente bem... até me deparar com esse exercício.

Eu consigo fazer sentido a isso:

(defn fib [x] 
  (if (or (= x 1) (= x 2))
    x
    (if (>= x 2)
      (println "Não pode ser número negativo")
      (+ (fib (- x 1)) (fib (- x 2))))))

Está de acordo com a lógica, digamos, "não funcional" da programação, só que essa função:

(defn fib[x]
    (loop [a 1 b 1 numero 2]
        (if 
            (= numero x) b
            (recur b (+ a b) (inc numero)))))

Me desculpem, mas não consigo ver como ela se relaciona com a primeira função.

Eu peguei essa resposta que foi escrita pelo Maurício e devo dizer que, pra mim, não faz sentido!

Talvez eu não tenha entendido o funcionamento do loop ou como o recur, que está recebendo 3 parâmetros, ao invés de 1 como é a função original fib recebe, mas de forma alguma, pelo menos não seguindo a mesma lógica, da pra sair da primeira função e chegar na segunda.

Alguém, por favor, poderia me explicar o que está acontecendo?

2 respostas
solução!

Fala aí Bruno tudo bem?

Nessa funcão:

(defn fib[x]
    (loop [a 1 b 1 numero 2]
        (if 
            (= numero x) b
            (recur b (+ a b) (inc numero)))))

O que está acontecendo é que o recur está fazendo uma recursão de cauda para o loop e não para o fib

O loop está recebendo 3 valores a e b para fazer a sequencia de fibonacci ( 1+1, 2 + 1 e etc...) e a variável numero que é um contador começando em 2. Esse loop vai repetir o processo enquanto o contador não for igual ao valor que você passou para a funcão fib.

Exemplo:

(fib 3)

Nesse casso o loop vai ser executado 2 vezes. A primeira vez o for executado o loop as variaveis estaram com os seguintes valores.

a=1 b=1 numero=2

No if vai ser comparado o valor da variável numero e o valor que foi passado para a função fib. Como não são iguais será executado o recur.

O recur vai chamar o loop passando para ele os valores de b para o primeiro parâmetro do loop. (+ a b) para o segundo parâmetro do loop e (inc numero) para o terceiro parâmetro do loop.

Com isso na segunda volta do loop os valores para os parâmetros são:

a=1 b=2 numero=3

No if será comparado o valor da variável numero com o valor passado para a função fib. Como os dois são iguais será retornado o valor da variável b.

Espero ter ajudado. []s

Excelente explicação, mas tem um pequeno problema nessa fórmula. Se o usuário chamar:

(fib 1)

ao invés de retornar o valor 1, que seria o resultado, a função entraria em um loop infinito, já que numero nunca seria 1.

No mais, foi uma excelente explicação. Esclareceu bastante o que está acontecendo, apesar de eu ainda não achar a função mais intuitiva de todas.