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
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
47
Pythonを書いていておーマジかーと感じたあれこれ
kunou
1
740
ネットワークグラフを作成する
kunou
0
73
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
DatadogのBits Chatが開発組織にもたらしたもの / What Bits Chat Has Brought Us
sms_tech
1
280
TypeScript入門 2026
recruitengineers
PRO
3
660
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
24k
20260804_Q4AzureUpdateBite_FabricDataAgentの精度を高める設計.pdf
matayuuu
1
140
事業価値と Engineering 2026年度版
recruitengineers
PRO
50
24k
今こそ聞きたいソフトウェア設計 ドメイン駆動設計再入門
masuda220
PRO
17
7.5k
私がブラウザを自作したくなった理由
supurazako
1
250
20260807_第6回_関東kaggler会LT_claw系bot xangiと始める、"寂しくない" kaggle
sugupoko
0
310
QAエンジニア起点で進める、SmartHRにおける信頼性向上について
kaomi_wombat
1
150
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
強化学習「理論」入門
enakai00
3
3.6k
案件に一番詳しいAIを Amazon Bedrock AgentCore で作る ― 知見が知見を生むチームへ / Compounding Knowledge with AgentCore
yusukeshimizu
1
110
Featured
See All Featured
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.8k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
490
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.9k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
280
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
470
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
240
How to build a perfect <img>
jonoalderson
1
5.9k
Between Models and Reality
mayunak
4
390
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
420
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
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