Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Clojure for PHP Developers
Search
Ian Barber
May 25, 2012
Technology
6
1.9k
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
150
How Google Builds Webservices
ianbarber
3
340
Mobile & Social
ianbarber
2
180
Event Stream Processing In PHP
ianbarber
7
2.4k
Building A Firehose - PHPNW
ianbarber
2
950
Building a Firehose
ianbarber
5
1.4k
Taking Sites Mobile
ianbarber
1
580
The Cookie Law
ianbarber
1
940
Teaching Your Machine To Find Fraudsters
ianbarber
3
1k
Other Decks in Technology
See All in Technology
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
8
65k
JNation 2025 - Quarkus for Spring Developers
edeandrea
PRO
0
100
データ戦略部門 紹介資料
sansan33
PRO
1
3.1k
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
3
1.5k
SmartHRの複数のチームにおけるMCPサーバーの活用事例と課題
yukisnow1823
2
1k
フロントエンドがTypeScriptなら、バックエンドはPHPでもいいじゃない/php-is-not-bad
hanhan1978
8
12k
“新卒らしさ”を脱ぎ捨てて 〜1年を経て学んだこと〜
rebase_engineering
0
120
会社員しながら本を書いてきた知見の共有
sat
PRO
3
670
declaration mergingの威力:ライブラリアップデート時の書き換え作業を90%短縮するテクニック
yutake27
2
270
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.2k
Node−RED で Ollama を使ったローカルLLM(node-red-contrib-ollamaを利用) / ビジュアルプログラミングIoTLT vol.20
you
PRO
0
130
それでもぼくらは貢献をつづけるのだ(たぶん) @FOSS4GLT会#002
furukawayasuto
1
260
Featured
See All Featured
Adopting Sorbet at Scale
ufuk
76
9.4k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
42
2.3k
How to Think Like a Performance Engineer
csswizardry
23
1.6k
GitHub's CSS Performance
jonrohan
1031
460k
We Have a Design System, Now What?
morganepeng
52
7.6k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
GraphQLとの向き合い方2022年版
quramy
46
14k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
Embracing the Ebb and Flow
colly
85
4.7k
The World Runs on Bad Software
bkeepers
PRO
68
11k
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