Что нового в Clojure 1.3?
Сегодня ночью была выпущена новая версия языка Clojure — 1.3. Что нового в этой версии? Давайте рассмотрим основные изменения сделанные в этой версии (детальный список изменений можно найти в соответствующей ветке репозитория).
Расширенная поддержка примитивных типовВ предыдущих версиях, примитивные типы (long, double, etc.) поддерживались только для локальных арифметических операций и при объявлении полей deftype/defrecord, но не для аргументов функций и не для возвращаемых значений. Boxing выполнялся всегда, что часто приводило к ощутимым накладным расходам.
В новой версии примитивные типы поддерживаются в полной мере, что приводит к значительному увеличению производительности кода (в соответствующих тестах, в среднем в 3-5 раз). Соответственно изменилась работа с арифметическими выражениями — для примитивных типов будут использоваться стандартные операторы Java. Но при этом не будет происходит автоматического превращения в "Big*" типы при переполнении, как это происходило раньше — вместо этого будет брошено исключение. Если вам все-таки нужно автоматическая конвертация, то вы можете использовать операторы +', *', и т.д., хотя они и более медленные. Битовые операции теперь только поддерживаются для примитивных типов, и вся их поддержка для "Big*" была убрана из языка.
Для использования примитивных типов вам необходимо добавить соответствующие type hints, например:
(defn fib ^long [^long n](if (<= n 1)
1
(+ (fib (dec n)) (fib (- n 2)))))
Более подробно обо всем этом на соответствующей странице JIRA.
Улучшения defrecord и deftypeВ версии 1.3 были сделаны различные улучшения для работы с defrecord и deftype:
новый синтаксис для чтения и записи — либо с метками (#myns.MyRecord{:a 1, :b 2} — только для записей), либо позиционный (#myns.MyRecord[1 2] — для записей и типов);автоматическая генерация функций для создания типов и записей: myns/map->MyRecord (только для записей) и myns/->MyRecord (для записей и типов).
Подробнее можно прочитать вот тут.
Reflection APIВведено новое пространство имен clojure.reflect, функции которого должны обеспечить более удобную и быструю работу с классами, методами и т.д. Подробнее об этом тут.
Модульный clojure-contribНачиная с версии 1.3, больше не существует монолитного набора библиотек известного как clojure-contrib — вместо этого, были созданы отдельные проекты для каждой из библиотек, что позволяет им развиваться и выпускаться независимо друг от друга. Полный список всех старых библиотек, и соответствующих им новых, можно найти на отдельной странице.
Множественные улучшения производительностиКроме улучшений в части производительности, описанных выше, в новом релизе сделано множество изменений чтобы обеспечить более высокую скорость работы программ на Clojure:
Более быстрый доступ к переменным;Ускорение загрузки
Promises не используют блокировок (locks);
Инлайнинг nil?, битовых функций, математических операций, функций min & max с разным числом аргументов;
и многое другое...Прочее
Помимо новой функциональности описанной выше, а также различных исправлений ошибок, в новой версии реализованы новые вещи (перечислены не все):
Некоторые вспомогательные пространства имен (clojure.set, clojure.xml, clojure.zip) не загружаются при запуске;Объявления сделанные с помощью def более не являются "динамическими" по умолчанию — вы должны использовать ^:dynamic если хотите иметь возможность использования ее в binding;
Улучшенные сообщения об ошибках и исключениях;
Можно вызвать deref с указанием таймаута;
Функция comp возвращает identity если вызвана без параметров;
Возможность указания разных возвращаемых типов в объявлениях одной функции с разными количествами аргументов;
Некоторые функции перемещены в другие пространства имен;


