Можем ли мы использовать макросы для статической диспетчеризации возвращаемого типа в Clojure?

Теперь мы знаем, что отправка по протоколам Clojure, static">строго говоря, является динамическим.

Здесь мы видим фантастический пример компиляции. диспетчеризация времени с помощью макроса:

(defmacro case+
  "Same as case, but evaluates dispatch values, needed for referring to
   class and def'ed constants as well as java.util.Enum instances."
  [value & clauses]
  (let [clauses (partition 2 2 nil clauses)
        default (when (-> clauses last count (== 1))
                  (last clauses))
        clauses (if default (drop-last clauses) clauses)
        eval-dispatch (fn [d]
                        (if (list? d)
                          (map eval d)
                          (eval d)))]
    `(case ~value
       ~@(concat (->> clauses
                   (map #(-> % first eval-dispatch (list (second %))))
                   (mapcat identity))
           default))))

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

Мой вопрос: Можем ли мы использовать макросы для статической диспетчеризации возвращаемого типа в Clojure?


person hawkeye    schedule 08.07.2016    source источник
comment
Какое отношение этот макрос case* имеет к вопросу?   -  person amalloy    schedule 09.07.2016
comment
Он создает конструкцию во время компиляции. Это диспетчер Clojure, не работающий во время выполнения.   -  person hawkeye    schedule 09.07.2016


Ответы (1)


Теоретически вы можете использовать макросы для создания Clojure DSL с семантикой типов Haskell, так что да, строго говоря, это возможно.

Однако с практической точки зрения диспетчеризация возвращаемого типа в типе компиляции означает предоставление этой информации и распространение ее во время компиляции. В Clojure нет встроенного «типа возврата» (все функции принимают переменное количество аргументов типа Object и возвращают объект), поэтому вам, вероятно, придется развернуть собственную систему типов и потребовать, чтобы большие части ваших программ участвовать в нем (как Type Clojure), с ограничением, что анализ типов должен быть доступен, как только вы используете свой макрос.

Случай case+ (каламбур) отличается, потому что он не требует системы типов, это в основном вопрос порядка оценки.

person Valentin Waeselynck    schedule 11.07.2016