What type is a function?
let's try some calls to the "type" function :
user=> (type 10)
java.lang.Integer
user=> (type 10.0)
java.lang.Double
user=> (type :keyword?)
clojure.lang.Keyword
and now with an anonymous function :
user=> (type #(str "wonder" "what" "this" "is"))
user$eval7$fn__8
A) what does this mean "user$eval7$fn__8" ? B) and what type is a function ?
the source for "type" is :
user=> (source type)
(defn type
"Returns the :type metadata of x, or its Class if none"
{:added "1.0"}
[x]
(or (:type (meta x)) (class x)))
nil
so a function needs to have a specific part of meta data or be a class
checking the meta of an anonymous function yields nada :
user=> (meta #(str "wonder" "what" "this" "is"))
nil
trying a different approach :
user=> (defn woot [] (str "wonder" "what" "this" "is"))
#'user/woot
user=> (meta woot)
{:ns #<Namespace user>, :name woot}
C) seems there is some meta but i figured this is the meta of the symbol "woot", right ?
what about the second half of the "or" :
user=> (class #(str "wonder" "what" "this" "is"))
user$eval31$fn__32
user=> (class woot)
user$woot
what are these : "user$eval31$fn__32" and "user$woot" and where do they come from ?
checking out the "class" function yields:
user=> (source class)
(defn ^Class class
"Returns the Class of x"
{:added "1.0"}
[^Object x] (if (nil? x) x (. x (getClass))))
nil
and further investigating yields :
开发者_如何学运维user=> (.getClass #(str "wonder" "what" "this" "is"))
user$eval38$fn__39
user=> (.getClass woot)
user$woot
i don't get it. D) is this a hashcode : eval38$fn__39 ? E) is this a symbol : woot ?
F) why doesn't a function have a type ? isn't it supposed to be an IFn or something ?
A function is of type clojure.lang.IFn
, which is a Java interface.
Every Clojure function is compiled into a Java class which implements clojure.lang.IFn
. The name user$eval7$fn__8
is the "binary class name" of that class, i.e., its internal name in the JVM.
Clojure is built on the JVM.
The JVM doesn't support first-class functions, or lambdas, out of the box. Every Clojure function, once it is compiled, becomes its own anonymous class from the perspective of the JVM. Each function is, technically, it's own type.
The class it becomes implements IFn, but when you retrieve it's type, it gives you the name of the anonymous class which is different every time.
Here's the description in the API docs
Returns the :type metadata of x, or its Class if none
What you are seeing ("user$eval7$fn__8") is the name of the internally generated inner class created by Clojure to implement the anonymous function you have defined.
As you may have noticed, Clojure doesn't follow standard Java class naming conventions :-)
Note that the class implements the interface clojure.lang.IFn - this applies to all Clojure functions.
I am a clojure novice but i am going to be bold. First we have two different meaning for "type" of a function, one, the java interfaces and classes of clojure internals and otoh the type of the function as a programming concept. Taking the second approach the type of a function would be the type of its return value (or its params types and return value type):
1) i guess all functions implements the IFn interface, whatever their current class
2) the class name automatic generated by clojure diffs if the function is anonymous or named, but it seems in both cases are inner classes (tipically theirs names are separated by $ and go from outer classes to inner ones)
3) the type of the returned value can be in the :tag key of function metadata if you annotate it in function definition. F.e. the function class you expose have Class as its returned type cause in its def there is a ^Class before the name.
I am assuming you are familiar with java (or a similar oop lang), sorry if not
精彩评论