On Thu, Feb 3, 2011 at 3:11 AM, Petr Gladkikh <petrg...@gmail.com> wrote: > On Thu, Feb 3, 2011 at 1:31 PM, Meikel Brandmeyer <m...@kotka.de> wrote: >> Hi, >> >> On 3 Feb., 08:04, Petr Gladkikh <petrg...@gmail.com> wrote: >> >>> Should not it be empty colection instead? >>> It seems odd to me since it is inconsistent and forces to consider one >>> more case (nil or collection). >> >> It is consistent. There is a difference between () and nil. () is the >> empty list. However there is no "empty sequence." Either there is >> something or there is nothing. Why would you have to check for nil? >> You can pass nil to any of the sequence library functions without fear >> of harm. When you write such a function yourself, there is usually a >> single check in the beginning when realising the sequence. Something >> like (when-let [s (seq coll)] ...). >> >> I never encountered any problems with this. Do you have a concrete >> example where this causes trouble for you? > > I have a vector that holds some history. I conj new items to it and to > save space I'd like to retain not more than n last items. > To do that I used (take-last n history). So: [] -> (take-last n []) -> > nil -> (conj nil newItem) -> '(newItem) > > But list conj's at the beginning not at end of sequence as I would > like to. Of course I could use () from the beginning (with account for > reverse order). > But with [] I should do little more.
Depending on your "little more", you might want to wrap the queue implementation I posted a while ago with something like (defn push-max [q item max] (let [q (conj q item)] (if (> (count q) max) (pop q) q))) This will be efficient (in particular, the count function should be efficient on my queue) without any full traversals (unlike take-last). The least recent item can be viewed with peek. If you want to view the most recent item you could use my deque implementation (amortized O(1) operations at both ends, and O(1) count) which lets you peek both ends. But neither will satisfy you if you want to random access in the middle. If you want to partially traverse from only one end (either youngest or oldest items) my deque will do: it can be partially traversed from the left end efficiently with seq, so you'd add new items at that end if you wanted to partially traverse youngest items, and at the other if you wanted to partially traverse oldest items. Of course, if the max length is short it won't matter much; you can just use a vector and (vec (take-last ...)) and it won't be very inefficient, nor would using reverse on a queue or deque to traverse from the other end and last to peek the "difficult" end of a queue. -- 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