Clojure #1
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Clojure #1

on

  • 456 views

 

Statistics

Views

Total Views
456
Views on SlideShare
456
Embed Views
0

Actions

Likes
0
Downloads
9
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Clojure #1 Presentation Transcript

  • 1. Clojure #1 Introduction to clojure
  • 2. Why Clojure? ● ● ● ● ● ● ● For JVM with Java interoperability Instant run/reloading Functional Lisp features (macros, expressive) built-in STM Dynamic Good performance
  • 3. Important tools ● Leiningen - Clojure build tool ● REPL, nREPL ● Editors: IDEA (La Clojure, Cursive), Emacs, Light Table
  • 4. Basics
  • 5. Functions Очень простой синтаксис: (fn [] 4)
  • 6. Function call Любая функция вызывается в prefix нотации: (+ 1 1) В данном случае + это функция, а единицы это аргументы.
  • 7. Expressions В Clojure, как практически и в Scala все является выражением, то есть возвращает значение: (if condition then-branch else-branch)
  • 8. Literals ● "a string" - String ● :key - Keyword ● 'symbol - Symbol ● newline, c - Character ● nil - No value ● true, false - Booleans ● Numbers like in Java
  • 9. Data literals ● [1 2 3] - Vector ● {:key value :key1 value1} - Map ● #{:key :key1} - Set ● #() - Анонимная функция (fn)
  • 10. Definitions Определяет “переменные”: (def x (+ 1 (- 3 1)))
  • 11. Named functions (defn foo "This is documentation" [arguments] body) Параметры анонимных функций определяются также.
  • 12. Higher order functions Можно в качестве параметров передавать и другие функции, например: (map inc [1 2 3]) Или анонимный вариант: (map (fn [i] (+ i 1)) [1 2 3])
  • 13. Scoped definitions (let) Можно определить переменные, которые будут видны лишь внутри s-expr: (def sum-result (let [pi Math/PI] (/ (* pi pi) 6)))
  • 14. Conrol structures
  • 15. if Ранее уже видели, else branch должен обязательно присутствовать
  • 16. do Если нужно выполнить несколько выражений прежде, чем что-то вернуть. Признак side effects: (do expr1 expr2 return-expression)
  • 17. when Всегда возвращает nil. Комбинация if только с then branch и do. (when (even? 2) expr1 expr2)
  • 18. if-let Комбинация let и if с проверкой на nil/false: (def France {:capital "Paris"}) (if-let [capital (:capital France)] (println "Capital is " capital) (println "Capital is empty"))
  • 19. cond Является альтернативой для else-if цепочек: (defn foo [n] (cond (> n 0) "positive" (< n 0) "negative" :else "zero"))
  • 20. More Clojure basics
  • 21. Function composition Следующий код легко может быть переписан: (fn [e] (fn1 (fn2 e))) Короче будет так: (comp fn1 fn2)
  • 22. Function application Есть более длинная форма для вызова функции, ее можно использовать, например, в макросах: (apply + [1 2 3])
  • 23. Namespaces Каждый символ определен в каком-то namespace, его можно задать с помощью вызова ns: (ns mylib.core)
  • 24. :requre С помощью этого ключа можно добавить в namespace элементы из других namespaces: (ns foo (:require clojure.test [clojure.string :as str]))
  • 25. :use Это сочетание :require и :refer. Использовать следует с осторожностью, как пример: (ns foo (:use clojure.string)) WARNING: replace already refers to: #'clojure.core/replace in namespace: foo, being replaced by: #'clojure.string/replace WARNING: reverse already refers to: #'clojure.core/reverse in namespace: foo, being replaced by: #'clojure.string/reverse
  • 26. :only Для того, чтобы избежать подобных проблем, можно использовать ключ :only (ns foo (:use [clojure.string :only [join]]))
  • 27. :import С помощью этого ключа можно добавлять классы из Java: (ns some.foo.space "This is namespace doc" (:import (java.util Date GregorianCalendar)))
  • 28. Clojure data structures
  • 29. Lists Списки определяются так: '(1 2 3) '("Scala" "Kotlin" "Erlang" "Clojure")
  • 30. Vectors Вектора уже ранее определяли, это аналог массивов в Clojure.
  • 31. Sets Множества задаются двумя способами #{1 2 3} (set [1 2 3])
  • 32. Maps Также уже ранее обсуждали: {:id :name 55 "Clojure" :is-dynamic true}
  • 33. Immutability Все структуры данных в Clojure неизменяемы. Чаще всего, вновь создаваемые, структуры данных используют предыдущие версии, но все равно это может быть медленно.
  • 34. Transient Для performance critical single-threaded кусков кода, можно написать все быстрее: (defn vrange [n] (loop [i 0 v (transient [])] (if (< i n) (recur (inc i) (conj! v i)) (persistent! v))))
  • 35. Vectors and Maps basics
  • 36. get Для векторов достает элемент по индексу. Для Maps достает элемент по ключу. (get [1 2 3] 1) ;2 (get {:one 1} :one) ;1 get-in принимает вектор, и выполняет последовательно get (get-in [1 [1 2] 3] [1 1]) ;2
  • 37. assoc Для векторов добавляет новый элемент по индексу (возвращает новый вектор). Для Maps добавляет новую пару key/value (assoc [] 0 1) ;[1] (assoc {} :key :value) ;{:key :value}
  • 38. dissoc Удаляет элемент по ключу в Maps: (dissoc {:key :value} :key) ; {}
  • 39. keys/vals Для Maps мы можем вытащить keys и values: (keys {:a :b :c :d}); (:a :c) (vals {:a :b :c :d}); (:b :d)
  • 40. merge Также можно объединять несколько Maps, перекрывая значения слева направо (merge {:a :x :c :x} {:a :b} {:a :c :e :f}) ; {:a :c :c :x :e :f}
  • 41. merge-with Если мы хотим перекрывать справа налево, то это тоже возможно: (merge-with (fn [a b] a) {:a :x :c :x} {:a :b} {:a :c :e :f}) ; {:a :x :c :x :e :f}
  • 42. All collections basics
  • 43. cons Образуется от слова construct, может добавлять первый элемент к спискам и векторам (cons 1 [1 2]) ; [1 1 2] (cons 1 '(1 2)) ; (1 1 2)
  • 44. conj Добавляет элемент туда, где это удобнее в плане реализации коллекции: (conj [1 2] 1) ; [1 2 1] (conj '(1 2) 1) ; (1 1 2)
  • 45. concat Объединяет две последовательности в один список (concat [1 2] '(3 4)) ; (1 2 3 4)
  • 46. disj Удаляет элемент из множества (и только!) (disj #{:a :b} :a) ; #{:b}
  • 47. seq Превращает любую коллекцию (включая Java collections, arrays) в seq коллекцию. Что важно, пустая коллекция превращается в nil.
  • 48. Advanced collection operations
  • 49. partition Разбивает коллекцию на части определенной длины. Можно указать шаг, тогда части смогут перекрываться: (partition 2 [1 2 3 4 5]) ; ((1 2) (3 4))
  • 50. flatten Собирает одну коллекцию из коллекции коллекций: (flatten [a [b] [c d]]) ; (a b c d)
  • 51. frequencies Возвращает частоту, встречающихся элементов: (frequencies [1 2 3 2 1 2]) ; {1 2, 2 3, 3 1}
  • 52. every? Проверяет, что все элементы удовлетворяют некоторому предикату: (every? even? [2 4 6]) ; true (every? even? [1 2 3]) ; false
  • 53. some true если хотя бы один элемент удовлетворяет предикату: (some even? [2 4 5]) ; true (some even? [1 5 3]) ; nil
  • 54. for comprehensions Создает ленивую коллекцию (for [x (range 2) y (range 2)] [x y]) ; [0 0] [0 1] [1 0] [1 1] (for [x (range 3) :while (even? x)] x) ; [2]
  • 55. doseq Поэтому для side effects нужно использовать doseq, в котором они предполагаются, и функция всегда возвращает nil.