Save 37% off PRO during our Black Friday Sale! »

Clojure: Return of the Jedi

Clojure: Return of the Jedi

My Clojure presentation from OpenFest 2012

Efd2550fb5f3059d815e731ecd61b701?s=128

Bozhidar Batsov

November 03, 2012
Tweet

Transcript

  1. Episode VI: Clojure Завръщането на Джедаите Saturday, November 3, 12

  2. Saturday, November 3, 12

  3. bozhidar user> (:twitter bozhidar) "@bbatsov" user> (bozhidar :blog) "http://batsov.com" user>

    (:github bozhidar) "http://github.com/bbatsov" Saturday, November 3, 12
  4. http://tradeo.com Saturday, November 3, 12

  5. Saturday, November 3, 12

  6. @emacs_knight Saturday, November 3, 12

  7. Мечки Saturday, November 3, 12

  8. Мечка Saturday, November 3, 12

  9. Мечка и Компютър Saturday, November 3, 12

  10. Защо съм тук? Saturday, November 3, 12

  11. Програмистите са идиоти! Saturday, November 3, 12

  12. Затънали сме до уши в калта наречена “инцидентна сложност” и

    въобще не си даваме сметка за това... Saturday, November 3, 12
  13. public boolean hasUpperCase(String word) { if (word == null) {

    return false; } int len = word.length(); for (int i = 0; i < len; i++) { if (Character.isUpperCase(word.charAt(i))) { return true; } } return false; } (defn has-uppercase? [string] (some #(Character/isUpperCase %) string)) Saturday, November 3, 12
  14. Новото е добре забравено старо. Saturday, November 3, 12

  15. Конвенционален език за програмиране Saturday, November 3, 12

  16. Читав език за програмиране Saturday, November 3, 12

  17. Функционален език за програмиране Saturday, November 3, 12

  18. Common Lisp Saturday, November 3, 12

  19. Clojure Saturday, November 3, 12

  20. Lisp Saturday, November 3, 12

  21. Saturday, November 3, 12

  22. Магията на Lisp • Половин вековна история • Често имитиран,

    вечно ненадминат • Изключително малко ядро • Почти никакъв синтаксис • “Кодът е данни” (code is data) • Интерактивно програмиране Saturday, November 3, 12
  23. Проблемите на Lisp (Common Lisp/Scheme) • Никаква иновация след стандартизирането

    им • Сегментация • Думата “едновременно” (concurrently) не се споменава в спецификациите им • Повечето Lisp-ове дефинират сами своята платформа Saturday, November 3, 12
  24. Истинските мъже не ги е страх от малко скоби! Saturday,

    November 3, 12
  25. Хората имат неприятния навик да бъркат думите “познато” и “интуитивно”.

    Saturday, November 3, 12
  26. "We were after the C++ programmers. We managed to drag

    a lot of them about halfway to Lisp." Saturday, November 3, 12
  27. Ruby was a Lisp originally, in theory. “Ruby was a

    Lisp originally, in theory.” Saturday, November 3, 12
  28. Голяма част от езиците, които стават за нещо са повлияни

    пряко или косвено от Lisp!!! Saturday, November 3, 12
  29. ФАКТ! Saturday, November 3, 12

  30. A language that doesn’t affect the way you think about

    programming is not worth knowing. Saturday, November 3, 12
  31. Clojure Saturday, November 3, 12

  32. Есенцията • Динамичен език за програмиране • JVM/CLR/JavaScript • Модерен

    диалеакт на Lisp (1) • Функционален по практичен начин • Оптимизиран за паралелно програмиране • Борец за един по-прост свят Saturday, November 3, 12
  33. Еволюцията на Lisp • сбогом car & cdr (hello first

    & rest) • по-малко скоби • повече структури от данни с literal синтаксис (set, map, vector) • коварно бърз runtime • стандартизиран runtime • непроменими (immutable) структури данни Saturday, November 3, 12
  34. (hello clojure) (defn hello-world [] (println "Hello, world!")) (defn hello

    [name] (println (format "Hello, %s!" name))) Saturday, November 3, 12
  35. user> (hello-world) Hello, world! nil user> (hello "Bozhidar") Hello, Bozhidar!

    nil Saturday, November 3, 12
  36. Lisp programmers know the value of everything, but the cost

    of nothing. Saturday, November 3, 12
  37. Структури от данни • свързан списък (list) • множество (set)

    • вектор • асоциативен масив (map/dictionary) • всичко Джавешко и родно Saturday, November 3, 12
  38. Списък Saturday, November 3, 12

  39. user> (list 1 2 3) (1 2 3) user> '(1

    2 3) (1 2 3) user> (def names '("Bozhidar" "Snezhi" "Batman" "Yoda" "Mike")) #'user/names user> (first names) "Bozhidar" user> (rest names) ("Snezhi" "Batman" "Yoda" "Mike") user> (last names) "Mike" user> (count names) 5 user> (map lower-case names) ("bozhidar" "snezhi" "batman" "yoda" "mike") user> (map count names) (8 6 6 4 4) user> (apply + (map count names)) 28 user> (cons "Pesho" names) ("Pesho" "Bozhidar" "Snezhi" "Batman" "Yoda" "Mike") user> names ("Bozhidar" "Snezhi" "Batman" "Yoda" "Mike") user> (conj names "Pesho") ("Pesho" "Bozhidar" "Snezhi" "Batman" "Yoda" "Mike") Saturday, November 3, 12
  40. Mutable state is the new spaghetti code. Saturday, November 3,

    12
  41. user> (filter even? (range 1 10)) (2 4 6 8)

    user> (every? even? (range 1 10)) false user> (every? even? (filter even? (range 1 10))) true user> (map #(+ % 5) (range 1 10)) (6 7 8 9 10 11 12 13 14) user> (map (partial + 5) (range 1 10)) (6 7 8 9 10 11 12 13 14) user> (map (comp (partial * 2) (partial + 5)) (range 1 10)) (12 14 16 18 20 22 24 26 28) Saturday, November 3, 12
  42. user> (doc and) ------------------------- clojure.core/and ([] [x] [x & next])

    Macro Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true. nil user> (source and) (defmacro and "Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true." {:added "1.0"} ([] true) ([x] x) ([x & next] `(let [and# ~x] (if and# (and ~@next) and#)))) nil Saturday, November 3, 12
  43. Множество (Set) Saturday, November 3, 12

  44. user> (set '(1 1 2 2 3 3)) #{1 2

    3} user> (def a-set #{1 2 3 4 5}) #'user/a-set user> (contains? a-set 3) true user> (contains? a-set 9) false user> (conj a-set 5) #{1 2 3 4 5} user> (conj a-set 6) #{1 2 3 4 5 6} user> (use 'clojure.set) nil user> (intersection #{1 2 3} #{2 3 4}) #{2 3} user> (difference #{1 2 3} #{2 3 4}) #{1} user> (union #{1 2 3} #{2 3 4}) #{1 2 3 4} Saturday, November 3, 12
  45. Асоциативен масив (Map) Saturday, November 3, 12

  46. user> (hash-map 1 2 3 4) {1 2, 3 4}

    user> (hash-map "Batman" "Bruce Wayne" "Superman" "Clark Kent") {"Batman" "Bruce Wayne", "Superman" "Clark Kent"} user> {:batman "Bruce Wayne", :superman "Clark Kent"} {:superman "Clark Kent", :batman "Bruce Wayne"} user> (def a-map {:batman "Bruce Wayne", :superman "Clark Kent"}) #'user/a-map user> (:superman a-map) "Clark Kent" user> (a-map :batman) "Bruce Wayne" user> (a-map :zorro) nil user> (merge a-map {:zorro "Diego de la Vega"}) {:superman "Clark Kent", :batman "Bruce Wayne", :zorro "Diego de la Vega"} user> a-map {:superman "Clark Kent", :batman "Bruce Wayne"} user> (contains? a-map :batman) true user> (assoc a-map :catwoman "Selina Kyle") {:superman "Clark Kent", :batman "Bruce Wayne", :catwoman "Selina Kyle"} user> a-map {:superman "Clark Kent", :batman "Bruce Wayne"} user> (dissoc a-map :batman) {:superman "Clark Kent"} user> a-map {:superman "Clark Kent", :batman "Bruce Wayne"} Saturday, November 3, 12
  47. Вектор (Vector) Saturday, November 3, 12

  48. user> (vector 1 2 3 4) [1 2 3 4]

    user> (into [] '(1 2 3 4)) [1 2 3 4] user> (def v (into [] (range 1 5))) #'user/v user> (count v) 4 user> (nth v 0) 1 user> (conj v 5) [1 2 3 4 5] user> (pop v) [1 2 3] user> (peek v) 4 user> [1 2 3 4] [1 2 3 4] Saturday, November 3, 12
  49. Seq API Saturday, November 3, 12

  50. Идентичност и състояние Saturday, November 3, 12

  51. Паралелно програмиране Saturday, November 3, 12

  52. Законът на Мур даде фира в последните години Saturday, November

    3, 12
  53. Процесорите днес са масово многоядрени. Saturday, November 3, 12

  54. Програмистите днес пишат масово single- threaded(process) софтуер! Saturday, November 3,

    12
  55. Защо така бе, юнаци? Saturday, November 3, 12

  56. Програмистите са идиоти! Saturday, November 3, 12

  57. Сложно паралелното програмиране е! Saturday, November 3, 12

  58. Първи стъпки Saturday, November 3, 12

  59. user> (def f (future (Thread/sleep 10000) (println "done") 100)) #'user/f

    user> f #<core$future_call$reify__5684@201075c5: :pending> user> @f done 100 user> @f 100 user> (def my-delay (delay (println "did some work") 100)) #'user/my-delay user> @my-delay did some work 100 user> @my-delay 100 Saturday, November 3, 12
  60. Паралелни операции върху колекции Saturday, November 3, 12

  61. user> (defn slow-op [n] (Thread/sleep 5000) n) #'user/slow-op user> (map

    slow-op (range 1 5)) (1 2 3 4) user> (time (doall (map slow-op (range 1 5)))) "Elapsed time: 20004.081 msecs" (1 2 3 4) user> (time (doall (pmap slow-op (range 1 5)))) "Elapsed time: 5002.705 msecs" (1 2 3 4) Saturday, November 3, 12
  62. Refs Saturday, November 3, 12

  63. (def picked-numbers (ref #{})) (def secret-num (.nextInt (java.util.Random.) 10)) (defn

    guess-number [n] (print "Enter a guess between 1 and 10: ") (flush) (let [guess (java.lang.Integer/parseInt (read-line)) ] (cond (= guess n) (println "You guessed correctly") (contains? (deref picked-numbers) n) (println "Pick another number!") :else (dosync (alter picked-numbers conj guess))))) Saturday, November 3, 12
  64. user> (guess-number secret-num) Enter a guess between 1 and 10:

    1 #{1} user> (guess-number secret-num) Enter a guess between 1 and 10: 2 #{1 2} user> (guess-number secret-num) Enter a guess between 1 and 10: 3 #{1 2 3} ... user> (guess-number secret-num) Enter a guess between 1 and 10: 7 #{1 2 3 4 5 6 7} user> (guess-number secret-num) Enter a guess between 1 and 10: 8 #{1 2 3 4 5 6 7 8} user> (guess-number secret-num) Enter a guess between 1 and 10: 9 You guessed correctly Saturday, November 3, 12
  65. Atoms Saturday, November 3, 12

  66. (def picked-numbers (atom #{})) (def secret-num (.nextInt (java.util.Random.) 10)) (defn

    guess-number [n] (print "Enter a guess between 1 and 10: ") (flush) (let [guess (java.lang.Integer/parseInt (read-line)) ] (cond (= guess n) (println "You guessed correctly") (contains? (deref picked-numbers) n) (println "Pick another number!") :else (swap! picked-numbers conj guess)))) Saturday, November 3, 12
  67. Agents Saturday, November 3, 12

  68. user> (def some-agent (agent 0)) #'user/some-agent user> (dotimes [i 100]

    (send some-agent inc)) nil user> some-agent #<Agent@1997c457: 100> user> @some-agent 100 Saturday, November 3, 12
  69. Time is the new memory. Saturday, November 3, 12

  70. Звучи добре, ама дали ще я бъде тая работа? •

    Добри програмисти се изнасят на талази към Clojure • O’Reilly издадоха книга за Clojure!!! • Thoughtbot съветва компаниите да залагат на Clojure Saturday, November 3, 12
  71. Инструменти за масово разрушение • Leiningen 2 • Emacs •

    clojure-mode • paredit • nrepl.el Saturday, November 3, 12
  72. Emacs Prelude включва всичко, което ви трябва да програмирате на

    Clojure https://github.com/bbatsov/prelude Saturday, November 3, 12
  73. Противотанкова артилерия • Eclipse (CounterClockWise) • IntelliJ IDEA (LaClojure) •

    NetBeans (Enclojure) Saturday, November 3, 12
  74. http://clojurekoans.org Saturday, November 3, 12

  75. Алтернативите Saturday, November 3, 12

  76. Simplicity is the ultimate sophistication. Leonardo Da Vinci Saturday, November

    3, 12
  77. Конец Saturday, November 3, 12

  78. Въпроси? Saturday, November 3, 12