"Vinay D.E" <devi...@gmail.com> writes: > I am a newbie and was doing some exercises when I ran across something that > I don't understand. > I am trying to count the number of elements in an array less than 100. > > My first attempt didn't work. The counter returns 0 > > (let [a (atom 0) > i (take-while (fn[x] (swap! a inc) (< x 100)) [1 2 3 4 5])] > [@a i]) => [0 (1 2 3 4 5)]
The primary concrete problem is laziness, but fundamentally this sort of mutable-imperative algorithm doesn't play nice with Clojure's core features. The sequence returned by `take-while` is lazy, and none of the function applications required to generate that sequence actually happen until something forces evaluation of the sequence elements. So when you get the result of `[@a i]` what happens is: (1) `@a` is evaluated; nothing else has actually happened yet, so the result is still the initial value of `0`. (2) `i` is evaluated; now the sequence is forced and generated, and as a side-effect the atom is updated. Instead of depending on mutating side-effects to do these sorts of calculations, most of the Clojure standard library assumes that you'll be working with (largely) pure functions which operate primarily in terms of their parameters and return values. As an aside, you probably wanted `filter` instead of `take-while` even for what you were trying to do in the first place -- you should be able to figure out the difference from the docs. So, using pure functions, we can something as simple as: (count (filter #(< x 100) input-sequence)) HTH, -Marshall -- 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