1
votes

Elementary question here.. I am a little confused.

(((fn [_ & y] y) 'blah +) 3 4)

will result in the error:

"java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn"

I was rather hoping for it to be evaluated to:

(+ 3 4) 

which equals 7.

I see that

((fn [_ & y] y) 'blah +)

evaluates to

(#<core$_PLUS_ clojure.core$_PLUS_@7cd07b83>)

which is an ArraySeq, not an IFn; so I understand the error- however I am not sure why it doesn't just evaluate to a + instead.

2

2 Answers

3
votes

& puts all excess arguments in a collection. This can be destructured to access its first element:

user> (((fn [_ & [y & _]] y) 'blah +) 3 4)
7

or, equivalently,

user> (((fn [_ & ys] (first ys)) 'blah +) 3 4)
7
1
votes

The ampersand & in function argument destruction collects all remaining arguments to a seq, even if there is only one there.

user=> ((fn [_ & y] y) 'blah +)
(#<core$_PLUS_ clojure.core$_PLUS_@205074de>)
user=> ((fn [_ y] y) 'blah +)
#<core$_PLUS_ clojure.core$_PLUS_@205074de>