#clojure #static-typing
#clojure #статическая типизация
Вопрос:
каков буквальный, самый простой и кратчайший способ проверки типа функции clojure. Обычная форма ann довольно короткая:
(ann bar [Number -> Number])
(defn bar [b]
( 2 (foo b)))
Но можем ли мы (с помощью макроса или чего-то еще) сделать его меньше, например:
(defn bar [b : Number -> Number]
( 2 (foo b)))
Спасибо за ваш совет!
Комментарии:
1. Возможно, вы захотите пересмотреть, действительно ли «кратчайший, простейший» — это та метрика, которую вы хотите: IMO, это никогда не подходящая метрика для чего-либо. Чего вы хотите от своей системы статической типизации? Если в одной системе отсутствует функция, но она короче, чем у альтернативы, в которой она есть, какую бы вы выбрали?
2. Возможно, я упускаю суть вопроса. Вы спрашиваете, какой синтаксис предпочли бы Clojurists, если это что-то (например, вы проводите опрос популярности для чего-то, над чем вы работаете)? Или вы спрашиваете, какие библиотеки и т.д. вы можете использовать для получения статических проверок типов, как вы предоставили примеры для?
3. Я понимаю, что вы хотите проверить тип, но, вообще говоря, это не идиоматический Clojure. Я предлагаю рассмотреть спецификацию, если это решит вашу проблему. clojure.org/guides/spec и обоснование clojure.org/about/spec
Ответ №1:
Я думаю, что Plumatic Schema является лучшей. Смотрите также этот пост в блоге.
Вот пример:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require [schema.core :as s]))
(s/defn add2 :- s/Num ; "superclass" for any number
[a :- s/Int ; must be an integer type
b :- Double] ; Must be a java.lang.Double
( a b))
(dotest
(throws? (add2 1 2))
(throws? (add2 1.0 2))
(is= 3.0 (add2 1 2.0)))
У меня также есть несколько предопределенных «типов» в дополнение к основным. Например, tupelo.schema/Keymap
это любая карта с ключевыми словами. Pair
является ли любой вектор или последовательность длиной = 2 и т.д.
Обновить
Пожалуйста, также посмотрите мой проект шаблона Clojure. В частности, файл test/clj/_bootstrap.clj
существует с единственной целью включить проверку типа Plumatic Schema при вводе lein test
(по умолчанию они отключены, поэтому производство не требует затрат).
Ответ №2:
Строго говоря, это проверка спецификации, а не статическая типизация, но вы можете захотеть проверить Guardrails (ответвление Ghostwheel, которое не поддерживается), целью которого является решение некоторых проблем, связанных со статической типизацией, и многое другое:
(>defn ranged-rand
[start end]
[int? int? | #(< start end)
=> int? | #(>= % start) #(< % end)]
( start (long (rand (- end start)))))