Slide 1

Slide 1 text

# mainstreamless ## Clojure 00 Никита Прокопов tonsky.livejournal.com 6 марта 2013

Slide 2

Slide 2 text

# Причины создания clojure.org/rationale Развитая платформа ЛИСП Функциональное программирование Concurrency

Slide 3

Slide 3 text

# JVM Быстрая Качественная Уровенем выше ОС, лучше абстракции Валом библиотек Валом инструментов

Slide 4

Slide 4 text

# JVM Уважает платформу Писать джаву на кложе проще, чем на джаве clj strings == java strings clj numbers == java numbers clj nil == java null

Slide 5

Slide 5 text

# LISP Гибкий Динамичный — новое для JVM Маленькое ядро → портируемость Почти нет синтаксиса Код-как-данные

Slide 6

Slide 6 text

# LISP def if do let quote var fn loop recur throw try monitor-enter monitor-exit . new set!

Slide 7

Slide 7 text

# LISP REPL Открытость — всё управляемо Даже синтаксис!

Slide 8

Slide 8 text

# ФП Удобный инструмент First-class functions Lexical closures Ленивость Dynamic typing

Slide 9

Slide 9 text

# Как это выглядит public class StringUtils { public static boolean isBlank(String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true; } }

Slide 10

Slide 10 text

# Как это выглядит (defn blank? [s] (every? #(Character/isWhitespace %) s))

Slide 11

Slide 11 text

# Как это выглядит public class StringUtils { public static boolean isBlank(String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true; } } (defn blank? [s] (every? #(Character/isWhitespace %) s))

Slide 12

Slide 12 text

# Синтаксис method() method(arg) object.method(arg) Map map = new HashMap(); map.put(“key”, “value”); (f) (f arg) (f object arg), (.method o a) (def map {:key “value”})

Slide 13

Slide 13 text

# Синтаксис (defn f [x y] (+ x y)) [1 2 3] (1 2 3) {:x 1 :y 2} #{:x :y :z}

Slide 14

Slide 14 text

# Философия См. youtube.com/clojuretv Особенно (!) Rich Hickey

Slide 15

Slide 15 text

# Открывайте данные Программы перемалывают данные Не прячьте их “It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures.”

Slide 16

Slide 16 text

# Открывайте данные distinct filter remove for keep keep-indexed cons concat lazy-cat mapcat cycle interleave interpose rest next fnext nnext drop drop-while nthnext for take take-nth take-while butlast drop-last for flat- ten reverse sort sort-by shuffle split-at split-with partition partition-all partition-by map pmap mapcat for replace reductions map-indexed seque first ffirst nfirst second nth when-first last rand-nth zipmap into reduce set vec into-array to-array-2d frequen- cies group-by apply not-empty some reduce seq? eve- ry? not-every? not-any? empty? some filter doseq do- run doall realized? seq vals keys rseq subseq rsubseq lazy-seq repeatedly iterate repeat range line-seq resultset-seq re-seq tree-seq file-seq xml-seq itera-

Slide 17

Slide 17 text

# Decomplecting Var = value + time Object = state + identity + value Method = func + state + namespace Actors = what + who Loops = what + how ...

Slide 18

Slide 18 text

# Открытость Мультиметоды, протоколы Метаданные Predicate dispatch вместо pattern matching Composable abstractions $().click().css() или (-> ($ ...) (click ) (css))

Slide 19

Slide 19 text

# Переиспользуемость Неймспейсится всё Нет custom reader, есть EDN Полиморфизм через протоколы

Slide 20

Slide 20 text

# Комбинируемость Avoid things that do not compose Manual locking Imperative code

Slide 21

Slide 21 text

# Concurrency ## Задача колония муравьев собирает пищу каждый муравей — отдельный поток общая карта еды рисовать положение дел

Slide 22

Slide 22 text

# Concurrency ## Задача

Slide 23

Slide 23 text

# Concurrency ## Проблемы неатомарные операции согласованное принятие решений когерентное состояние мира

Slide 24

Slide 24 text

# Проблемы многопоточного программирования «Мир» постоянно меняется Просадка скорости на syncs Dead locks Live locks Легко ошибиться Сложно просчитать варианты Сложно тестировать

