Hello,

When interacting with java code, and maybe in other pure clojure situations
as well (but I have not encountered the case myself), I was faced with
writing boiler plate code to check whether the return values of a chain of
calls to successive instance members were null before continuing ...

something like writing :
(let [person (get-the-person)]
  (when-not (nil? person)
    (let [address (.getAddress person)]
      (when-not (nil? address)
         (let [street (.getStreet address)]
            (when-not (nil? street)
               (do-something-finally-with-street street)))))

I know it's somewhat encouraging the violation of the law of Demeter, but
still, there are a lot of libraries that force you to write this, so I wrote
a version of -> that short-circuits the computation if one of the
intermediate threaded value is nil.

I named it ?-> because some other OO languages already use the ? as a
"maybe" reminder :
person?.address?.street?.call-finally-something-on-street

With this macro, the above code can be written as :

(?-> (get-the-person ...) .address .street do-something-finally-with-street)

Here is the macro. If you think it could be an interesting addition to
clojure-contrib, feel free to add it (maybe re-explain me how to trigger the
contribution stuff) :

(defmacro ?->
  "Same as clojure.core/-> but returns nil as soon as the threaded value
   is nil itself (thus short-circuiting any pending computation).
   Examples :
   (?-> \"foo\" .toUpperCase (.substring 1)) returns \"OO\"
   (?-> nil .toUpperCase (.substring 1)) returns nil
   "
  ([x form]
    (let [list-form (if (seq? form) form (list form))]
      `(let [i# ~x]
         (when-not (nil? i#)
           (~(first list-form) i# ~@(rest list-form))))))
  ([x form & more]
    `(?-> (?-> ~x ~form) ~...@more)))

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