I am trying to figure out the equivalent of this Java in Clojure:
public int compute(int x) {
if (x < 0) return 0;
// continue do some computing
return result;
}
Is there idiomatic Clojure that "break" processing within a function and return a result?
One of the main guiding principals when programming with Clojure is that everything "returns" a value, though it is usually expressed as "everything evaluates to something". When calling a function the result of the function is the result of the last expression in the function.
user> (defn foo [] 1 2 3 4)
#'user/foo
user> (foo)
4
There are several forms for expressing the idea of "stopping early":
user> (defn compute [x] (cond (< x 0) 0 :default (* x 42)))
#'user/compute
user> (compute 1)
42
or
user> (defn compute [x] (if-let [y (< x 0)] (* 8 y) (* 4 x)))
#'user/compute
user> (compute 1)
4
or a simple if expression. The important concept being that everything results in a new value. This has spawned many buzwords in the clojure community including "value oriented programming"
No. There is no short-circuit return statement (or break or goto ... ). Return is implicit.
A near equivalent in Clojure to your example is
(defn test [x]
(if (< x 0)
0
(let [result (comment compute result)]
result)))
But you would probably return result without naming it:
(defn test [x]
(if (< x 0)
0
(comment compute result)))
These run, but the comment always evaluates to nil.
By the way, the if construct with two expressions (rather than the full three) returns nil if the test fails.
(if (< 3 0) 0) ; nil
So there is always something to return.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With