# Как это выглядит
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”})
# Философия
См. 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
Безопасно!