Подтвердить что ты не робот

Какой тип функции?

попробуйте несколько вызовов функции "type":

user=> (type 10)
java.lang.Integer

user=> (type 10.0)
java.lang.Double

user=> (type :keyword?)
clojure.lang.Keyword

и теперь с анонимной функцией:

user=> (type #(str "wonder" "what" "this" "is"))
user$eval7$fn__8

A) Что это значит "user $eval7 $fn__8"? B) и какой тип является функцией?

источник для "type":

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

поэтому функция должна иметь определенную часть метаданных или быть классом

проверка мета анонимной функции дает nada:

user=> (meta #(str "wonder" "what" "this" "is"))
nil

пытается использовать другой подход:

user=> (defn woot [] (str "wonder" "what" "this" "is"))
#'user/woot
user=> (meta woot)
{:ns #<Namespace user>, :name woot}

C) кажется, что есть какая-то мета, но я понял, что это мета символа "woot", правильно?

как насчет второй половины "или":

user=> (class #(str "wonder" "what" "this" "is"))
user$eval31$fn__32

user=> (class woot)
user$woot

что это такое: "user $eval31 $fn__32" и "user $woot" и откуда они взялись?

проверка функции "class" дает:

user=> (source class)
(defn ^Class class
  "Returns the Class of x"
  {:added "1.0"}
  [^Object x] (if (nil? x) x (. x (getClass))))
nil

и дальнейшее исследование выходов:

user=> (.getClass #(str "wonder" "what" "this" "is"))
user$eval38$fn__39

user=> (.getClass woot)
user$woot

Я не понимаю. D) - это хэш-код: eval38 $fn__39? E) - это символ: woot?

F) Почему функция не имеет тип? разве это не должно быть IFn или что-то в этом роде?

4b9b3361

Ответ 1

Clojure построен на JVM.

JVM не поддерживает функции первого класса, или лямбды, из коробки. Каждая функция Clojure, после ее компиляции, становится ее собственным анонимным классом с точки зрения JVM. Каждая функция, технически, имеет собственный тип.

Класс, которым он становится, реализует IFn, но когда вы возвращаете его тип, он дает вам имя анонимного класса, который каждый раз отличается.

Ответ 2

Функция имеет тип clojure.lang.IFn, который является интерфейсом Java.

Каждая функция Clojure скомпилирована в класс Java, который реализует clojure.lang.IFn. Имя user$eval7$fn__8 - это "двоичное имя класса" этого класса, то есть его внутреннее имя в JVM.

Ответ 3

Здесь описание в API docs

Returns the :type metadata of x, or its Class if none

То, что вы видите ( "user $eval7 $fn__8" ), является именем внутреннего внутреннего класса, созданного Clojure, для реализации анонимной функции, которую вы определили.

Как вы могли заметить, Clojure не соответствует стандартным соглашениям об именах классов Java: -)

Обратите внимание, что класс реализует интерфейс clojure.lang.IFn - это относится ко всем функциям Clojure.

Ответ 4

Я новичок clojure, но я буду смелым. Сначала у нас есть два разных значения для "типа" функции: одна, интерфейсы java и классы внутренних элементов clojure и otoh тип функции как концепция программирования. Взяв второй подход, тип функции будет типом возвращаемого значения (или его типов параметров и типа возвращаемого значения):

1) Я предполагаю, что все функции реализуют интерфейс IFn, независимо от их текущего класса

2) имя класса автоматически генерируется с помощью clojure diffs, если функция анонимна или именована, но в обоих случаях кажется, что это внутренние классы (типично их имена разделены на $и переходят из внешних классов во внутренние)

3) тип возвращаемого значения может быть в ключе тега функции метаданных функции, если вы аннотируете его в определении функции. F.E. класс функции, который вы выставляете, имеет класс как возвращаемый тип, потому что в его определении есть класс ^ перед именем.

Я предполагаю, что вы знакомы с java (или аналогичным oop lang), извините, если не