Clojure: Return of the Jedi

Post on 27-Jun-2015

747 views 1 download

Tags:

description

My Clojure presentation from OpenFest 2012

transcript

Episode VI:Clojure

Завръщането на Джедаите

Saturday, November 3, 12

Saturday, November 3, 12

bozhidar

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

Saturday, November 3, 12

http://tradeo.comSaturday, November 3, 12

Saturday, November 3, 12

@emacs_knightSaturday, November 3, 12

МечкиSaturday, November 3, 12

МечкаSaturday, November 3, 12

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

Защо съм тук?

Saturday, November 3, 12

Програмистите са идиоти!

Saturday, November 3, 12

Затънали сме до уши в калта наречена

“инцидентна сложност” и въобще не си даваме сметка за това...

Saturday, November 3, 12

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

Новото е добре забравено старо.

Saturday, November 3, 12

Конвенционален език за програмиране

Saturday, November 3, 12

Читав език за програмиране

Saturday, November 3, 12

Функционален език за програмиране

Saturday, November 3, 12

Common LispSaturday, November 3, 12

ClojureSaturday, November 3, 12

Lisp

Saturday, November 3, 12

Saturday, November 3, 12

Магията на Lisp

• Половин вековна история• Често имитиран, вечно ненадминат• Изключително малко ядро• Почти никакъв синтаксис• “Кодът е данни” (code is data)

• Интерактивно програмиране

Saturday, November 3, 12

Проблемите на Lisp (Common Lisp/Scheme)• Никаква иновация след стандартизирането им

• Сегментация• Думата “едновременно” (concurrently) не се споменава в спецификациите им

• Повечето Lisp-ове дефинират сами своята платформа

Saturday, November 3, 12

Истинските мъже не ги е страх от малко скоби!

Saturday, November 3, 12

Хората имат неприятния навик да бъркат думите “познато” и

“интуитивно”.

Saturday, November 3, 12

"We were after the C++ programmers. We managed to drag a lot of them about

halfway to Lisp."

Saturday, November 3, 12

Ruby was a Lisp originally, in theory.

“Ruby was a Lisp originally, in theory.”

Saturday, November 3, 12

Голяма част от езиците, които стават за нещо са повлияни пряко или косвено от

Lisp!!!

Saturday, November 3, 12

ФАКТ!

Saturday, November 3, 12

A language that doesn’t affect the way you think about programming is not worth

knowing.

Saturday, November 3, 12

ClojureSaturday, November 3, 12

Есенцията

• Динамичен език за програмиране• JVM/CLR/JavaScript

• Модерен диалеакт на Lisp (1)

• Функционален по практичен начин• Оптимизиран за паралелно програмиране• Борец за един по-прост свят

Saturday, November 3, 12

Еволюцията на Lisp

• сбогом car & cdr (hello first & rest)

• по-малко скоби• повече структури от данни с literal синтаксис (set, map, vector)

• коварно бърз runtime

• стандартизиран runtime

• непроменими (immutable) структури данни

Saturday, November 3, 12

(hello clojure)

(defn hello-world [] (println "Hello, world!"))

(defn hello [name] (println (format "Hello, %s!" name)))

Saturday, November 3, 12

user> (hello-world)Hello, world!niluser> (hello "Bozhidar")Hello, Bozhidar!nil

Saturday, November 3, 12

Lisp programmers know the value of everything, but the cost of nothing.

Saturday, November 3, 12

Структури от данни

• свързан списък (list)• множество (set)

• вектор • асоциативен масив (map/dictionary)

• всичко Джавешко и родно

Saturday, November 3, 12

СписъкSaturday, November 3, 12

user> (list 1 2 3)(1 2 3)user> '(1 2 3)(1 2 3)user> (def names '("Bozhidar" "Snezhi" "Batman" "Yoda" "Mike"))#'user/namesuser> (first names)"Bozhidar"user> (rest names)("Snezhi" "Batman" "Yoda" "Mike")user> (last names)"Mike"user> (count names)5user> (map lower-case names)("bozhidar" "snezhi" "batman" "yoda" "mike")user> (map count names)(8 6 6 4 4)user> (apply + (map count names))28user> (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

