deltanovember
deltanovember

Reputation: 44051

In Clojure, is it possible to define an anonymous function within an anonymous function?

For example, solving the following problem

http://projecteuler.net/problem=5

I came up with the following solution

(defn div [n] (= 0 (reduce + (map #(mod n %) (range 1 21)))))
(take 1 (filter #(= true (div %)) (range 20 1e11 20)))

Suppose for some golfing fun I wish to merge the first line as an anonymous function into the second line. Does the language support this?

Upvotes: 7

Views: 1096

Answers (2)

viebel
viebel

Reputation: 20670

You could rewrite your solution in a much simpler and more efficient way (x2 faster!)

(defn div [n] (every? #(= 0 (mod n %)) (range 1 21)))
(take 1 (filter div (range 20 1e11 20)))

The reason it is more efficient is because every? wouldn't traverse the whole list but rather stop when one of the element of the list is false.

Upvotes: 0

liwp
liwp

Reputation: 6926

Yes it does, but you cannot nest the #() reader-macro forms, you have to use the (fn) form.

For example:

(#(#(+ %1 %2) 1) 2)

does not work, because there's no way to refer to the arguments of the outer anonymous functions. This is read as the outer function taking two arguments and the inner function taking zero arguments.

But you can write the same thing with (fn...)s:

user=> (((fn [x] (fn [y] (+ x y))) 1) 2)
3

You can also use the #() form for one of the two anonymous functions, e.g:

user=> (#((fn [x] (+ x %)) 1) 2)
3

So you can inline your div function like this (notice that we had to change the #() form passed to map to a (fn) form):

#(= true (= 0 (reduce + (map (fn [x] (mod % x)) (range 1 21)))))

Upvotes: 18

Related Questions