guides - clojure starting
¿Qué tipo es una función? (4)
Aquí está la descripción en los documentos API
Returns the :type metadata of x, or its Class if none
Lo que está viendo ("usuario $ eval7 $ fn__8") es el nombre de la clase interna generada internamente creada por Clojure para implementar la función anónima que ha definido.
Como habrá notado, Clojure no sigue las convenciones estándar de nomenclatura de clases de Java :-)
Tenga en cuenta que la clase implementa la interfaz clojure.lang.IFn; esto se aplica a todas las funciones de Clojure.
Probemos algunas llamadas a la función "tipo":
user=> (type 10)
java.lang.Integer
user=> (type 10.0)
java.lang.Double
user=> (type :keyword?)
clojure.lang.Keyword
Y ahora con una función anónima:
user=> (type #(str "wonder" "what" "this" "is"))
user$eval7$fn__8
A) ¿Qué significa esto "usuario $ eval7 $ fn__8"? B) ¿Y qué tipo es una función?
la fuente de "tipo" es:
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
por lo que una función debe tener una parte específica de metadatos o ser una clase
Comprobando el meta de una función anónima se obtiene nada:
user=> (meta #(str "wonder" "what" "this" "is"))
nil
intentando un enfoque diferente:
user=> (defn woot [] (str "wonder" "what" "this" "is"))
#''user/woot
user=> (meta woot)
{:ns #<Namespace user>, :name woot}
C) parece que hay algún meta, pero pensé que este es el meta del símbolo "woot", ¿verdad?
¿qué pasa con la segunda mitad de la "o":
user=> (class #(str "wonder" "what" "this" "is"))
user$eval31$fn__32
user=> (class woot)
user$woot
¿Qué son estos: "user $ eval31 $ fn__32" y "user $ woot" y de dónde vienen?
Verificando los rendimientos de la función "clase":
user=> (source class)
(defn ^Class class
"Returns the Class of x"
{:added "1.0"}
[^Object x] (if (nil? x) x (. x (getClass))))
nil
y además investigando los rendimientos:
user=> (.getClass #(str "wonder" "what" "this" "is"))
user$eval38$fn__39
user=> (.getClass woot)
user$woot
no lo entiendo D) ¿ es este un código de hash: eval38 $ fn__39? E) ¿ Es este un símbolo: woot?
F) ¿Por qué una función no tiene un tipo? ¿No se supone que es un IFN o algo así?
Clojure está construido en la JVM.
La JVM no admite funciones de primera clase, o lambdas, listas para usar. Cada función de Clojure, una vez compilada, se convierte en su propia clase anónima desde la perspectiva de la JVM. Cada función es, técnicamente, su propio tipo.
La clase en la que se convierte implementa IFn, pero cuando recuperas su tipo, te da el nombre de la clase anónima que es diferente cada vez.
Soy un novato de clojure pero voy a ser audaz. Primero, tenemos dos significados diferentes para el "tipo" de una función, una, las interfaces java y las clases de internos de clojure y el tipo de la función como un concepto de programación. Tomando el segundo enfoque, el tipo de una función sería el tipo de su valor de retorno (o sus tipos de parámetros y el tipo de valor de retorno):
1) Supongo que todas las funciones implementan la interfaz IFn , sea cual sea su clase actual
2) el nombre de clase automático generado por clojure diffs si la función es anónima o tiene nombre, pero parece que en ambos casos son clases internas (típicamente, sus nombres están separados por $ y van de clases externas a clases internas)
3) el tipo del valor devuelto puede estar en: la clave de la etiqueta de metadatos de la función si lo anota en la definición de la función. Si la clase de función que expone tiene Clase como su tipo de causa devuelta en su definición, hay una Clase ^ antes del nombre.
Supongo que está familiarizado con java (o un similar oop lang), lo siento si no
Una función es de tipo clojure.lang.IFn
, que es una interfaz Java.
Cada función de Clojure se compila en una clase de Java que implementa clojure.lang.IFn
. El nombre de user$eval7$fn__8
es el "nombre de clase binario" de esa clase, es decir, su nombre interno en la JVM.