Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Clojure for PHP Developers
Ian Barber
May 25, 2012
Technology
6
1.6k
Clojure for PHP Developers
My introduction to Clojure from PHP Tek 12 #tek12
Ian Barber
May 25, 2012
Tweet
Share
More Decks by Ian Barber
See All by Ian Barber
Crossing Platforms With Google+ Sign-In
ianbarber
0
110
How Google Builds Webservices
ianbarber
3
270
Mobile & Social
ianbarber
2
110
Event Stream Processing In PHP
ianbarber
7
2.1k
Building A Firehose - PHPNW
ianbarber
2
650
Building a Firehose
ianbarber
5
970
Taking Sites Mobile
ianbarber
1
340
The Cookie Law
ianbarber
1
630
Teaching Your Machine To Find Fraudsters
ianbarber
3
710
Other Decks in Technology
See All in Technology
SRENEXT2022 組織にSREを実装していくまでの道のり
marnie0301
1
730
我々はなぜテストをするのか?
kawaguti
PRO
0
590
Stripe Search APIを利用した、LINEとStripeの顧客情報連携/line-dc-202205
stripehideokamoto
0
130
srenext2022-skaru
mixi_engineers
PRO
1
940
失敗を経験したあなたへ〜建設的なインシデントの振り返りを行うために実践するべきこと〜
nobuakikikuchi
0
210
Scrum Fest Niigata 2022 開発エンジニアに聞いてみよう!
moritamasami
1
620
⚡Lightdashを試してみた
k_data_analyst
0
220
CAMのサービス開発の歴史と共通基盤を使った 開発スタイルへの変遷について
ishikawa_pro
0
110
[AKIBA.AWS] それ、t2.micro選んで大丈夫?
tsukuboshi
0
380
[SRE NEXT 2022]KaaS桶狭間の戦い 〜Yahoo! JAPANのSLI/SLOを用いた統合監視〜
srenext
0
570
A1A会社紹介資料-2022-05-20
a1a
2
1.1k
Data-Driven Healthcare - Techplay
kotaroito
0
120
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
86
12k
Mobile First: as difficult as doing things right
swwweet
213
7.5k
Embracing the Ebb and Flow
colly
73
3.3k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
498
130k
Building an army of robots
kneath
299
40k
YesSQL, Process and Tooling at Scale
rocio
157
12k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
19
1.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
25
1.5k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_i
21
14k
Debugging Ruby Performance
tmm1
65
10k
Stop Working from a Prison Cell
hatefulcrawdad
261
17k
JazzCon 2018 Closing Keynote - Leadership for the Reluctant Leader
reverentgeek
172
8.3k
Transcript
ian barber - ianb@php.net - @ianbarber CLOJURE FOR PHP DEVELOPERS
WHAT IS CLOJURE AND WHAT IS IT GOOD FOR?
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
SEQUENCES CONCURRENCY WITH STM REPL $ lein repl REPL started;
user=>
READ EVALUATE PRINT LOOP
(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
/* 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) ); }
/* 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) ); }
/* 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) ] )
(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) ] )
(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));
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"))
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)
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"
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"
CONCURRENCY WITH STM ? CORE CORE CORE CORE
CONCURRENCY WITH STM A 1 A 2 A 3 A
4 STATE IDENTITY
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}
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
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)} )
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"
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
(defpage [:post "/verbatim"] {text :text :or {text ""}} (if (blank?
text) (resp/json {:error "Invalid Input"}) (resp/json {:tagged (tagger (tokeniser 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"],["?","."]]}
(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)))))
http://clojure.org/ WHERE TO GO NEXT? http://blip.tv/clojure
ian barber - ianb@php.net - @ianbarber THANKS!
http://flickr.com/photos/usarmyafrica/4456204113 http://flickr.com/photos/puliarfanita/6648892997 IMAGE CREDITS