1 марта был выпущен релиз clojure 1.5. Полный список изменений здесь https://github.com/clojure/clojure/blob/master/changes.md
Теперь для версии clojure 1.5 требуется Java 7 (используется класс java.util.concurrent.ForkJoinPool). Новая версия Java необходима для работы с новым добавленным неймспейсом clojure.core.reducers
Новая библиотека core.reducers призвана увеличить скорость обработки коллекций. Основная оптимизация заключается в том, что последовательность действий над коллекцией (например (filter #() (map #() seq))) не создает промежуточную коллекцию и действия могут выполняться параллельно(при этом код остаётся без изменений)
Для агентов появилась возможность задать собственный пул тредов для выполнения модифицирующих операций над агентами(с помощью send, send-of, send-via)
Например можно выполнять операции над агентами в один поток(по умолчанию число потоков равно числу ядер + 2)
Для кастомизации функции send используется set-agent-send-executor! для send-off используется set-agent-send-off-executor!. Если нужно выполнить действие над агентом с произвольным исполнителем, можно использовать send-via. В общем случае функцию send следует использовать когда операция занимает фиксированное количество времени, а send-off когда операция может быть заблокирована по I/O или другому внешнему ресурсу.
Начиная с версии 1.5 функции-конструкторы (hash-map, array-map) принимают дублирующие значения ключей и не выкидывают исключения
в версии 1.4
К макросам -> ->> добавилось несколько новых макросов cond-> и cond->> для выполнения последовательности действий с условиями, а также есть возможность задать именнованную область с помощью as->
Новая версия gen-class позволяет обращаться к protected final методам родительского класса через :exposes-methods
К мета данным (функция meta) добавлен атрибут :column, указывающий номер колонки в исходном файле. До версии 1.5 был указан только номер строки :line
Теперь для версии clojure 1.5 требуется Java 7 (используется класс java.util.concurrent.ForkJoinPool). Новая версия Java необходима для работы с новым добавленным неймспейсом clojure.core.reducers
Новая библиотека core.reducers призвана увеличить скорость обработки коллекций. Основная оптимизация заключается в том, что последовательность действий над коллекцией (например (filter #() (map #() seq))) не создает промежуточную коллекцию и действия могут выполняться параллельно(при этом код остаётся без изменений)
clojure-1-5.core=> (require ['clojure.core.reducers :as 'r]) nil clojure-1-5.core=> (def numbers (into [] (range 99999))) #'clojure-1-5.core/numbers clojure-1-5.core=> (time (doseq [x (range 100)] (reduce + (r/filter #(> 4 (mod %1 10)) (r/map inc numbers))))) "Elapsed time: 729.914422 msecs" nil clojure-1-5.core=> (time (doseq [x (range 100)] (reduce + (filter #(> 4 (mod %1 10)) (map inc numbers))))) "Elapsed time: 847.422309 msecs" nil
Для агентов появилась возможность задать собственный пул тредов для выполнения модифицирующих операций над агентами(с помощью send, send-of, send-via)
Например можно выполнять операции над агентами в один поток(по умолчанию число потоков равно числу ядер + 2)
clojure-1-5.core=> (def a (agent {:a 1})) #'clojure-1-5.core/a clojure-1-5.core=> @a {:a 1} clojure-1-5.core=> (send a assoc :b 2) #<Agent@17d577c: {:a 1, :b 2}> clojure-1-5.core=> @a {:a 1, :b 2} clojure-1-5.core=> (set-agent-send-executor! (java.util.concurrent.Executors/newSingleThreadExecutor)) #<FinalizableDelegatedExecutorService java.util.concurrent.Executors$FinalizableDelegatedExecutorService@108fbd4> clojure-1-5.core=> (send a assoc :c 3) #<Agent@17d577c: {:a 1, :c 3, :b 2}> clojure-1-5.core=> @a {:a 1, :c 3, :b 2}
Для кастомизации функции send используется set-agent-send-executor! для send-off используется set-agent-send-off-executor!. Если нужно выполнить действие над агентом с произвольным исполнителем, можно использовать send-via. В общем случае функцию send следует использовать когда операция занимает фиксированное количество времени, а send-off когда операция может быть заблокирована по I/O или другому внешнему ресурсу.
Начиная с версии 1.5 функции-конструкторы (hash-map, array-map) принимают дублирующие значения ключей и не выкидывают исключения
в версии 1.4
(hash-map :a 1 :b 2 :a 4) IllegalArgumentException Duplicate key: :a clojure.lang.PersistentHashMap.createWithCheck (PersistentHashMap.java:92)в 1.5
(hash-map :a 1 :b 2 :a 4) {:a 4, :b 2}объявление литерала c дублирующими ключами по прежнему кидает исключение
{:a 1 :b 2 :a 4} #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: :a>
К макросам -> ->> добавилось несколько новых макросов cond-> и cond->> для выполнения последовательности действий с условиями, а также есть возможность задать именнованную область с помощью as->
(-> 84 (/ 4) (as-> twenty-one (* 2 twenty-one))) 42Для последовательности действий, где на промежуточном шаге результат действия может быть nil и необходимо прервать выполнение дальнейших шагов есть макрос some-> (или some->>)
(-> (range 1) next inc) NullPointerException [trace missing] (some-> (range 1) next inc) nil
Новая версия gen-class позволяет обращаться к protected final методам родительского класса через :exposes-methods
К мета данным (функция meta) добавлен атрибут :column, указывающий номер колонки в исходном файле. До версии 1.5 был указан только номер строки :line
насчет Java 7 - не совсем точно. Оно может работать и с 6-й версией, при явном добавлении библиотеки для fork/join и даже с 5-й версией, если reducers не будут использоваться
ОтветитьУдалить