How can I associate an expression that uses itself?

I have lazy-seqto calculate the fibonacci sequence.

(def fibonacci
  (lazy-cat [0 1] (map + fibonacci (rest fibonacci))))
=> #'user/fibonacci
(take 10 fibonacci)
=> (0 1 1 2 3 5 8 13 21 34)

But when I try to put fibonacciinlet

(let [fibonacci
  (lazy-cat [0 1] (map + fibonacci (rest fibonacci)))]
  (take 10 fibonacci))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: fibonacci in this context, compiling:...

How to solve it?

+4
source share
2 answers

In contrast, defbinding xto f, made (let [x f] ...)no visible inside f. More precisely, the binding to xis performed after the evaluation f. To have recursive definitions, you need to use letfnone that is designed to define functions. Therefore, you can no longer consider fibonaccihow LazySeq, but you can define it as a function that returns LazySeq:

(letfn [(fibonacci [] 
          (lazy-cat [0 1] (map + (fibonacci) (rest (fibonacci)))))]
  (take 10 (fibonacci)))
+4
source

, , let, :

(defn override-variables [x]
  (let [x (do-some-stuff-with x)]
    (do-stuff x))

, .

, (fn fib-func [args] ...) lazy-seq , .

(let [fib ((fn rfib [a b] 
             (lazy-seq (cons a (rfib b (+ a b)))))
           0 1)]
  (take 10 fib)) 
+2

Source: https://habr.com/ru/post/1606544/


All Articles