Does identity return an "argument"?
It depends on your argument.
- If this is an expressed expression in the form of a function call, then not always.
- If this is what the function body sees on the stack upon entry, then yes, it is.
The anomaly is due to the way Clojure functions are called.
- Clojure functions are objects that conform to the
IFn interface . - The call to the Clojure function translates into one of the many
invoke methods - overloaded for arity - the functional object. - All
invoke methods have Object parameters.
The result of all this is that each call to the Clojure function translates each of its arguments into some kind of Object - an identification operation, with the exception of primitives that are wrapped in the corresponding Java class: long to long , etc.
Thus, even the identity function, essentially (defn identity [x] x) , does not return a primitive argument. This cannot be, because he never sees it.
For example, consider the expression
(inc 3)
The number 3 is certainly long . What type (inc 3) ? Let me ask Clojure:
(type (inc 3)) => java.lang.Long
... a boxed long object.
Take, we are sure that 3 is a primitive long ?:
(type 3) => java.lang.Long
Aaaaaaagh! He is also in the box!
Not necessarily ! You cannot say, because by the time the type body sees 3 , it is put into a box, regardless of whether it was for the reader / compiler. Clojure documentation is silent. He simply says that numeric literals are usually represented as Java.
So, in general, this is an evaluation mechanism, not a specific function (for example, identity ), which is responsible for the primitive arguments of the box . This is auto boxing.
As your example shows, primitives are stored as such, without a box, at least in let forms:
(let [x 1.0] (identical? xx)) ;=> false (let [x (identity 1.0)] (identical? xx)) ;=> true
The fact that identical? able to distinguish between two boxes 1.0 , shows that it is held as a primitive double . (I used a regular double to show that the behavior has nothing to do with the special Double/NaN value).
Now try putting the number in var:
(def x 1.0) (identical? xx) ;=> true (let [x (identity x)] (identical? xx)) ;=> true
He is in the box.
While we are here, auto-boxing is idempotent:
(identical? x (identity x)) ;=> true
The above does not add much to the fact that Alan Thompson and Joshβs answers and comments by Alan Mallow and Lee. I just felt that they hooked and played the fish without planting it.