5

I'm learning Clojure. Quite basic task is to generate Fibonacci sequence. I end up with pretty much copy of the imperative solution (and list is reversed, huh):

(defn n-fib [n]
  (if (= n 1) '(1)
  (loop [i 2 l '(1 1)]
    (if (= i n)
        l
        (recur (inc i) (cons (+ (fst l) (snd l)) l))))))

What is the better way, more functional, concise? Lazy sequences? How to use them? For example, in Haskell using laziness I can write one liner:

fib = 1 : 1 : zipWith + (tail fib) 

Note that Haskell solution offers infinite sequence (laziness...). If Clojure both eager and lazy solutions can be (even like get n-length list) I would like to know both.

Update: Another solution I got yields not reversed list, but it uses stack to generate it:

(defn n-fib [n]
  (defn gen [i a b]
    (if (= i 0)
        ()
        (cons (+ a b) (gen (dec i) b (+ a b)))))
  (gen n 0 1))
3
  • 1
    You could use a vector representation rather than a list. The the last solution with a generator, you should be able to use a stream-cons to avoid using the stack. A stream is a pair where the first term is a value, and the second term is a delayed expression for calculating the rest of the values. Commented Jul 8, 2013 at 14:05
  • 1
    In Clojure, def / defn should not be used inside a function; in particular, if you do that, global Vars are created, not locals. To introduce locals, use let or letfn. Commented Jul 8, 2013 at 17:23
  • 2
    this is one of the first examples in the famous SICP book in infinite streams (= stream lazy-seq) section. Strongly recommended reading for grasping basic lazy seq concepts mitpress.mit.edu/sicp/full-text/book/… Commented Jul 8, 2013 at 20:21

2 Answers 2

7

You might want to look at http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci

The equivalent to your lazy Haskell solution is this

 (def fib (lazy-cat [1 1] (map + (rest fib) fib)))
Sign up to request clarification or add additional context in comments.

1 Comment

0

This one doesn't generate the whole sequence, but it is good at finding the nth fibonacci number with an iterative algorithm. I'm only just learning clojure, so I'd be interested what people think about this approach and if there's something wrong with it. It's not pretty, and it's not clever, but it does seem to work.

(defn fib [n]
  (if (< n 2)
    n
    (loop [i 1
           lst 0
           nxt 1]
      (if (>= i n)
        nxt
        (recur (inc i) nxt (+' lst nxt))))))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.