Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

# Clojure web stack Servlet Netty Mongrel2 Http-kit Aleph Ring Moustache Compojure Enlive Hiccup Laser ClojureScript Domina Enfocus Crate Javelin Reflex

Slide 3

Slide 3 text

# Ring Server ←→ app contract fn [request-map] → response-map Похоже на WSGi (Python) github.com/ring-clojure/ring/blob/master/SPEC

Slide 4

Slide 4 text

# Ring { :uri :query-string :request-method :headers :body ... } → { :status :headers :body }

Slide 5

Slide 5 text

# Ring Нет реализации — нет зависимостей, багов, етц Маленькая — легко реализовать Низкоуровневая Вход-выход — просто тестировать Веб-сокеты не засунешь

Slide 6

Slide 6 text

# Middleware (fn [handler ...] → handler’) ring.middleware: + Sessions + Cookies + Uploads + Form parsing ...

Slide 7

Slide 7 text

# Диспатчинг ## Moustache (def my-app (app [“hi”] {:get “hello world only for GET!”} [“hi” name] {:get [“hello “ name]}))

Slide 8

Slide 8 text

# Диспатчинг ## Compojure (defroutes app (GET “/” [] “

Hello World

”) (route/not-found “

Page not found

”))

Slide 9

Slide 9 text

# Templating — цветочки ## Hiccup (html [:span {:class “foo”} “bar”]) bar (html [:div#foo.bar.baz “bang”])
bang

Slide 10

Slide 10 text

# Templating — цветочки ## Hiccup (defn with-cdn [cdn-url form] (clojure.walk/postwalk (fn [node] (if (rel-asset-path? node) (cdn-url node) node) form)))

Slide 11

Slide 11 text

# Templating — ягодки ## Enlive Парсинг и трансформация HTML Код отдельно от верстки Переиспользование snippets Модификации можно комбинировать Макросы!

Slide 12

Slide 12 text

# Templating — ягодки ## Enlive (at a-node [:a :selector] a-transformation [:another :selector] another-transformation ...) (html/deftemplate index “tutorial/template1.html” [ctxt] [:p#message] (html/content (get ctxt :message “Nothing to see here”))

Slide 13

Slide 13 text

# Templating — ягодки ## Laser Еще более функциональный (laser/document (laser/parse html) (laser/class= “meow”) (laser/content “omg”))

Slide 14

Slide 14 text

# Aleph Сетевая библиотека Общение через каналы Conforms to Ring, только request и response разделены HTTP, WebSockets, TCP, UDP, Redis

Slide 15

Slide 15 text

# Aleph async (defn handler [response-channel request] (enqueue response-channel {:status 200 :headers {“content-type” “text/plain”} :body “Hello World”}))

Slide 16

Slide 16 text

# Aleph async (def handler (app [“sync”] {:get “response”} [“async”] {:get (wrap-aleph-handler async-han- dler)})) (start-http-server (wrap-ring-handler handler) {:port 8080})

Slide 17

Slide 17 text

# Aleph async (def broadcast-channel (channel)) (defn chat-handler [ch handshake] (receive ch (fn [name] (siphon (map* #(str name “: “ %) ch) broadcast-channel) (siphon broadcast-channel ch)))) (start-http-server chat-handler {:port 8080 :websocket true})

Slide 18

Slide 18 text

# http-kit Pure Java & Clojure, very small Server & client Ring-compliant Websockets, long-polling, streaming extensions

Slide 19

Slide 19 text

# edn Data exchange format Based on Clojure syntax Rich set of elements collections, symbols, keywords Extensible for new types Self-describing (no schema) Namespaces

Slide 20

Slide 20 text

# edn { :created_at #inst “1985-04-12T23:20:50.52Z” :id 209722238071619586 :id_str “209722238071619586” :retweeted false :text “tweet” :com.google.maps/geo nil :entries { :user_mentions [ { :id 1001 :indices [0 16] :name “Petrov” } ] } }

Slide 21

Slide 21 text

# edn clojure.core/read-string clojure.edn/read-string (since 1.5)

Slide 22

Slide 22 text

# edn clojure.core/read-string clojure.edn/read-string (since 1.5) and cljs.reader/read-string

Slide 23

Slide 23 text

# ClojureScript

Slide 24

Slide 24 text

# Lessons learned from Node.js Писать клиент и сервер на одном языке очень удобно! Только почему на JavaScript?

