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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---