On Sun, Dec 5, 2010 at 5:16 PM, Robert McIntyre <r...@mit.edu> wrote: > Your function never actually ends because even the empty list > evaluates to true :) > > rlm.dna-melting> (if (rest '()) true false) > true > > rlm.dna-melting> (if (next '()) true false) > false > > so, changing your list length function to use next will work > > rlm.dna-melting> (defn list-length [col] (if col (+ 1 (list-length > (next col))) 0)) > #'rlm.dna-melting/list-length > rlm.dna-melting> (list-length (range 5)) > 5 > > hope that helps, > --Robert McIntyre
Yeah, but user=> (list-length ()) 1 :) And the original code will still bomb on long enough lists. How about: (defn list-length [coll] (let [ll (fn [n s] (if s (recur (inc n) (next s)) n))] (ll 0 (seq coll)))) user=> (list-length ()) 0 user=> (list-length (range 5)) 5 user=> (list-length (range 10000000)) 10000000 The inner function takes a second argument that is the count-so-far. This is so that the recursion can be turned into a tail call. As you can see, no stack overflow even on a very long input. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en