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
0
440
esm lt Clojure like threading macro
kunou
October 11, 2016
Tweet
Share
More Decks by kunou
See All by kunou
GANについて
kunou
0
440
AIか何かについて.pdf
kunou
0
39
Pythonを書いていておーマジかーと感じたあれこれ
kunou
1
730
ネットワークグラフを作成する
kunou
0
58
Rubyで機械学習してみた
kunou
1
1.1k
ZIP!!
kunou
0
180
zip
kunou
0
510
Make Mouse
kunou
0
640
RubyのProcのあれをこうしました
kunou
0
99
Other Decks in Technology
See All in Technology
GeminiとNotebookLMによる金融実務の業務革新
abenben
0
250
Lambda Web Adapterについて自分なりに理解してみた
smt7174
5
150
KubeCon + CloudNativeCon Japan 2025 Recap Opening & Choose Your Own Adventureシリーズまとめ
mmmatsuda
0
250
Glacierだからってコストあきらめてない? / JAWS Meet Glacier Cost
taishin
1
130
SmartNewsにおける 1000+ノード規模 K8s基盤 でのコスト最適化 – Spot・Gravitonの大規模導入への挑戦
vsanna2
0
110
B2C&B2B&社内向けサービスを抱える開発組織におけるサービス価値を最大化するイニシアチブ管理
belongadmin
1
4.7k
PHPでWebブラウザのレンダリングエンジンを実装する
dip_tech
PRO
0
220
タイミーのデータモデリング事例と今後のチャレンジ
ttccddtoki
6
2.2k
製造業からパッケージ製品まで、あらゆる領域をカバー!生成AIを利用したテストシナリオ生成 / 20250627 Suguru Ishii
shift_evolve
PRO
1
160
AIとともに進化するエンジニアリング / Engineering-Evolving-with-AI_final.pdf
lycorptech_jp
PRO
0
150
開発生産性を組織全体の「生産性」へ! 部門間連携の壁を越える実践的ステップ
sudo5in5k
1
4.8k
「クラウドコスト絶対削減」を支える技術—FinOpsを超えた徹底的なクラウドコスト削減の実践論
delta_tech
4
110
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
462
33k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Faster Mobile Websites
deanohume
307
31k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
Being A Developer After 40
akosma
90
590k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
Building Applications with DynamoDB
mza
95
6.5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
46
9.6k
The Cost Of JavaScript in 2023
addyosmani
51
8.5k
Facilitating Awesome Meetings
lara
54
6.4k
Adopting Sorbet at Scale
ufuk
77
9.4k
Producing Creativity
orderedlist
PRO
346
40k
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