Anonymous function consuming another anonymous function - clojure koan

clojure

Solution

look at your expression in the first function:

(b a)

since `b` is first, `b` has to be a function. In your second example, you're trying to pass 5 to `b`, but 5 is not a function. With descriptive names you can see that you're trying to use 5 as a function:

((fn [argument function] (argument function)) ;; problem!!
 5 
 (fn [n] (* n n)))

Remember the evaluation rules for lisps: given this s-expression:

(f x y z)

evaluate f, x, y, and z, and apply f as a function to x, y, and z.

see answer to 1 -- '5' is not a function. Use descriptive names, and easily spot the problem:

((fn [function] (5 function)) ;; problem!!
 (fn [n] (* n n)))

Change to:

   ((fn [a] (a 5))  ;; 'a' and '5' flipped
    (fn [n] (* n n)))

to get this to run.

this isn't a problem: `a` is 5, `b` is a function in `(b a)`. With descriptive names it makes more sense:

((fn [argument function] (function argument)) 
 5
 (fn [n] (* n n)))

Problem

I am working on the clojure koans and one of the questions in the functions needs further explanation for me to “get it” and have an aha moment. I am able to write the function that satisfies the question. But I don't fully understand why all the bits work. ``` Clojure> (= 25 ((fn [a b] (b a)) 5 (fn [n] (* n n)))) true ``` Question 1. I do not understand why this throws an error: ``` Clojure> (= 25 ((fn [b a] (b a)) 5 (fn [n] (* n n)))) java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn ``` So the only change in the above is switching the order of b and a. In my brain I read “a function that takes an a and b” or a “b and an a” but how they are used is up to the subsequent statement in the parens. Why does the order matter at this point? Questions 2. ``` Clojure> (= 25 ((fn [a] (5 a)) (fn [n] (* n n)))) java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn ``` Why when I substitute out the value of b for the int it represents do I get an error? Quentions 3. ``` ((fn [a b] (b a)) 5 (fn [n] (* n n)))) ``` Why does this not throw an error (b a) b in this instance is 5 which is a symbol. The first item in brackets is expected to be a function or a special form unless it is a list?

Original source