2010-11-15 2 views
23

Я знаю, что это может звучать как богохульство поклонникам Лиспа (и другим любителям динамических языков), но насколько сложно было бы улучшить компилятор Clojure для поддержки статической (компиляции) проверки типов?Clojure static typing

Отключение аргументов за и против статического и динамического ввода, возможно ли это (не «это целесообразно»)?

Я думал, что добавление нового макроса читателя для принудительного использования типа времени компиляции (расширенная версия макроса # ^) и добавление информации о типе в таблицу символов позволит компилятору отмечать места, где были переменные неправильно. Например, в следующем коде, я ожидал бы ошибку во время компиляции (# * является «время компиляции» типа макро):

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

#^Макрос может быть даже повторно с глобальным переменным (*compile-time-type-checking*), чтобы заставить компилятор выполнить проверки.

Любые мысли о выполнимости?

+0

(definline t [] (list '.charAt "hello" (nth [1 "a" 2: c 0] (rand-int 4)))) – Pepijn

+3

+1 Мне очень нравится получать некоторую дополнительную проверку статического типа в clojure a la racket http: //docs.racket-lang.org/ts-guide/begin.html – jneira

+0

Некоторые распространенные компиляторы Lisp, такие как SBCL, обнаруживают некоторые ошибки статического типа, как этот. –

ответ

8

Это, безусловно, возможно. Компилятор уже выполняет некоторую проверку статического типа вокруг примитивных типов аргументов в ветке разработки 1.3.

+0

Теперь мне просто нужно узнать, как работает компилятор Clojure :-) – Ralph

+0

Теперь его возможно, кому-то просто нужно потратить время на его реализацию, но большинство людей на самом деле не волнует. (Нам нужно будет использовать систему типов Java и, что не очень хорошо, в первую очередь) – nickik

+0

@nickik: Да, но, как вы хорошо знаете, в мире есть два типа программистов: те, кто любит динамическую типизацию и тех, кто ненавидят Это. Если бы у Clojure была факультативная статическая типизация, многие из «динамических ненавистников» могли бы побудить ее попробовать. – Ralph

0

Поскольку одна форма считывается и оценивается в то время, когда вы не можете иметь прямые ссылки, делающие это несколько ограниченным.

+2

Clojure поддерживает прямые ссылки w/declare. – dnolen

+0

Clojure поддерживает прямые ссылки для «переменных», которые не помогают при проверке статического типа. Вы не можете статически проверять тип, о котором вы еще не знаете (кроме имени, вы ничего не знаете о структуре данных). Вот почему многие статически типизированные языки имеют двухпроходный компилятор. Сначала создайте таблицу символов, а затем проверьте ее. Итак, что сказал Стюарт, правильно для типов, которые уже определены (примитивы, STD lib и т. Д., Включая любые классы, которые вы определили до этого момента в вашей программе), но это не общее решение. – Bryan

+0

На 'declare', могут ли быть подсказки типов? – Ralph

10

Это определенно возможно. Однако я не думаю, что Clojure когда-либо получит какую-либо форму слабой статической типизации - преимуществ слишком мало.

Rich Хики имеют, однако неоднократно выражали его как для сильной, необязательной и выразительной типизации функции языка Qi, http://www.lambdassociates.org/qilisp.htm

alt text

+1

Спасибо Дэвид - есть ли у вас какие-либо ссылки для Богатых, выражающих это? – hawkeye

0

DECLARE может иметь намеки типа, поэтому можно объявить var, что «есть» тип, который еще не определен, но содержит данные о структуре, но это было бы действительно неуклюже, и вам нужно было бы сделать это до того, как любой путь кода, который мог бы выполнить, до того, как будет определен тип , В принципе, вы бы хотели определить все свои пользовательские типы спереди, а затем использовать их как обычно. Я думаю, что это делает библиотеку несколько хакерской.

Я не хотел предлагать ранее, что это невозможно, только для пользовательских типов это намного сложнее, чем для заранее определенных типов. Преимущество этого и затрат - это то, что следует серьезно рассмотреть. Но я призываю всех, кто заинтересован попробовать и посмотреть, смогут ли они заставить его работать!

+0

Одна из замечательных вещей о Clojure (и других Lisps) - это макросистема. Я согласен, что добавление метаданных в 'declare' неудобно, но с новым макросом (например:' declare-typed'), добавление метаданных может быть очень простым. Аналогично для 'def'. – Ralph

+0

Поскольку dnolen указал на другую ветку комментариев, вам не нужно использовать алгоритм проверки типа двух проходов. Вот почему я использовал слово «много» и не все при описании статически типизированных языков. – Bryan

7

Да! Похоже, что идет проект, core.typed, чтобы сделать факультативный статический тип проверки реальностью. См Github project и его documentation

Эта работа grew out of an undergraduate honours dissertation (PDF) Амвросий Боннер-сержант, и связан с системой Typed Racket.

+0

Я действительно посмотрел на это несколько недель назад. Надеюсь, он полностью созреет. – Ralph

0

Старый вопрос, но два важных момента: я не думаю, что Clojure поддерживает макросы читателей, только обычные макросы lisp. И теперь у нас есть опция core.typed для ввода в Clojure.

+0

Clojure поддерживает макросы считывателя, а не ** пользовательские ** - определенные макросы чтения. – Ralph