Hi!

For a blogging software, I want to support nested comments. Rendered as nested <div>s, to not have to define per level CSS classes.

My data-gathering function calls itself to deliver a nested structure. On IRC I've been told that, since it happens via map, there is not necessarily a problem with an ever growing stack, but that it depends on how I use the result. Thing is, I have no clue what happens regarding the interaction of the model and the view code.

Plus I'm wondering if I'm perhaps doing something silly, in having both model and view code recurse, or if that's just the nature of dealing with the nested structure.

I considered making the model fn use loop/recur, but thinking about how to do an accumulator gives me nothing but headaches.

So under which circumstances is such a naive recursion inside map, thus making it somehow lazy, a fine solution, and when would it break down?

Can you think of significant improvements to the following code?


From models.clj;
comments have a parent property, with the ID of the article they refer to for first level comments, comment ID's for all following levels. ds/key-id is an appengine-magic function delivering those IDs:
---

(defn comments
  "Retrieve all comments for the ID, then recurse to retrieve comments
   for the IDs of the just retrieved comments. The whole will be
   wrapped in ()."
  [id]
  (let [cs (comments-for-parent id)]
    (when (not (nil? cs))
      (map #(cons % (comments (ds/key-id %))) cs))))

(defn tree
  "Tree consisting of an Article and 0 to n Comments, via article-id.
   nil if there is no Article."
  [id]
  (let [a (article id)
        cs (comments id)]
    (if (nil? a)
      nil
      (into a {:comments cs}))))

---

From views.clj, using Hiccup:
---

(defhtml comment-rendition
  [{:keys [index parent author link body created updated
           time-stamps css-class]} children]
  [:div.comment
   time-stamps
   [:div {:class (str "comment-body " css-class)}
    [:p.meta
     [:span.index [:a {:href (str "/" index)} (str "#" index " ")]]
     [:span.author [:a {:href link} author] ":"]]
    body]
   children])

(defn comments-rendition-recur
  "Recurse for nested Comments."
  [comments]
  (map #(comment-rendition (into (first %)
                                 (derive-time-stamps (first %)))
                           (let [children (rest %)]
                             (when-not (empty? children)
                               (comments-rendition-recur children)))) comments))

(defhtml comments-rendition
  [comments]
  [:div#comments
   [:h3 "Comments"]
   (comments-rendition-recur comments)])

(defhtml tree-rendition
  [{:keys [comments] :as all}]
  (article-rendition (into all
                           (derive-time-stamps all)))
  (comments-rendition comments))


Thanks!

--
Thorsten Wilms

thorwil's design for free software:
http://thorwil.wordpress.com/

--
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

Reply via email to