Matthew Phillips <mattp...@gmail.com> writes:

> The only way I can think of to write it in Clojure is:
>
> (reduce
>   (fn [items op]
>     (let [items1 (if (:delete op) (drop-index (:delete op) items)
> items)]
>       (if (:insert op) (cons (:insert op) items1) items1)))
>   items ops)
>
> i.e. I'm using a cascade of conditional let's. This isn't _too_ bad in
> this case, but you can image how unreadable this could get.


To avoid a "cascade of lets" I've occasionally defined a function called
conj-if (or disj-if or assoc-if...). Like so:

    (defn conj-if [coll test x]
      (if test (conj coll x) coll))

    (fn [items op]
      (-> (conj-if (foo? op) "one")
          (conj-if (bar? op) "two")))
          (conj-if (baz? op) "three")))

That could be generalized, but I've so far never gotten into a situation
where I've felt the need to.

    (defn call-if [x test f & [args]]    ; needs a better name
      (if test (apply f x args) x))

    (fn [items op]
      (-> (call-if (foo? op) assoc "foo" 1)
          (call-if (bar? op) dissoc "bar")
          (call-if (baz? op) empty)))

On the other hand the cascading lets are really not that bad especially
if you pull any complex predicate or value-manipulation logic out into
separate functions:

    (fn [items op]
      (let [items (if (foo? op) (assoc items "foo" 1) items)
            items (if (bar? op) (dissoc items "bar")  items)
            items (if (baz? op) (empty items)         items)]
        items))

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