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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
69
Rubyで機械学習してみた
kunou
1
1.2k
ZIP!!
kunou
0
200
zip
kunou
0
530
Make Mouse
kunou
0
660
RubyのProcのあれをこうしました
kunou
0
110
Other Decks in Technology
See All in Technology
Agent Skills設計で柔軟性と硬さのバランスが難しい話
nassy20
0
140
Claude Code の Sandbox 機能を Anthropic Sandbox Runtime(srt) で試そう!/lets-play-anthropic-sandbox-runtime
tomoki10
1
640
2026TECHFRESH畢業分享會 - AI 時代的人生存檔點
line_developers_tw
PRO
0
1.2k
AmazonRoute 53ではじめてのドメイン取得!HTTPS化までの道のりを整理してみた
usanchuu
3
150
SteampipeとExcel Power QueryでAWS構成定義書の作成を自動化する
jhashimoto
0
110
2026TECHFRESH畢業分享會 - Lightning Talk - 打造精準高效的 MCP 設計模式與測試實務
line_developers_tw
PRO
0
1.2k
エンジニアリング戦略の作り方 / Crafting Engineering Strategy
iwashi86
21
7k
中期計画、2回作ってみた ~業務委託と正社員、両方の視点から~
demaecan
1
920
Bedrock AgentCore RuntimeでAuth0 Changelog調査AIをアップグレードした話
t5u8a5a
1
180
ルールやカスタム機能、どう活かす?ハンズオンで体感するIBM Bobの出力コントロール
muehara
1
170
アンオフィシャルな、オフィシャルからのお願い
wyamazak_devrel
0
130
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
170
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
950
Are puppies a ranking factor?
jonoalderson
1
3.6k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
170
Abbi's Birthday
coloredviolet
2
8.1k
The Curious Case for Waylosing
cassininazir
1
390
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
200
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
220
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
From π to Pie charts
rasagy
0
210
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
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