Error when trying to get the first element of a sequence by index in a function call
I got a problem when I was doing a task from 4clojure.com . Here's a description of the task:
Write a function that returns the last item in a sequence.
I solved it using the following code:
#(first (reverse %))
When I wanted to change the function first
to the number of indices. So:
#(0 (reverse %))
I got the error:
java.lang.ClassCastException: java.lang.Long cannot be thrown clojure.lang.IFn
My question is:
Why am I getting this error? I can't get it because, for example, it
([1 2 3 4] 0)
works fine and returns the first element of the sequence, so why can't I use the array index in the function?
EDIT1:
Even the following code doesn't work, and I suppose it APersistentVector
does here.
#((reverse %) 0)
EDIT2:
I managed to get it to work by converting the list returned by the function reverse
to a vector. Thanks @Josh
(#((vec (reverse %)) 0)[1 2 3])
source to share
If you look at the code for APersistentVector , you will see:
public abstract class APersistentVector extends AFn ...
AFn
implements IFn
which extends java interfaces Callable
and Runnable
, which means the constant vector clojure can be called as a function, with the argument being used as an index to retrieve. You can see it here :
public Object invoke(Object arg1) {
if(Util.isInteger(arg1))
return nth(((Number) arg1).intValue());
throw new IllegalArgumentException("Key must be integer");
}
The same is true for cards and sets; they can all be called as functions:
({:a 1 :b 2} :b) ;; 2
(#{:a :b} :a) ;; :a
([1 2 3 4] 0) ;; 1
However a Long
(your number zero) does not implement IFn
:
(ancestors (class 42))
=>
#{java.lang.Comparable
java.lang.Number
java.lang.Object
java.io.Serializable}
Hence, it cannot be called as a function.
source to share