Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
CLOJURE
LISP FOR THE MODERN
WORLD
Alex Ott
alexott@gmail.com, http://alexott.net/
О чем пойдет речь?
   Что такое Clojure?
   Основы языка
     Базовый синтаксис
     Метапрограммирование

     Полиморфизм

     Конкурентное программирование

   Clojure в реальной жизни
   Clojure для веб-разработки
Что такое Clojure?
   Функциональный (неизменяемые данные, ФВП, …)
   Lisp-ообразный
   Конкурентное программирование
   Многоплатформенный (JVM, .Net, JavaScript, etc.)
   Открытый исходный код и либеральная лицензия
   Активное сообщество разработчиков
   Коммерческое применение
   Коммерческая поддержка
Почему ФП?
   Неизменяемость данных
   Отсутствие побочных эффектов
   Функции в математическом смысле
   Функции – объекты первого порядка
   Возможность автоматической параллелизации
    кода
   Меньше проблем с конкурентным
    выполнением кода
Почему Lisp?
   Простой синтаксис - code as data structures
    (Homoiconic)
   Метапрограммирование (макросы)
     Создание доменно-специфических языков
     Генерация кода во время компиляции

     Возможность избежать повторений

   Генерация и выполнение кода в runtime
   Интерактивная разработка
   Динамически типизированный
Отличия от других Lisp’ов
   Немного упрощенный синтаксис -- меньше
    скобочек
   Неизменяемые данные
    Добавлено больше базовых структур данных:
    вектора, отображения (maps) и т.п.
   Расширяемый reader, но без reader macros
   "Ленивые" коллекции
   Мета-информация привязанная к данным и
    функциям
   Case-sensitive names
   Исключения вместо условий/рестартов
Базовый синтаксис
   Код – структуры данных
   Выражение – список, первый элемент бывает:
     Функция
     Макрос
     Специальная форма

   Примеры:
    (def a 1)
    (+ 1 2)
    (defn func [x] (* x x))
    (defmacro when [x & body]
      `(if ~x (do ~@body)))
Как выполняется код
Базовые типы данных
   Числа (целые, рациональные, вещественные):
    42, 1/3, 1N, 4.2, 42.2M
   Строки: "String»
   Знаки (characters): a, newline, …
   Регулярные выражения: #"d+"
   Логические значения: true, false
   nil – как null в Java
   Символ (symbol): name
   Keyword: :name, (:name {:name "test"})
Коллекции
   Разные коллекции:
       Списки: (1 2 3 "abc")
       Вектора: [1 2 3]
       Отображения (maps): {:k1 1234 :k2 "value"}
       Множества: #{:val1 "text" 1 2 10}
   Persistent & transient коллекции
   Вектора, отображения и множества сами являются
    функциями:
    ([1 2 3] 2) => 3
    ({:a 1 :b 2 :c 3} :b) => 2
Persistent collections
   Новая копия данных
    при изменении
   Затрагивается только
    измененная часть
   Производительность
    сравнима с
    коллекциями Java
Последовательности
   Последовательности (sequences):
     Коллекции Clojure & Java, массивы, iterable, …
     "Ленивые" операции над
      последовательностями
     Могут быть бесконечными

     Один набор операций над
      последовательностями: map, reduce, filter, …
Управляющие структуры
   Определение переменной: (def name value)
   Определение функции: (defn name [args…]
    body), (fn [args…] body), #(body)
   Локальные переменные: (let [name1 value1
    name2 value2] body)
   Ветвление: if, cond, when, …
   Последовательное выполнение: do
   Цикл: loop/recur
   List comprehension: for
   Исключения: try/catch, throw
Метапрограммирование и макросы

   Макросы – функции, выполняемые во время
    компиляции
   Макросы получают код и возвращают новый код
   Генерация кода:
     Стандартные функции работы со списками
     Quasi-quote (`) и операторы подстановки: ~ и ~@

   Суффикс # для генерации уникальных имен
   macroexpand-1 & macroexpand для отладки
   Большая часть библиотеки Clojure – макросы
