Slide 1

Slide 1 text

ian barber - [email protected] - @ianbarber CLOJURE FOR PHP DEVELOPERS

Slide 2

Slide 2 text

WHAT IS CLOJURE AND WHAT IS IT GOOD FOR?

Slide 3

Slide 3 text

INSTALLING CLOJURE mac osx $ brew install rlwrap leiningen debian / ubtuntu $ apt-get install leiningen windows https://github.com/technomancy/leiningen http://dev.clojure.org/display/doc/Getting+Started

Slide 4

Slide 4 text

SEQUENCES CONCURRENCY WITH STM REPL $ lein repl REPL started; user=>

Slide 5

Slide 5 text

READ EVALUATE PRINT LOOP

Slide 6

Slide 6 text

(ns boids.core (:use [quil.core])) (def wwidth 646) ; Map width (def wheight 400) ; Map height (def avoid-dist 20) ; Stay this far apart (def col-dist 35) ; Avoid columns (def col-size 30) ; Column size (def infl-dist 100) ; Boids influence (def boid-count 50) ; How many boids (def boid-diam 5) ; Size of a boid (def max-speed 6) ; Boid max speed https://github.com/ianbarber/Boids

Slide 7

Slide 7 text

/* Head towards the rest of the boids */ function attract($x, $y, $boids) { $cboids = closest($x, $y, $boids, 100); $boid_count = count($boids) == 0 ? count($boids) : 1; $sum_x = $sum_y = 0; foreach ($cboids as $boid) { $sum_x += $boid['x']; $sum_y += $boid['y']; } $x_average = $sum_x / $boid_count; $y_average = $sum_y / $boid_count; return array( ($x_average - $x), ($y_average - $y) ); }

Slide 8

Slide 8 text

/* Head towards the rest of the boids */ defn attract(x, y, boids) { cboids = closest(x, y, boids, 100); boid_count = count(boids) == 0 ? count(boids) : 1; sum_x = sum_y = 0; foreach (cboids as boid) { sum_x += boid['x']; sum_y += boid['y']; } x_average = sum_x / boid_count; y_average = sum_y / boid_count; return array( (x_average - x), (y_average - y) ); }

Slide 9

Slide 9 text

/* Head towards the rest of the boids */ (defn attract [x y boids] cboids = (closest x y boids 100) boid_count = (count boids) == 0 ? (count boids) : 1 sum_x = sum_y = 0 foreach (cboids as boid) { sum_x += (:x boid) sum_y += (:y boid) } x_average = (/ sum_x boid_count) y_average = (/ sum_y boid_count) [ (- x_average x) (- y_average y) ] )

Slide 10

Slide 10 text

(defn attract "Head towards the rest of the boids" [x y boids] (let [ cboids (closest x y boids 100) boid_count (if (= 0 (count boids)) 0 (count boids)) [sum_x sum_y] foreach (cboids as boid){ sum_x += (:x boid) sum_y += (:y boid) } x_average] (/ sum_x boid_count) y_average (/ sum_y boid_count) ] [ (- x_average x) (- y_average y) ] )

Slide 11

Slide 11 text

