Статическая типизация Clojure, часть 2


Это продолжение моего предыдущего вопроса о статическом типировании Clojure.

Я просмотрел исходный код Java для компилятора, и есть несколько мест, где он проверяет значение *warn-on-reflection*, но когда я компилирую следующий код, я получаю только ошибку во время выполнения:

(defn div-2 [^String s] (/ 2 s))

Существуют ли какие-либо обстоятельства, при которых этот код не должен выдавать предупреждение во время компиляции (это не так)? Насколько сложно было бы заставить компилятор выдать предупреждение о следующем код:

(defn get-length [^String s] (.length s))
(defn test-get-length [] (get-length 2.0))

Спасибо.

3 3

3 ответа:

Проблема в том, что компилятор не отслеживает тип def'd vars. Так что да, в вашем простом примере это было бы возможно. Но как часто вы проходите литерал? Редко, в реальной программе.

Создание типов "проточных", как это происходит в реальном статически типизированном языке, потребует значительного объема переработки. Вам придется отслеживать информацию о типе через vars, динамически восстанавливать vars, разыменования и т. д. И тогда у вас все еще есть проблема вытаскивания предметов из коллекции / последовательности, что подразумевает генерализованные типы, которые представляют собойогромную банку червей... Аннотации типов в Clojure никогда не были предназначены для обеспечения безопасности типов во время компиляции - они просто позволяют компилятору генерировать более оптимизированный код (за счет ошибки во время выполнения, если встречается неожиданный тип.)

Инструментирование компилятора с полной статической информацией о типировании возможно, но на этом этапе вы в значительной степени переписали язык, и вы будете мне пришлось принять много решений и компромиссов в том, как обрабатываются типы. Это действительно больше не будет Клоджур.

Вместо того, чтобы пытаться модифицировать компилятор, почему бы не написать отдельный инструмент, который просто сканирует файл кода Clojure и предупреждает о нарушениях типа? Вы можете разработать свою собственную нотацию типов, используя макросы, которые просто сворачиваются в обычный нетипизированный код Clojure. Но когда вы запускаете статическую проверку типов, она будет проверять типы и выводить предупреждения.

Если бы Вы были готовы к немного более сложной задаче, вы могли бы даже заставить его выполнять вывод типа, тем самым снижая бремя нотации.

Вслед за этим потоком теперь существует проект, направленный на постепенное введение текста в clojure (например, Dart и т. д.). Стоит проверить это : Typed-Clojure

Если кто-то может также дать некоторую обратную связь после реального использования...