Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you return from a function early in Clojure?

Tags:

return

clojure

Common Lisp has return-from; is there any sort of return in Clojure for when you want to return early from a function?

like image 406
compman Avatar asked Sep 20 '11 20:09

compman


People also ask

How do you return a function in Clojure?

Functions Returning Functions and Closures Our first function will be called adder . It will take a number, x , as its only argument and return a function. The function returned by adder will also take a single number, a , as its argument and return x + a . The returned function form adder is a closure.

How do you do if else in Clojure?

In Clojure, the condition is an expression which evaluates it to be either true or false. If the condition is true, then statement#1 will be executed, else statement#2 will be executed. The general working of this statement is that first a condition is evaluated in the 'if' statement.

Does Clojure have closures?

Clojure has closures, and closures are an excellent way to group functions (Crockford 2008) with their supporting data.


2 Answers

There isn't any explicit return statement in clojure. You could hack something together using a catch/throw combination if you want to, but since clojure is much more functional than common lisp, the chances you actually need an early return right in the middle of some nested block is much smaller than in CL. The only 'good' reason I can see for return statements is when you're dealing with mutable objects in a way that's not idiomatic in clojure.

I wouldn't go as far as saying that it's never useful, but I think in Clojure, if your algorithm needs a return statement, it's a major code smell.

like image 34
Joost Diepenmaat Avatar answered Sep 20 '22 08:09

Joost Diepenmaat


When you need to bail out of a computation early, you need a way to do that, not an argument from purists. Usually you need it when you're reducing a big collection and a certain value indicates that there's no point in further processing the collection. To that end, the ever-practical Clojure provides the reduced function.

A simple example to illustrate is that when multiplying a sequence of numbers, if you encounter a zero, you already know that the final result will be zero, so you don't need to look at the rest of the sequence. Here's how you code that with reduced:

(defn product [nums]   (reduce #(if (zero? %2)                (reduced 0.0)                (* %1 %2))           1.0           nums)) 

reduced wraps the value you give it in a sentinel data structure so that reduce knows to stop reading from the collection and simply return the reduced value right now. Hey, it's pure-functional, even!

You can see what's going on if you wrap the above if in a do with a (println %1 %2):

user=> (product [21.0 22.0 0.0 23.0 24.0 25.0 26.0]) 1.0 21.0 21.0 22.0 462.0 0.0 0.0  user=> (product [21.0 22.0 23.0 24.0 25.0 26.0]) 1.0 21.0 21.0 22.0 462.0 23.0 10626.0 24.0 255024.0 25.0 6375600.0 26.0 1.657656E8 
like image 170
Ben Kovitz Avatar answered Sep 22 '22 08:09

Ben Kovitz