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
430
esm lt Clojure like threading macro
kunou
October 11, 2016
Tweet
Share
More Decks by kunou
See All by kunou
GANについて
kunou
0
430
AIか何かについて.pdf
kunou
0
32
Pythonを書いていておーマジかーと感じたあれこれ
kunou
1
720
ネットワークグラフを作成する
kunou
0
49
Rubyで機械学習してみた
kunou
1
1.1k
ZIP!!
kunou
0
170
zip
kunou
0
510
Make Mouse
kunou
0
630
RubyのProcのあれをこうしました
kunou
0
94
Other Decks in Technology
See All in Technology
バックエンドエンジニアのためのフロントエンド入門 #devsumiC
panda_program
18
7.5k
Amazon S3 Tablesと外部分析基盤連携について / Amazon S3 Tables and External Data Analytics Platform
nttcom
0
130
データの品質が低いと何が困るのか
kzykmyzw
6
1.1k
現場で役立つAPIデザイン
nagix
33
12k
技術的負債解消の取り組みと専門チームのお話 #技術的負債_Findy
bengo4com
1
1.3k
(機械学習システムでも) SLO から始める信頼性構築 - ゆる SRE#9 2025/02/21
daigo0927
0
120
分解して理解する Aspire
nenonaninu
1
130
Swiftの “private” を テストする / Testing Swift "private"
yutailang0119
0
130
リアルタイム分析データベースで実現する SQLベースのオブザーバビリティ
mikimatsumoto
0
1.4k
2.5Dモデルのすべて
yu4u
2
860
君も受託系GISエンジニアにならないか
sudataka
2
430
Oracle Cloud Infrastructure:2025年2月度サービス・アップデート
oracle4engineer
PRO
1
210
Featured
See All Featured
Building Adaptive Systems
keathley
40
2.4k
Faster Mobile Websites
deanohume
306
31k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
Designing Experiences People Love
moore
140
23k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Building an army of robots
kneath
303
45k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
Designing for Performance
lara
604
68k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
330
Making Projects Easy
brettharned
116
6k
Rails Girls Zürich Keynote
gr2m
94
13k
Embracing the Ebb and Flow
colly
84
4.6k
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