(let [ [sum_x sum_y] (reduce (fn [[sum_x sum_y] boid] [(+ sum_x (:x boid)) (+ sum_y (:y boid))] [0 0] cboids) ]) list($sum_x, $sum_y) = array_reduce($cboids, function($boid, $sum) { return array( $sum[0] + $boid['x'], $sum[1] + $boid['y']); }, array(0,0));

Slide 12

Slide 12 text

UNIT TESTING (ns boids.test.core (:use [boids.core] :reload) (:use [clojure.test])) (deftest test-create-boid (is (= 10 (:x (create-boid 10 0 0 0 []))) "Create boid does not include x val")) (deftest test-close-boids (is (= 1 (count (close-boids 60 60 #{(create-boid 80 30 10 10 [])} 100 ))) "Close boids does not include expected"))

Slide 13

Slide 13 text

SEQUENCES Refs Atomics Agents (first '(1 2 3)) ;; 1 (nth [1 2 3] 1) ;; 2 (first {:a 1 :b 2 :c 3}) ;; [:a 1] (rest #{:a :b :c}) ;; (:c :b) (defn fib [a b] (lazy-seq (cons a (fib b (+ b a))))) ;; #'user/fib (take 5 (fib 1 1)) ;; (1 1 2 3 5)

Slide 14

Slide 14 text

INFINITE SEQUNCES (def users (cycle [1 2 3 4 5])) (defn slow-search [user] (Thread/sleep 1000) (println "Loop") (if (> (rand-int 4) 1) true false)) (def immediate-user (first (filter slow-search users))) ;; Loops 6 times (time (print immediate-user)) (2)"Elapsed time: 0.119 msecs"

Slide 15

Slide 15 text

DELAYED EXECUTION (def lazy-user (take 1 (filter slow-search users))) ;; Immediate return (time (print lazy-user)) ;; Loops 6 times (1) "Elapsed time: 5018.576 msecs" (time (print lazy-user)) (1)"Elapsed time: 0.185 msecs"

Slide 16

Slide 16 text

CONCURRENCY WITH STM ? CORE CORE CORE CORE

Slide 17

Slide 17 text

CONCURRENCY WITH STM A 1 A 2 A 3 A 4 STATE IDENTITY

Slide 18

Slide 18 text

Refs Atomics Agents (defn updateit [] (swap! mystate assoc :punctuation "!")) (def mystate (atom {:name "hello" :value "world"})) (let [foo @mystate] (future (updateit)) (println foo) (println @mystate) (Thread/sleep 1000) (println foo) (println @mystate)) {:name hello, :value world} {:name hello, :value world} {:name hello, :value world} {:punctuation !, :name hello, :value world}

Slide 19

Slide 19 text

STM - REFS Refs Atomics Agents (def ted (ref 0)) (def bob (ref 0)) (defn pickup [user gold] (dosync (commute user + gold))) (defn transfer [from to gold] (dosync (if (> (deref from) gold) (do (alter from - gold) (alter to + gold)) false))) (pickup ted 100) (pickup bob 20) (transfer bob ted 25) ; false (transfer bob ted 19) ; 120 / 1

Slide 20

Slide 20 text

STM - AGENTS (def boids (take 5 (repeatedly #(agent {:x (rand-int 100) :y (rand-int 100)})))) (defn getav [dim b] (int (/ (reduce + (map dim b)) (count b))) ) (defn behave [boid boids] (Thread/sleep 5000) {:x (getav :x boids) :y (getav :y boids)} )

Slide 21

Slide 21 text

STM - AGENTS (doseq [boid boids] (send boid behave (remove #(= @boid %) (map deref boids)))) (time (apply await boids)) ;; "Elapsed time: 9997.488 msecs" (doseq [boid boids] (send-off boid behave (remove #(= @boid %) (map deref boids)))) (time (apply await boids)) ;; "Elapsed time: 4979.295 msecs"

Slide 22

Slide 22 text

LEIN PROJECT FILE (defproject textapp "0.1.0-SNAPSHOT" :description "Simple text analysis rest service" :dependencies [ [org.clojure/clojure "1.3.0"] [clojure-opennlp "0.1.9"] [noir "1.2.1"]] :main textapp.server) https://github.com/ianbarber/Textservice $ lein noir new textapp

Slide 23

Slide 23 text

(defpage [:post "/verbatim"] {text :text :or {text ""}} (if (blank? text) (resp/json {:error "Invalid Input"}) (resp/json {:tagged (tagger (tokeniser text))} )))

Slide 24

Slide 24 text

CALL FROM CURL $ curl -X POST http://localhost:8080/ verbatim -d "text=Hello+world+how+are +things+with+you?" {"tagged":[["Hello","UH"],["world","NN"], ["how","WRB"],["are","VBP"], ["things","NNS"],["with","IN"], ["you","PRP"],["?","."]]}

Slide 25

Slide 25 text

(defmethod make-pos-tagger POSModel [model] (fn pos-tagger [tokens] (let [ token-array (into-array tokens) tagger (POSTaggerME. model *beam-size*) tags (.tag tagger token-array) ] (with-meta (map vector tokens tags)))))

Slide 26

Slide 26 text

http://clojure.org/ WHERE TO GO NEXT? http://blip.tv/clojure

Slide 27

Slide 27 text

ian barber - [email protected] - @ianbarber THANKS!

Slide 28

Slide 28 text

http://flickr.com/photos/usarmyafrica/4456204113 http://flickr.com/photos/puliarfanita/6648892997 IMAGE CREDITS