Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
esm lt Clojure like threading macro
Search
kunou
October 11, 2016
Technology
470
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
esm lt Clojure like threading macro
kunou
October 11, 2016
More Decks by kunou
See All by kunou
GANについて
kunou
0
460
AIか何かについて.pdf
kunou
0
49
Pythonを書いていておーマジかーと感じたあれこれ
kunou
1
740
ネットワークグラフを作成する
kunou
0
75
Rubyで機械学習してみた
kunou
1
1.2k
ZIP!!
kunou
0
200
zip
kunou
0
530
Make Mouse
kunou
0
670
RubyのProcのあれをこうしました
kunou
0
110
Other Decks in Technology
See All in Technology
品質と信頼性を地続きにする
grimoh
2
1k
Coil3を内部実装から読み解く~キャッシュ戦略とAVIF画像の描画〜/nikkei-tech-talk50
nikkei_engineer_recruiting
0
100
その Lambda、8分で 管理者権限まで奪われます
k1nakayama
7
3.7k
.NET WebAssemblyで実現するクライアントサイドAI推論:NuGetからViteまで、2つのエコシステムを繋ぐビルド戦略
yamachu
1
870
AIに賢く動いてもらうためのコンテキスト〜Snowflake女子会 vol.8
snowwmn0824
0
180
Kiro Meetup #8 Kiro アップデート (2026/3/21〜2026/9/24)
katzueno
1
240
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
12k
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
540
人にやさしく、AIにやさしく、書き手を選ばないIaCのガードレール再考 / Rethinking IaC Guardrails for Humans and AI Alike
kohbis
5
1.2k
CI/CDではもう遅い - 人とAIが迂回しないDevSecOps Verify基盤の再設計 -
kintotechdev
1
270
JSONataとAWS Step Functionsで目指すRuntimelessな世界
mu7889yoon
1
510
データ_AIの事業の勝敗をわけるもの
nek0128
1
480
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
680
The Invisible Side of Design
smashingmag
301
52k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
950
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Bash Introduction
62gerente
615
220k
Documentation Writing (for coders)
carmenintech
77
5.5k
Being A Developer After 40
akosma
91
590k
Building Adaptive Systems
keathley
44
3.2k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Automating Front-end Workflow
addyosmani
1369
210k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Transcript
Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨ ʹ͍ͭͯ esm LT 2016/10/07
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ࣗݾհ ▸ ٱೲ ▸ 2006ೖࣾ ▸ ITαʔϏεࣄۀ෦
Clojure ▸ Clojure (ൃԻ/'klouʒər/[2], Ϋϩʔδϟʔ)ϓϩάϥϛϯάݴ ޠͰ͋ΓɺLISPܥͷݴޠͷํݴͷҰͭͰ͋Δɻؔܕϓϩάϥ ϛϯάͷϓϩάϥϛϯάελΠϧͰͷΠϯλϥΫςΟϒͳ։ൃ Λࢧԉ͠ɺϚϧνεϨουϓϩάϥϜͷ։ൃΛ༰қԽ͢Δ൚༻ ݴޠͰ͋ΔɻClojureݴޠͷϓϩάϥϜJavaԾϚγϯͱ Microsoft
.NET ڞ௨ݴޠϥϯλΠϜͰಈ࡞͢ΔɻClojureݴޠ ʮσʔλͱͯ͠ͷϓϩάϥϜίʔυʯ (ӳޠ:ʮcode as dataʯ) ͱ͍͏ࢥͰઃܭ͞Ε͓ͯΓɺચ࿅͞ΕͨϚΫϩػߏΛ࣋ͭɻ ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ WikipediaΑΓ
Clojure ▸ Clojure (ൃԻ/'klouʒər/[2], Ϋϩʔδϟʔ)ϓϩάϥϛϯάݴ ޠͰ͋ΓɺLISPܥͷݴޠͷํݴͷҰͭͰ͋Δɻؔܕϓϩάϥ ϛϯάͷϓϩάϥϛϯάελΠϧͰͷΠϯλϥΫςΟϒͳ։ൃ Λࢧԉ͠ɺϚϧνεϨουϓϩάϥϜͷ։ൃΛ༰қԽ͢Δ൚༻ ݴޠͰ͋ΔɻClojureݴޠͷϓϩάϥϜJavaԾϚγϯͱ Microsoft
.NET ڞ௨ݴޠϥϯλΠϜͰಈ࡞͢ΔɻClojureݴޠ ʮσʔλͱͯ͠ͷϓϩάϥϜίʔυʯ (ӳޠ:ʮcode as dataʯ) ͱ͍͏ࢥͰઃܭ͞Ε͓ͯΓɺચ࿅͞ΕͨϚΫϩػߏΛ࣋ͭɻ ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ WikipediaΑΓ
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2)
(filter even? [1 2 3 4])))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2)
(filter even? [1 2 3 4]))) こう実行されて
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2)
(filter even? [1 2 3 4]))) ;;=> 112 こうなる
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100)) こう実行されて
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100)) ;;=> 112 こうなる
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͷར εϨοσΟϯάϚΫϩ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100)) SࣜͷΈ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͷར εϨοσΟϯάϚΫϩ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100)) SࣜͷΈ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4]))) スレッディングマクロを使うと 評価の時系列順に上から読むことが出来る
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ଞʹ͋ΔεϨοσΟϯάϚΫϩͷར ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2)
(filter even? [1 2 3 4])))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ଞʹ͋ΔεϨοσΟϯάϚΫϩͷར ClojureͷSࣜͩͱ (reduce + 100 ..(map #(* %1 2)
....(filter even? ......[1 2 3 4]))) インデントはこうなる
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ଞʹ͋ΔεϨοσΟϯάϚΫϩͷར εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ଞʹ͋ΔεϨοσΟϯάϚΫϩͷར εϨοσΟϯάϚΫϩͩͱ (->> ..[1 2 3 4] ..(filter even?)
..(map #(* %1 2)) ..(reduce + 100)) インデントはこうなる
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ଞʹ͋ΔεϨοσΟϯάϚΫϩͷར εϨοσΟϯάϚΫϩ (->> [1 2 3 4] (filter even?)
(map #(* %1 2)) (reduce + 100)) SࣜͷΈ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ଞʹ͋ΔεϨοσΟϯάϚΫϩͷར εϨοσΟϯάϚΫϩ (->> ..[1 2 3 4] ..(filter even?)
..(map #(* %1 2)) ..(reduce + 100)) SࣜͷΈ (reduce + 100 ..(map #(* %1 2) ....(filter even? ......[1 2 3 4]))) コードのインデントが深くならない
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ εϨοσΟϯάϚΫϩͷར 他にも有るけど割愛
Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨ ʹ͍ͭͯ esm LT 2016/10/07
Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨ ʹ͍ͭͯ END esm LT 2016/10/07
Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨ ʹ͍ͭͯ ୈೋ෦ esm LT 2016/10/07
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ RubyͷϥϜμࣜͰSࣜ૬ͷॲཧΛॻ͘ͱ…
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ RubyͷϥϜμࣜͰSࣜ૬ͷॲཧΛॻ͘ͱ… -> (collection) { collection.reduce(100, :+) }. call(-> (collection)
{ collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ RubyͷϥϜμࣜͰSࣜ૬ͷॲཧΛॻ͘ͱ… -> (collection) { collection.reduce(100, :+) }. call(-> (collection)
{ collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4]))) これをスレッディングマクロっぽく 書けるようにする
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ جຊͷΞΠσΟΞ [ -> (collection) { collection.select(&:even?) }, -> (collection)
{ collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) }
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ جຊͷΞΠσΟΞ [ -> (collection) { collection.select(&:even?) }, -> (collection)
{ collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } Procの配列に対して
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ جຊͷΞΠσΟΞ [ -> (collection) { collection.select(&:even?) }, -> (collection)
{ collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } Procの配列に対して reduceして、処理結果に順々に適用する
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ جຊͷΞΠσΟΞ [ -> (collection) { collection.select(&:even?) }, -> (collection)
{ collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } => 112 Procの配列に対して reduceして、処理結果に順々に適用する
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͱΓ͋͑ͣ͜͜·Ͱ࣮ͯ͠ΈΔ def thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }
end
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͱΓ͋͑ͣ͜͜·Ͱ࣮ͯ͠ΈΔ def thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }
end thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } )
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͱΓ͋͑ͣ͜͜·Ͱ࣮ͯ͠ΈΔ def thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }
end thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ) => 112
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͱΓ͋͑ͣ͜͜·Ͱ࣮ͯ͠ΈΔ def thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }
end thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ) => 112 出来た!
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ جຊͷΞΠσΟΞ [ -> (collection) { collection.select(&:even?) }, -> (collection)
{ collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) }
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖Ͳ͏͢Δʁ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) }
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖Ͳ͏͢Δʁ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } nを指定したい
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖Ͳ͏͢Δʁ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } ArgumentError: wrong number of arguments (given 1, expected 2)
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖Ͳ͏͢Δʁ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } ArgumentError: wrong number of arguments (given 1, expected 2) 一つの引数にだけ Procを適用している
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) }
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖͜͏͢Δʂ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) }
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖͜͏͢Δʂ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } => 112
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜Μͳͱ͖͜͏͢Δʂ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) } curryとは?
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏) ΧϦʔԽͱ෦ద༻
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ 関数がただ一つの引数だけをとるようにすること。 この状態の関数をカリー化されていると呼ぶ。 2引数の関数はカリー化することで、引数の数が 一つである関数と、その関数を返す引数の数が一 つの関数に分けられる。
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ Ruby で書くと… ->(x, y) { x +
y }.call(2, 3) => 5
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ Ruby で書くと… ->(x, y) { x +
y }.call(2, 3) => 5 ->(x) { -> (y) { x + y } }.call(2).call(3) => 5 カリー化(手動)
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ Ruby で書くと… ->(x, y) { x +
y }.call(2, 3) => 5 ->(x, y) { x + y }.curry[2][3] => 5 カリー化
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ Ruby で書くと… ->(x, y) { x +
y }.call(2, 3) ->(x, y) { x + y }.curry[2][3] ``-> (y) { 2 + y }`` 相当のProcが返ってくる カリー化
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ 任意の数の引数のProcをカリー化出来る ->(x, y, z) { x +
y + z }.curry[2][3][4] => 9 ->(x, y, z, xx, yy, zz) { x + y + z + xx + yy + zz }.curry[2][3][4][5][6][7] => 27
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ 途中で変数に取ることも出来る partialized_proc = ->(x, y) { x
+ y }.curry[2] => #<Proc:0x007feaa2f4c6f0 (lambda)> partialized_proc[3] => 5
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ΧϦʔԽͱ 途中で変数に取ることも出来る partialized_proc = ->(x, y) { x
+ y }.curry[2] => #<Proc:0x007feaa2f4c6f0 (lambda)> partialized_proc[3] => 5 全ての引数が渡されると処理結果が返ってくる
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ෦ద༻ͱ 部分適用とは、関数に対して全ての引数を一度に 渡さず、一部の引数だけ渡すことができる仕組 み。
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ෦ద༻ͱ partialized_proc = ->(x, y) { x +
y }.curry[2] => #<Proc:0x007feaa2f4c6f0 (lambda)> partialized_proc[3] => 5
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦ద༻ ෦ద༻ͱ partialized_proc = ->(x, y) { x +
y }.curry[2] => #<Proc:0x007feaa2f4c6f0 (lambda)> partialized_proc[3] => 5 これが部分適用された状態のProc
60sec Ͱ͔Δ(ͱྑ͍ͳͱࢥ͏) ΧϦʔԽͱ෦ద༻ END
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ⾠ҙࣄ߲
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ⾠ҙࣄ߲ Clojureではスレッディングマクロの実現に Transducersという機構を使用しています。
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ⾠ҙࣄ߲ Clojureではスレッディングマクロの実現に Transducersという機構を使用しています。 が、ここではTransducersについては触れません。
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͜ͷॻ͖ํΛ [ -> (collection) { collection.select(&:even?) }, -> (n,
collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) } ].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc) }
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ thread_last ʹద༻͢Δͱ… thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) },
-> (n, collection) { collection.map {|e| e * n }.curry[2] }, -> (collection) { collection.reduce(100, :+) } )
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ thread_last ʹద༻͢Δͱ… thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) },
-> (n, collection) { collection.map {|e| e * n }.curry[2] }, -> (collection) { collection.reduce(100, :+) } ) => 112
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ thread_last ʹద༻͢Δͱ… thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) },
-> (n, collection) { collection.map {|e| e * n }.curry[2] }, -> (collection) { collection.reduce(100, :+) } ) => 112 利用者がcurryしないといけない
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍……
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc def |(arg) self.curry[arg] end end
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc def |(arg) self.curry[arg] end end Procに
| メソッドを生やす
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc def |(arg) self.curry[arg] end end thread_last(
[1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } } | 2, -> (collection) { collection.reduce(100, :+) } ) Procに | メソッドを生やす
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc def |(arg) self.curry[arg] end end thread_last(
[1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } } | 2, -> (collection) { collection.reduce(100, :+) } ) => 112 Procに | メソッドを生やす
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ thread_last(->>) が出来た!
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ thread_last(->>) が出来た!
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ 色々なスレッディングマクロ ‣ ‣ ‣ BT ‣ TPNF
‣ TPNF ‣ DPOE ‣ DPOE
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ 色々なスレッディングマクロ ‣ ‣ ‣ BT ‣ TPNF
‣ TPNF ‣ DPOE ‣ DPOE まだまだ戦いは続く……
▸ Ұ൪࠷ॳͷʹProc͕དྷΔ͜ͱ͋ΔɻͷͰɺ࠷ॳ͕ProcͳΒ࣮ߦ͢ΔɻͪΖΜҾͷ͕ෆఆͳͷͰcallͰ ͳ͘curryͰɻ ▸ Procʹੜͨ͠|ϝιουͰଈ࣌curry͍͚ͯͨ͠Ͳɺthread_first(->) ͷͱ͖࣮ߦ͢Δੇલ·ͰΧϦʔԽͨ͘͠ͳ ͍ͷͰɺ࣮ߦ࣌·ͰྻͰ͍࣋ͬͯΔΑ͏ʹͨ͠ɻ ▸ thread_as(as->) ͢Δͱ͖ҾͷૠೖॴΛબΔɻγϯϘϧͰදݱ͍͕ͨ͠Procͷ݁Ռ͕γϯϘϧʹͳΔ͜ͱ
༗ΔͷͰɺදݱ͖͠Εͳ͍ɻͷͰProcʹ৽ͨͳϝιου&Λੜͨ͠ɻ͔ͭɺૠೖҐஔΛද͢ܕΛ༻ҙͨ͠ɻ ▸ map ͱ͔reduceͱ͔͢ΔϥϜμࣜΛҰʑॻ͖ͨ͘ͳ͍……ͷͰɺҾͰड͚औͬͨCollectionΛϨγʔόʔͱ͠ ͯmapΛ࣮ߦ͢Δϝιου_map(proc)͕includeͨ͠Ϋϥεͷselfʹੜ͑ΔΑ͏ʹͨ͠ɻreduce, selectʹؔͯ͠ ಉ༷ɻ ▸ ↑Ͱ࡞ͬͨϝιουͰɺProcΛ͍ͨ͠ͱ͖ͱBlockΛ͍ͨ͠ͱ͖͕͋Δɻ ▸ Clojureͷ->>ͱಉ͡Α͏ͳϝιουͷΤΠϦΞεΛઃ͚͍͕ͨɺ- ࢝·Γͷϝιουॻ͚ͳ͍ɻϚϧνόΠτ ͍͚ΔͷͰɺ৭ʑߟ͑ͨ݁Ռ͜Ε͕Ұ൪͍ۙͱࢥ͏ɻ ``ʔ✈✈`` ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ 戦いの記録(ダイジェスト版)
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ৭ʑͬͨ݁Ռ -> (collection) { collection.reduce(100, :+) }. call(-> (collection)
{ collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ৭ʑͬͨ݁Ռ -> (collection) { collection.reduce(100, :+) }. call(-> (collection)
{ collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4]))) thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+) )
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ৭ʑͬͨ݁Ռ -> (collection) { collection.reduce(100, :+) }. call(-> (collection)
{ collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4]))) thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+) ) こ こ まで 短 く簡 潔 に 書 け る! ! !
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͳ͓…… thread_last( [1, 2, 3, 4],
_select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+) )
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͳ͓…… thread_last( [1, 2, 3, 4], _select(&:even?),
_map(-> (e) { e * 2 }), _reduce(100, &:+) ) このコードをラムダ式を使わずに 普通に書くと……
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ͳ͓…… [1, 2, 3, 4]. select(&:even?). map {|e| e
* 2}. reduce(100, :+) thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+) ) このコードをラムダ式を使わずに 普通に書くと……
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ݁ɻ
ClojureͷεϨοσΟϯάϚΫϩͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨʹ͍ͭͯ ݁ɻ 素のRubyすごい
Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍ͷΛRubyͰ࣮ͯ͠Έͨ ʹ͍ͭͯ ୈೋ෦ esm LT 2016/10/07 END