Что нового в 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 если вызвана без параметров;
Возможность указания разных возвращаемых типов в объявлениях одной функции с разными количествами аргументов;
Некоторые функции перемещены в другие пространства имен;
 •  0 comments  •  flag
Share on Twitter
Published on September 24, 2011 08:14
No comments have been added yet.