3

If I have a function that evaluates to a function

(defn func1 [c1 c2]
  (fn [x1 x2]
    ...do some stuff with c1 c2 x1))

that I use elsewhere in a map or reduce, is it better to use inline

(defn func2 [x y z]
  (reduce (func1 x y) z (range 20)))

or to let bind it first

(defn func2 [x y z]
  (let [ffunc (func1 x y)]
    (reduce ffunc z (range 20))))

In the first case I would be worried that a new function over x and y is generated each step through the reduce.

1 Answer 1

3

The evaluation of the function call (func1 x y) is done once in each case.

The rule for evaluating a function call in Clojure consists of evaluating all the expressions that are provided as its arguments and then invoking the function with those values.

If you define the following higher order function:

(defn plus []
  (println "calling plus")
  +)

And then call reduce in the following way:

(reduce (plus) [0 1 2 3])

A single calling plus is printed, showing the function plus is invoked only once.

The same thing happens when using the let form:

(let [f (plus)]
  (reduce f [0 1 2 3]))

Hope it helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah that's exactly what I was looking for. Never thought to test it with a side-effect. Thanks.
Note also that instantiating functions is generally cheap anyway, so even if multiple functions were allocated it wouldn't be a big deal. Obviously you can construct functions which are expensive to build, but it's not like you're having to recompile the function each time (I mention this because newcomers to closures often thing they are compiled each time they are constructed).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.