You can get quite a long way with just "if-let" "and" and "or" to express the bailout logic.
Examples I find myself using all the time: ;; fallback / default values (or (maybe-make-value) (make-fallback-value) (error "this shouldn't happen!")) ;; bailout with nil return (assumes you are running operations for side effects, and nil return means failure) (and (operation1) (operation2) (operation3) :success) ;; let a value, with potential defaults (if-let [value (or passed-value (try-to-find-default-value))] ....) Apart from that, I found myself writing a few macros to allow early bailouts from computations. My favourite currently is the "and-as->" macro, which works like this: (and-as-> (some-initial-value-expression) symbol (do-something-with symbol) (some-thing-else symbol) (reduce some-fn symbol some-seq)) At each step, symbol is rebound to the result of the expression (like "as->") unless the result is nil, in which case the whole expression bails out and returns nil. So it is like a cross between "and" as "as->". On Saturday, 23 March 2013 11:19:28 UTC+8, Russell Mull wrote: > > Hi Clojurians, > > I'm relatively new to the language and am trying to get used to its > idioms. One thing I'm accustomed to doing in things like java and C# is > checking values for validity and then bailing out early if they don't make > sense. For example, without this idiom in java you might do: > > Object doSomething() { > > Integer a = someComputation(); > if(a != null) { > Integer b = anotherComputation(a, 42); > if(b != null && b.intValue() >= 0) { > return a / b; > } > else { > return null; > } > } > else { > return null; > } > } > ... which is really only desirable if you believe in the "one exit point" > school of imperative programming. It is of course much better to do this: > Object doSomething() { > Integer a = someComputation(); > if(a == null) { return null; } > > Integer b = anotherComputation(a, 42); > if(b == null || b.intValue == 0) { return null; } > > return a / b; > } > > > > ... which is much more literate. In Clojure, I have to write what is > effectively the first form: > > (let [a (some-computation)] > (if (nil? a) > nil > (let [b (another-computation a 42)] > (if (or (nil? b) (= b 0)) > nil > (/ a b))))) > > While more concise, it suffers the same readability problems as the first > java version. I can easily imagine a macro to support this idiom: > > (let-check [a (some-computation) > :check (nil? a) nil > b (another-computation a 42) > :check (or (nil? b) (< b 0)) nil] > (/ a b)) > > > Which leads me to my question: does such a construct already exist? Or > perhaps am I doing it wrong? I've googled around for this, but I'm not > exactly sure what it's called. > > Cheers, > > Russell > > -- -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.