Slide 25

Slide 25 text

# Immutable data structures Легко шарить между потоками Операции атомарны по определению Едят кучу памяти (медленно?)

Slide 26

Slide 26 text

# Persistent data structures «Умно» делят общие части Едят мало памяти Быстрые (почти константная стоимость) Портированы в Scala :)

Slide 27

Slide 27 text

# List 1 2 3 list1 head tail list2 head tail list3 head tail

Slide 28

Slide 28 text

# Vector v

Slide 29

Slide 29 text

# Vector v

Slide 30

Slide 30 text

# Vector v

Slide 31

Slide 31 text

# Vector v

Slide 32

Slide 32 text

# Vector v

Slide 33

Slide 33 text

# Vector v

Slide 34

Slide 34 text

# Vector v ... ...

Slide 35

Slide 35 text

# Vector v ... ... up to 32 elms log 32 (size)

Slide 36

Slide 36 text

# Vector v ... ... up to 32 elms log 32 (size) 00[00000][00000][00000][00000][00001][00100]

Slide 37

Slide 37 text

# Map ## Hash trie

Slide 38

Slide 38 text

# Map

Slide 39

Slide 39 text

# Atoms (def x (atom 1)) ;; #’user/x (swap! x inc) ;; 2 (swap! x inc) ;; 3 (swap! x inc) ;; 10 (?) (swap! x #(Math/sin %)) ;; -0.544...

Slide 40

Slide 40 text

# Atoms 1 x

Slide 41

Slide 41 text

# Atoms 1 2 x (f 1)

Slide 42

Slide 42 text

# Atoms 1 2 x swap!

Slide 43

Slide 43 text

# Atoms 1 2 x

Slide 44

Slide 44 text

# Atoms 1 2 3 x (f 2)

Slide 45

Slide 45 text

# Atoms 1 2 3 x swap!

Slide 46

Slide 46 text

# Atoms 1 2 3 x

Slide 47

Slide 47 text

# Atoms 1 2 3 x @x

Slide 48

Slide 48 text

# Atoms 1 2 3 x (f (f 1)) @x

Slide 49

Slide 49 text

# Atoms Для «простого» mutable state Явно выделенная «мутация» Атомарное изменение Любое значение — это всегда результат последовательного применения функций

Slide 50

Slide 50 text

# Atoms ## Конфликты 1 2 3 x (f 2) −2

Slide 51

Slide 51 text

1 2 3 x (f −2) −2 −1 # Atoms ## Конфликты

Slide 52

Slide 52 text

1 2 3 x swap! −2 −1 # Atoms ## Конфликты

Slide 53

Slide 53 text

# Agents (def x (agent 1)) ;; #’user/x (send x inc) ;; # (send x inc) ;; # (send x (fn [a] (Thread/sleep 1000) (inc a))) ;; # @x ;; # @x ;; #

Slide 54

Slide 54 text

# Agent 2 g f h thread pool

Slide 55

Slide 55 text

# Agent 2 h g f thread pool

Slide 56

Slide 56 text

# Agent 2 h g thread pool f

Slide 57

Slide 57 text

# Agent 2 h g thread pool f (f 2)

Slide 58

Slide 58 text

# Agent 3 h g thread pool (f 2)

Slide 59

Slide 59 text

# Agent 3 h g thread pool

Slide 60

Slide 60 text

# Agent 3 h thread pool g

Slide 61

Slide 61 text

# Agent Unit of work Похож на atoms, только… Для последовательных операций: heavy lifting, сохранение в файл, запись в сеть, конечные автоматы, … Выполняется в отдельном потоке Очередь сообщений Всегда наблюдаемое состояние

Slide 62

Slide 62 text

# STM Согласованное изменение состояния Проще рассуждать Сложнее ошибиться Composable Агенты работают с STM!

Slide 63

Slide 63 text

# STM

Slide 64

Slide 64 text

# Concurrency Иммутабельность Персистентные структуры данных Software transactional memory Lock-free Composable Безопасно!

Slide 65

Slide 65 text

# mainstreamless ## Clojure 00 Никита Прокопов tonsky.livejournal.com 6 марта 2013