Mutable state is the new spaghetti code.

Saturday, November 3, 12

user> (filter even? (range 1 10))(2 4 6 8)user> (every? even? (range 1 10))falseuser> (every? even? (filter even? (range 1 10)))trueuser> (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

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.niluser> (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

Множество(Set)

Saturday, November 3, 12

user> (set '(1 1 2 2 3 3))#{1 2 3}user> (def a-set #{1 2 3 4 5})#'user/a-setuser> (contains? a-set 3)trueuser> (contains? a-set 9)falseuser> (conj a-set 5)#{1 2 3 4 5}user> (conj a-set 6)#{1 2 3 4 5 6}user> (use 'clojure.set)niluser> (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

Асоциативен масив(Map)

Saturday, November 3, 12

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-mapuser> (:superman a-map)"Clark Kent"user> (a-map :batman)"Bruce Wayne"user> (a-map :zorro)niluser> (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)trueuser> (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

Вектор(Vector)

Saturday, November 3, 12

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/vuser> (count v)4user> (nth v 0)1user> (conj v 5)[1 2 3 4 5]user> (pop v)[1 2 3]user> (peek v)4user> [1 2 3 4][1 2 3 4]

Saturday, November 3, 12

Seq API

Saturday, November 3, 12

Идентичност и състояние

Saturday, November 3, 12

Паралелно програмиране

Saturday, November 3, 12

Законът на Мур даде фира в последните

години

Saturday, November 3, 12

Процесорите днес са масово многоядрени.

Saturday, November 3, 12

Програмистите днес пишат масово single-

threaded(process) софтуер!

Saturday, November 3, 12

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

Програмистите са идиоти!

Saturday, November 3, 12

Сложно паралелното програмиране е!

Saturday, November 3, 12

Първи стъпки

Saturday, November 3, 12

user> (def f (future (Thread/sleep 10000) (println "done") 100))#'user/fuser> f#<core$future_call$reify__5684@201075c5: :pending>user> @fdone

100user> @f100user> (def my-delay (delay (println "did some work") 100))#'user/my-delayuser> @my-delaydid some work100user> @my-delay100

Saturday, November 3, 12

Паралелни операции върху колекции

Saturday, November 3, 12

user> (defn slow-op [n] (Thread/sleep 5000) n)#'user/slow-opuser> (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

Refs

Saturday, November 3, 12

(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

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: 9You guessed correctly

Saturday, November 3, 12

Atoms

Saturday, November 3, 12

(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

Agents

Saturday, November 3, 12

user> (def some-agent (agent 0))#'user/some-agentuser> (dotimes [i 100] (send some-agent inc))niluser> some-agent#<Agent@1997c457: 100>user> @some-agent100

Saturday, November 3, 12

Time is the new memory.Saturday, November 3, 12

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

• Добри програмисти се изнасят на талази към Clojure

• O’Reilly издадоха книга за Clojure!!!

• Thoughtbot съветва компаниите да залагат на Clojure

Saturday, November 3, 12

Инструменти за масово разрушение

• Leiningen 2

• Emacs

• clojure-mode

• paredit

• nrepl.el

Saturday, November 3, 12

Emacs Prelude включва всичко, което ви трябва да програмирате на Clojure

https://github.com/bbatsov/prelude

Saturday, November 3, 12

Противотанкова артилерия

• Eclipse (CounterClockWise)

• IntelliJ IDEA (LaClojure)

• NetBeans (Enclojure)

Saturday, November 3, 12

http://clojurekoans.orgSaturday, November 3, 12

Алтернативите

Saturday, November 3, 12

Simplicity is the ultimate sophistication.

Leonardo Da Vinci

Saturday, November 3, 12

Конец

Saturday, November 3, 12

Въпроси?

Saturday, November 3, 12