Slide 25

Slide 25 text

# ClojureScript JS is broken

Slide 26

Slide 26 text

# ClojureScript JS is fundamentally broken

Slide 27

Slide 27 text

# ClojureScript JS is fundamentally broken Синтаксические изменения не спасут Нужно править семантику

Slide 28

Slide 28 text

# Что сломано? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 29

Slide 29 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 30

Slide 30 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 31

Slide 31 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 32

Slide 32 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 33

Slide 33 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 34

Slide 34 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 35

Slide 35 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции

Slide 36

Slide 36 text

# CoffeeScript? Типы Структуры данных Зависимости Неймспейсы Полиморфизм Типовые операции Меньше кнопок нажимать

Slide 37

Slide 37 text

# Как правильно? Состояние Иммутабельность ФП Макросы Строгая типизация Протоколы

Slide 38

Slide 38 text

# Как правильно? Стандартные решения для стандартных проблем

Slide 39

Slide 39 text

# Как правильно? Стандартные решения для стандартных проблем Реализаций import: 0 ООП-фреймворков: 0 Альтерн. синтаксисов: 0 Альтерн. коллекций: 0 Monad tutorials: 0

Slide 40

Slide 40 text

# Как работает? Компилируется на большой Clojure Генерирует Javascript для Google Closure Compiler Оптимизируется Google Closure Compiler Зависимости через Goolge Closure Library

Slide 41

Slide 41 text

Notice Clojure (Rich Hickey) and Closure (Google)

Slide 42

Slide 42 text

# Компиляция? Dead code elimination Smart code compression Снимает browser quirks Может увеличить производительность Debug :(

Slide 43

Slide 43 text

# Отличия от Clojure Однопоточный Compilation и macroexpansion только на Clojure (no eval) Browser-connected REPL Native JS regexes

Slide 44

Slide 44 text

# Отличия от Clojure Atoms, but no Refs nor STM No Vars No agents No symbol or var (def) metadata

Slide 45

Slide 45 text

# Отличия от Clojure (.foo o) => o.foo() (.-foo o) => o.foo

Slide 46

Slide 46 text

# Персистентные структуры данных Native JS impl http://www.50ply.com/cljs-bench/ 2-6 times slower than JVM Google Chrome usually ×3-5 times faster than Safari / FF

Slide 47

Slide 47 text

# Персистентные структуры данных

Slide 48

Slide 48 text

# Персистентные структуры данных

Slide 49

Slide 49 text

# Зачем? Разработка больших приложений Организация кода Командная работа Переиспользуемость кода Производительность, оптимизация

Slide 50

Slide 50 text

# Библиотеки No problem Нужен extern файл /** * @param {(string|Object.)} arg1 * @param {Object.=} settings * @return {jQuery.jqXHR} */ jQuery.ajax = function(arg1, settings) {};

Slide 51

Slide 51 text

# Библиотеки ## jQuery $(“element“) .appen(“xyz”) .attr(“data-weight”, 70) .css(“left”, 156 + “px”); (-> (js/$ “#element“) (.append “xyz“) (.attr “data-weight“ 70) (.css “left“ (str 156 “px”))

Slide 52

Slide 52 text

# Библиотеки ## jayq (def $interface (jq/$ :#interface)) (-> $interface (jq/css {:background “blue”}) (jq/inner “Loading!”))

Slide 53

Slide 53 text

# DOM manipulation Domina Enfocus Crate Webfui Dommy

Slide 54

Slide 54 text

# DOM manipulation Domina ~ jQuery Enfocus ~ Enlive Crate ~ Hiccup Webfui ~ DOM isolation Dommy ~ Efficient macro-compile

Slide 55

Slide 55 text

# FRP javelin reflex shafty

Slide 56

Slide 56 text

# FRP ## Javelin (defn ^:export start [] (let [text (form-cell “#text”) length (cell (count text))] (.focus (by-id “#text”)) (cell (html! “#count” “Length: %s” length))))

Slide 57

Slide 57 text

# CLJS on Node.js Faster startup times Native clients (node-webkit)

Slide 58

Slide 58 text

# Usecases ## Lighttable

Slide 59

Slide 59 text

# Usecases ## Prismatic

Slide 60

Slide 60 text

# Usecases ## Weathertable

Slide 61

Slide 61 text

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