самая короткая статическая типизация Clojure

#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)))))