Clojure – Что это и зачем это?



Clojure – Что это и зачем это?

0 0


slides-clojure-elegion

Slides for e-Legion internal presentation

On Github alwx / slides-clojure-elegion

Clojure

Что это и зачем это?

 

Alexandr Pantyuhov / alexandr.pantyuhov@e-legion.com

Что это?

  • Современный диалект Lisp (2007);
  • Не совместим с другими диалектами Lisp;
  • Работает на платформе JVM (+ ClojureScript & CLR);
  • Изначально спроектирован для поддержки многопоточных вычислений.

О многопоточности

  • Многопоточность слишком сложна в Java;
  • FP/Immutability помогает в свободном обмене данными между потоками;
  • Но в реальных приложениях часто нужна возможность менять глобальные состояния,
  • и поэтому в Clojure поддерживается мутабельность.

Поддержка со стороны IDE

  • Counterclockwise for Eclipse
  • La Clojure for IntelliJ IDEA
  • vim, emacs
  • textmate, sublime, ...

Build Tools

Let's see code!

Последовательности

						(def list '(1 2 3 4 5))          -> #'user/list
(def vect [1 2 3 4 5])           -> #'user/vect
(def hmap {:a 1 :b 2})           -> #'user/hmap

(first list)                     -> 1
(rest list)                      -> (2 3 4 5)
							
(drop 2 [1 2 3 4 5])             -> (3 4 5)
(take 9 (cycle [1 2 3 4]))       -> (1 2 3 4 1 2 3 4 1)
(interleave [:a :b :c] [1 2 3])  -> (:a 1 :b 2 :c 3)
(keys hmap)                      -> (:a :b)
					

Lazy

						(take 10 (filter even? (iterate inc 0)))   -> (0 2 4 6 8 10 12 14 16 18)
					

High order functions

						(map inc [1 2 3 4])       -> (2 3 4 5)
(reduce + [1 2 3 4 5])	  -> 15
(filter even? '(1 2 3))   -> (2)
					

Структуры

						(defstruct person :name :age :sex)              -> #'user/person
(def p (struct person "Alexander" 22 "male"))	-> #'user/p
(:name p)                                       -> "Alexander"
					

Еще чуть о многопоточности

ref

Изменение ссылок на неизменяемые данные в рамках транзакций (больше: http://clojure.org/refs)

						(def counters (ref {}))

(defn add-counter [key val]
	(dosync (alter counters assoc key val)))

(defn increment-counter [key]
	(dosync (alter counters assoc key (inc (@counters key 0)))))
					

Как это работает

						user> @counters
{}
user> (dosync (add-counter :a 1) (add-counter :b 2))
user> @counters
{:a 2, :b 1}
user> (dosync (increment-counter :a) (increment-counter :b))
user> @counters
{:a 2, :b 3}
					

agents

Похожи на ref, но только обновление данных может происходить в любой момент в зависимости от количества заданий. Задания выполняются в отдельном пуле потоков выполнения, размер этого пула ограничен (больше: http://clojure.org/agents)

Многопоточность

Обычный путь

  • изменение мутабельных объектов в разных потоках;
  • наличие блокировок в коде;
  • боль

Clojure way

  • ссылки на иммутабельные объекты;
  • отсутствие каких-либо блокировок;
  • счастье

Взаимодействие с Java

В пространство имен импортируются классы из java.lang

						(def m (String. "Hello"))     -> #'user/m
(.toUpperCase m)              -> "HELLO"
(. m toUpperCase)

(Math/sin 1)                  -> 0.8414709848078965
(. Math sin 1)

(.. System getProperties (get "os.name"))
					
						
(def hmap (java.util.HashMap.))  -> #'user/hmap
(. n put "a" 1)                  -> nil
n                                -> {"a" 1}
(. n equals {"a" 1})             -> true
						
					

Зачем?

What have been the biggest wins for you in using Clojure?

(http://cemerick.com/2011/07/11/results-of-the-2011-state-of-clojure-survey/)

Полезные ресурсы

Вопросы?

Слайды: http://github.com/alwx/slides-clojure-elegion