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])

      

+3


source to share


1 answer


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.

+8


source







All Articles