Макросы: примеры
Макрос (любой из двух):
 (defmacro when [test & body]
  (list 'if test (cons 'do body)))
  (defmacro when [x & body]
    `(if ~x (do ~@body)))
Использование:
 (when (pos? a)
  (println "positive") (/ b a))
Раскрывается в:
 (if (pos? a)
   (do (println "positive") (/ b a)))
Полиморфизм: мультиметоды
   CLOS-подобный полиморфизм
   Диспатчеризация в зависимости от любого
    условия и количества аргументов
   Диспатчеризация выполняется функцией
   Диспатчеризация во время выполнения
   Возможность построения иерархических
    зависимостей между типами
Мультиметоды: примеры
   Определение:
    (defmulti m-example class)
    (defmethod m-example String [this]
      (println "This is string '" this "'"))
    (defmethod m-example java.util.Collection [this]
      (print "This is collection!"))
   Использование:
    (m-example "Hello") => "This is string 'Hello'"
    (m-example [1 2 3]) => "This is collection!"
    (m-example '(1 2 3)) => "This is collection!”
Мультиметоды: примеры
(defmulti encounter
   (fn [x y] [(:Species x) (:Species y)]))
(defmethod encounter [:Bunny :Lion] [b l] :run-away)
(defmethod encounter [:Lion :Bunny] [l b] :eat)
(defmethod encounter [:Lion :Lion] [l1 l2] :fight)
(defmethod encounter [:Bunny :Bunny] [b1 b2] :mate)
(def b1 {:Species :Bunny})
(def b2 {:Species :Bunny})
(def l1 {:Species :Lion})
(def l2 {:Species :Lion})

(encounter b1 b2) ==> :mate
(encounter b1 l1) ==> :run-away
(encounter l1 b1) ==> :eat
(encounter l1 l2) ==> :fight
Полиморфизм: протоколы
   Способ решения expression problem
   Диспатчеризация только по типу данных
   Быстрее чем мультиметоды
   defprotocol: определяет протокол
   deftype: новые типы данных (низкоуровневый)
   defrecord: новые типы данных (только данные)
   Можно реализовать протокол для произвольных
    классов или интерфейсов (extend-protocol &
    extend-type)
Протоколы: примеры
(defprotocol Hello "Test of protocol"
 (hello [this] "hello function"))

(defrecord B [name] Hello
 (hello [this] (str "Hello " (:name this) "!")))
(hello (B. "User")) => "Hello User!"

(extend-protocol Hello String
         (hello [this] (str "Hello " this "!")))
(hello "world") => "Hello world!"

(extend-protocol Hello java.lang.Object
  (hello [this] (str "Hello '" this "'! ("
               (type this) ")")))
(hello 1) => "Hello '1'! (class java.lang.Integer)”
Concurrency: пространство и время

   Clojure разделяет
    концепции состояния    Code               Code             Code

    (state) и имени        (past)           (present)        (future)



    (identity)
   Состояние (значение)                    Identity
                                       (ref/agent/atom
                                             name)
    не изменяется!
    Identity просто
    указывает на новое     State S1
                           [1 2 3 4]
                                             State S2
                                          [1 2 3 4 5 6 7]
                                                            State S3
                                                            [?????]

    состояние
Конкурентное программирование

   Средства для изменяемых данных:
     Ссылки (refs): синхронное, координированное
      изменение (STM)
     Агенты: асинхронное, некоординированное
      изменение
     Атомы: синхронное, некоординированное
      изменение
     Vars: thread-local изменение

   @ или deref для доступа к данным
   Валидаторы и функции-наблюдатели
Конкурентное программирование

   Параллельное выполнение кода:
     future
     pmap, pvalues, pcalls

     потоки JVM

   Синхронизация: promise
   Отложенное выполнение кода: delay
   Конкурентные примитивы из JVM
Сoncurrency: примеры
(defn acc-validator [new]
 (if (neg? (:amount new))
   (throw (Exception. "Not money on account!"))
   true))

(defn make-account [name init-amount]
 (let [r (ref {:name name :amount init-amount})]
   (set-validator! r acc-validator) r))

(def acc1 (make-account "User1" 1000))
(def acc2 (make-account "User2" 300))

(defn money-transfer [from to amount]
 (dosync (alter from update-in [:amount] - amount)
      (alter to update-in [:amount] + amount)))

(money-transfer acc1 acc2 100) => acc1 = 900, acc2 = 400
(money-transfer acc1 acc2 1000) => Exception “No money”
Взаимодействие с платформой
   Взаимодействие с платформой:
     Создание объектов: (Class.) или (new Class)
     Вызов методов или доступ к членам классов:

      `.’, `..’ или doto
     Генерация классов и интерфейсов

   Вызов Clojure кода из Java, и т.п.
   Примитивы для работы с массивами
   Генерация и перехват исключений
Interoperability: примеры
   Создание объектов:
    (new java.util.Date) <==> (java.util.Date.)
   Вызов методов:
    (.substring "Hello World" 0 5) => "Hello"
    (. "Hello World" substring 0 5) => "Hello"
    Math/PI              => 3.141592653589793
    (Integer/parseInt "42")   => 42
    Clj: (.. System getProperties (get "os.name"))
    Java: System.getProperties().get("os.name")
    (doto (java.util.HashMap.)
     (.put "a" 1) (.put "b" 2))
IDE & средства сборки кода
   Поддержка в IDE/редакторах:
     Eclipse (Counterclocwise)
     Netbeans (Enclojure)
     IntelliJ IDEA (La Clojure)
     Emacs + SLIME или nRepl
     VimClojure
     Textmate, Sublime Text 2, Jedit

   Средства сборки кода:
     Поддержка Clojure в Maven, Ant, Cake, Gradle
     Leiningen: самый популярный
Библиотеки и репозитории
   Простой доступ к библиотекам JVM
   Библиотеки написанные на Clojure:
     Web-разработка: Compojure, Ring, Scriptjure, Noir
     RDBMS: ClojureQL, clojure.java.jdbc, Korma

     NoSQL: Monger, Clouch, …

     Contrib библиотеки: core.*

     GUI: Seesaw

     Логическое программирование: core.logic

   Репозитории: Maven Central, Clojars.org
Как все это дело изучать?
   Много книг
   Интерактивные сайты:
    4clojure.com, tryclj.com, himera.herokuapp.com,
    …
   Множество видео-лекций
   Списки рассылки: clojure, clojure-russian, …
   Группы пользователей
   Конференции в США и Европе
   IRC
   Clojure/core: поддержка, тренинги, …
Webdev: server side
   Ring – низкоуровневая основа:
     Функции-обработчики
     Объекты request/response

     Middleware – функции-обертки для обработчика

   Более высокоуровневые фреймворки:
     Compojure – упрощение разработки с Ring
     Noir – микрофреймворк на базе Ring

   Hiccup – генерация HTML
   Плугины для Leiningen: lein-ring, lein-noir, …
   Standalone или war
Webdev: server side, примеры
 (defroutes app-routes
  (GET ["/user/:id", :id #"[0-9]+"] [id]
     (get-user-info id))
  (GET "/users/" []
     (get-user-list))
  (GET "/" [] "It works!n")
  (route/resources "/")
  (route/not-found "Resource isn't found"))

 (def app (-> #'app-routes
               wrap-base-url
               handler/site
               (wrap-reload '[ws])))
Webdev: ClojureScript
   Подмножество Clojure:
       Пространства имен
       Неизменяемые данные
       ….
   Библиотеки из Clojure & JavaScript
   Производительный
   Оптимизуется с помощью Google Closure
   Может выполняться на Node.js
   Отличия от Clojure:
       нет ссылок/транзакций, агентов и vars – только атомы
       отличия в объявлении пространств имен
       нет компиляции и вычисления кода в run-time
       нет Java-специфичных вещей, как gen-class, gen-interface, …
Webdev: deployment
   Поддержка развертывания для:
     Google App Engine
     Heroku

     RedHat's OpenShift
     Elastic Beanstalk

   Платформо-специфичные библиотеки
   Плагины для Leiningen
Вопросы




     Спасибо за внимание

More Related Content

Clojure: Lisp for the modern world (русская версия)

  • 1. CLOJURE LISP FOR THE MODERN WORLD Alex Ott alexott@gmail.com, http://alexott.net/
  • 2. О чем пойдет речь?  Что такое Clojure?  Основы языка  Базовый синтаксис  Метапрограммирование  Полиморфизм  Конкурентное программирование  Clojure в реальной жизни  Clojure для веб-разработки
  • 3. Что такое Clojure?  Функциональный (неизменяемые данные, ФВП, …)  Lisp-ообразный  Конкурентное программирование  Многоплатформенный (JVM, .Net, JavaScript, etc.)  Открытый исходный код и либеральная лицензия  Активное сообщество разработчиков  Коммерческое применение  Коммерческая поддержка
  • 4. Почему ФП?  Неизменяемость данных  Отсутствие побочных эффектов  Функции в математическом смысле  Функции – объекты первого порядка  Возможность автоматической параллелизации кода  Меньше проблем с конкурентным выполнением кода
  • 5. Почему Lisp?  Простой синтаксис - code as data structures (Homoiconic)  Метапрограммирование (макросы)  Создание доменно-специфических языков  Генерация кода во время компиляции  Возможность избежать повторений  Генерация и выполнение кода в runtime  Интерактивная разработка  Динамически типизированный
  • 6. Отличия от других Lisp’ов  Немного упрощенный синтаксис -- меньше скобочек  Неизменяемые данные  Добавлено больше базовых структур данных: вектора, отображения (maps) и т.п.  Расширяемый reader, но без reader macros  "Ленивые" коллекции  Мета-информация привязанная к данным и функциям  Case-sensitive names  Исключения вместо условий/рестартов
  • 7. Базовый синтаксис  Код – структуры данных  Выражение – список, первый элемент бывает:  Функция  Макрос  Специальная форма  Примеры: (def a 1) (+ 1 2) (defn func [x] (* x x)) (defmacro when [x & body] `(if ~x (do ~@body)))
  • 9. Базовые типы данных  Числа (целые, рациональные, вещественные): 42, 1/3, 1N, 4.2, 42.2M  Строки: "String»  Знаки (characters): a, newline, …  Регулярные выражения: #"d+"  Логические значения: true, false  nil – как null в Java  Символ (symbol): name  Keyword: :name, (:name {:name "test"})
  • 10. Коллекции  Разные коллекции:  Списки: (1 2 3 "abc")  Вектора: [1 2 3]  Отображения (maps): {:k1 1234 :k2 "value"}  Множества: #{:val1 "text" 1 2 10}  Persistent & transient коллекции  Вектора, отображения и множества сами являются функциями: ([1 2 3] 2) => 3 ({:a 1 :b 2 :c 3} :b) => 2
  • 11. Persistent collections  Новая копия данных при изменении  Затрагивается только измененная часть  Производительность сравнима с коллекциями Java
  • 12. Последовательности  Последовательности (sequences):  Коллекции Clojure & Java, массивы, iterable, …  "Ленивые" операции над последовательностями  Могут быть бесконечными  Один набор операций над последовательностями: map, reduce, filter, …
  • 13. Управляющие структуры  Определение переменной: (def name value)  Определение функции: (defn name [args…] body), (fn [args…] body), #(body)  Локальные переменные: (let [name1 value1 name2 value2] body)  Ветвление: if, cond, when, …  Последовательное выполнение: do  Цикл: loop/recur  List comprehension: for  Исключения: try/catch, throw
  • 14. Метапрограммирование и макросы  Макросы – функции, выполняемые во время компиляции  Макросы получают код и возвращают новый код  Генерация кода:  Стандартные функции работы со списками  Quasi-quote (`) и операторы подстановки: ~ и ~@  Суффикс # для генерации уникальных имен  macroexpand-1 & macroexpand для отладки  Большая часть библиотеки Clojure – макросы
  • 15. Макросы: примеры Макрос (любой из двух): (defmacro when [test & body] (list 'if test (cons 'do body))) (defmacro when [x & body] `(if ~x (do ~@body))) Использование: (when (pos? a) (println "positive") (/ b a)) Раскрывается в: (if (pos? a) (do (println "positive") (/ b a)))
  • 16. Полиморфизм: мультиметоды  CLOS-подобный полиморфизм  Диспатчеризация в зависимости от любого условия и количества аргументов  Диспатчеризация выполняется функцией  Диспатчеризация во время выполнения  Возможность построения иерархических зависимостей между типами
  • 17. Мультиметоды: примеры  Определение: (defmulti m-example class) (defmethod m-example String [this] (println "This is string '" this "'")) (defmethod m-example java.util.Collection [this] (print "This is collection!"))  Использование: (m-example "Hello") => "This is string 'Hello'" (m-example [1 2 3]) => "This is collection!" (m-example '(1 2 3)) => "This is collection!”
  • 18. Мультиметоды: примеры (defmulti encounter (fn [x y] [(:Species x) (:Species y)])) (defmethod encounter [:Bunny :Lion] [b l] :run-away) (defmethod encounter [:Lion :Bunny] [l b] :eat) (defmethod encounter [:Lion :Lion] [l1 l2] :fight) (defmethod encounter [:Bunny :Bunny] [b1 b2] :mate) (def b1 {:Species :Bunny}) (def b2 {:Species :Bunny}) (def l1 {:Species :Lion}) (def l2 {:Species :Lion}) (encounter b1 b2) ==> :mate (encounter b1 l1) ==> :run-away (encounter l1 b1) ==> :eat (encounter l1 l2) ==> :fight
  • 19. Полиморфизм: протоколы  Способ решения expression problem  Диспатчеризация только по типу данных  Быстрее чем мультиметоды  defprotocol: определяет протокол  deftype: новые типы данных (низкоуровневый)  defrecord: новые типы данных (только данные)  Можно реализовать протокол для произвольных классов или интерфейсов (extend-protocol & extend-type)
  • 20. Протоколы: примеры (defprotocol Hello "Test of protocol" (hello [this] "hello function")) (defrecord B [name] Hello (hello [this] (str "Hello " (:name this) "!"))) (hello (B. "User")) => "Hello User!" (extend-protocol Hello String (hello [this] (str "Hello " this "!"))) (hello "world") => "Hello world!" (extend-protocol Hello java.lang.Object (hello [this] (str "Hello '" this "'! (" (type this) ")"))) (hello 1) => "Hello '1'! (class java.lang.Integer)”
  • 21. Concurrency: пространство и время  Clojure разделяет концепции состояния Code Code Code (state) и имени (past) (present) (future) (identity)  Состояние (значение) Identity (ref/agent/atom name) не изменяется! Identity просто указывает на новое State S1 [1 2 3 4] State S2 [1 2 3 4 5 6 7] State S3 [?????] состояние
  • 22. Конкурентное программирование  Средства для изменяемых данных:  Ссылки (refs): синхронное, координированное изменение (STM)  Агенты: асинхронное, некоординированное изменение  Атомы: синхронное, некоординированное изменение  Vars: thread-local изменение  @ или deref для доступа к данным  Валидаторы и функции-наблюдатели
  • 23. Конкурентное программирование  Параллельное выполнение кода:  future  pmap, pvalues, pcalls  потоки JVM  Синхронизация: promise  Отложенное выполнение кода: delay  Конкурентные примитивы из JVM
  • 24. Сoncurrency: примеры (defn acc-validator [new] (if (neg? (:amount new)) (throw (Exception. "Not money on account!")) true)) (defn make-account [name init-amount] (let [r (ref {:name name :amount init-amount})] (set-validator! r acc-validator) r)) (def acc1 (make-account "User1" 1000)) (def acc2 (make-account "User2" 300)) (defn money-transfer [from to amount] (dosync (alter from update-in [:amount] - amount) (alter to update-in [:amount] + amount))) (money-transfer acc1 acc2 100) => acc1 = 900, acc2 = 400 (money-transfer acc1 acc2 1000) => Exception “No money”
  • 25. Взаимодействие с платформой  Взаимодействие с платформой:  Создание объектов: (Class.) или (new Class)  Вызов методов или доступ к членам классов: `.’, `..’ или doto  Генерация классов и интерфейсов  Вызов Clojure кода из Java, и т.п.  Примитивы для работы с массивами  Генерация и перехват исключений
  • 26. Interoperability: примеры  Создание объектов: (new java.util.Date) <==> (java.util.Date.)  Вызов методов: (.substring "Hello World" 0 5) => "Hello" (. "Hello World" substring 0 5) => "Hello" Math/PI => 3.141592653589793 (Integer/parseInt "42") => 42 Clj: (.. System getProperties (get "os.name")) Java: System.getProperties().get("os.name") (doto (java.util.HashMap.) (.put "a" 1) (.put "b" 2))
  • 27. IDE & средства сборки кода  Поддержка в IDE/редакторах:  Eclipse (Counterclocwise)  Netbeans (Enclojure)  IntelliJ IDEA (La Clojure)  Emacs + SLIME или nRepl  VimClojure  Textmate, Sublime Text 2, Jedit  Средства сборки кода:  Поддержка Clojure в Maven, Ant, Cake, Gradle  Leiningen: самый популярный
  • 28. Библиотеки и репозитории  Простой доступ к библиотекам JVM  Библиотеки написанные на Clojure:  Web-разработка: Compojure, Ring, Scriptjure, Noir  RDBMS: ClojureQL, clojure.java.jdbc, Korma  NoSQL: Monger, Clouch, …  Contrib библиотеки: core.*  GUI: Seesaw  Логическое программирование: core.logic  Репозитории: Maven Central, Clojars.org
  • 29. Как все это дело изучать?  Много книг  Интерактивные сайты: 4clojure.com, tryclj.com, himera.herokuapp.com, …  Множество видео-лекций  Списки рассылки: clojure, clojure-russian, …  Группы пользователей  Конференции в США и Европе  IRC  Clojure/core: поддержка, тренинги, …
  • 30. Webdev: server side  Ring – низкоуровневая основа:  Функции-обработчики  Объекты request/response  Middleware – функции-обертки для обработчика  Более высокоуровневые фреймворки:  Compojure – упрощение разработки с Ring  Noir – микрофреймворк на базе Ring  Hiccup – генерация HTML  Плугины для Leiningen: lein-ring, lein-noir, …  Standalone или war
  • 31. Webdev: server side, примеры (defroutes app-routes (GET ["/user/:id", :id #"[0-9]+"] [id] (get-user-info id)) (GET "/users/" [] (get-user-list)) (GET "/" [] "It works!n") (route/resources "/") (route/not-found "Resource isn't found")) (def app (-> #'app-routes wrap-base-url handler/site (wrap-reload '[ws])))
  • 32. Webdev: ClojureScript  Подмножество Clojure:  Пространства имен  Неизменяемые данные  ….  Библиотеки из Clojure & JavaScript  Производительный  Оптимизуется с помощью Google Closure  Может выполняться на Node.js  Отличия от Clojure:  нет ссылок/транзакций, агентов и vars – только атомы  отличия в объявлении пространств имен  нет компиляции и вычисления кода в run-time  нет Java-специфичных вещей, как gen-class, gen-interface, …
  • 33. Webdev: deployment  Поддержка развертывания для:  Google App Engine  Heroku  RedHat's OpenShift  Elastic Beanstalk  Платформо-специфичные библиотеки  Плагины для Leiningen
  • 34. Вопросы Спасибо за внимание

Editor's Notes

  1. Presentation slide for courses, classes, lectures et al.
  2. Objectives for instruction and expected results and/or skills developed from learning.
  3. Relative vocabulary list.
  4. Conclusion to course, lecture, et al.