Clojure

обзор

Дмитрий Грошев (@lambdadmitry)

План

  • демо: как начать
  • демо: синтаксис и Emacs
  • демо: Clony
  • повседневное
  • core.matrix
  • CodeNotes
  • vs Erlang

Демо

Как начать: Leiningen

Демо

синтаксис, Emacs, nrepl, paredit

Демо

Clony

WARNING

Слайды далее полны необоснованных утверждений

Повседевное

Seq

  • универсальная абстракция
  • Seqable
  • линейная
  • ленивая (!)
  • chunked
  • много функций для работы с Seq
(for [x [1 2 3]]
    (prn x))
(doseq [x [1 2 3]]
    (prn x))

Структуры данных: vector

  • ordered
  • иммутабельный
  • гетерогенный
  • O(log32) get/set/delete
  • O(1) append (справа)
  • Seqable
(def test-vec [1 :a 2 3])
(test-vec 1)      ; :a
(take 2 test-vec) ; (1 :a)

Структуры данных: map

  • O(log32) get/set/delete/insert
  • Seqable
(def test-map {:a 1 :b 2})
(test-map :a)     ; 1
(:a test-map)     ; 1
(get test-map :a) ; 1
(seq test-map)    ; ([:a 1] [:b 2]) — KVPairs!
(for [[k v] test-map] …)

Atoms

  • CAS семантика
  • swap!/reset!
  • watchers
  • кеши, system state в map'е
(def test-atom (atom 0))
@test-atom            ; 0
(swap! test-atom + 2) ; 3
@test-atom            ; 3
(reset! test-atom 42) ; 42
@test-atom            ; 42

Arrow macros

(-> 1 (+ ,,, 2) (* ,,, 3))

Arrow macros

(def test-map {:a {:b 2}))
(-> test-map (:a) (:b)) ; 2

Arrow macros

(def test-map {:a {:b 2}))
(-> test-map :a :b) ; 2

Arrow macros

(def some-vector […])
(->> some-vector (take 2) (map some-fn) vec)

Arrow macros

(-> headers
    (safe-get :x-ratelimit-reset)
    Long/parseLong
    (* 1000)
    timec/from-long
    timec/to-string)

core.matrix

  • GSoC 2013
  • матричная библиотека на чистом Clojure
  • сравнимая с Java скорость
  • low-level

JVM!

  • slow Clojure: reflection
  • fast Clojure: type hints
(deftype NDArray
  [^doubles data
   ^int ndims
   ^ints shape
   ^ints strides
   ^int offset])

±10% Java

JVM!

  • slow Clojure: Object
  • fast Clojure: primitive
(defn dot-product [^doubles ws ^doubles xs]
  (areduce xs i ret 0.0
    (+ ret (* (aget xs i)
              (aget ws i)))))

±10% Java

macros!

(c-for [k (int 0) (< k n) (inc k)]
  (aset a (inc (aget a k))))

macros!

(require '[hiphip.double :as dbl])
(defn dot-product [ws xs]
  (dbl/asum [x xs w ws] (* x w)))

Уроки core.matrix

  • очень легко написать эффективный tight loop
  • генерация кода для примитивов (полиморфизм для бедных)
  • макросы очень полезны!
  • баг (?) в Clojure замедляет компиляцию больших (10KLOC+) сорцев с тайпхинтами
  • AOT помогает

CodeNotes

  • победитель ClojureCup 2013
  • отсутствующий таск-трекер

Процесс разработки

  • очень легко писать код
  • очень легко наговнякать рабочее решение
  • рефакторить несложно
  • но нужно рефакторить

Идеология

  • libraries >>> frameworks
  • Fine-grained, Composable Abstractions (FCA)
  • очень много готовых либ
  • много очень крутых либ
  • постоянные парадоксы выбора (большой search space)
  • как организовать приложение?

Anecdotal evidence

  • 1-4 человека (мы): совместное владение кодом + рефакторинг
  • 10+ людей (Prismatic): свои абстракции (не фреймворки!)

vs Erlang

  • гораздо шире возможности
  • очень много сахара
  • инфраструктура и экосистема гораздо лучше, чем у Erlang

core.async (vs Erlang)

  • first-order channels
  • больше свободы, чем с акторами
  • чуть сложнее, чем с акторами
  • лучше, чем акторы?

Актор

(go (loop []
      (when-let [msg (<! cs-c)]
        (handler system config user msg sc-c)
        (recur))))
  • core.async + core.match позволяют эмулировать акторов
  • …но нет желания
  • эмуляция дерева супервизоров неудобна
  • …сложность обработки ошибок в JVM?
  • можно выразить очень сложную логику коротко (conditional retry в 10 строк)

Erlang:

  • узкие ниши (стриминговый сервер, «умный» роутер) ИЛИ
  • большие команды

Clojure:

  • маленькие высокопрофессиональные команды И
  • сложные задачи

Резюме

  • очень приятный язык
  • невероятно гибкий
  • никакого BDSM
  • очень помогает в programming in the small
  • (пока) хуже помогает в programming in the large

Учите Clojure!

Programming Clojure, Joy of Clojure

Вопросы?

Слайды: si14.github.io/fprog-2013-10-slides