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
Clojure 1.10 概要紹介
Search
OHTA Shogo
November 29, 2018
Programming
3
610
Clojure 1.10 概要紹介
2018/11/29のLisp meetup #70の発表資料です。
OHTA Shogo
November 29, 2018
Tweet
Share
More Decks by OHTA Shogo
See All by OHTA Shogo
テンクーでのClojure活用事例
athos
0
270
軽量デバッグツールPostmortemの紹介.pdf
athos
1
190
やってみる!clojure.spec
athos
4
960
kitchen-async: a promising (?) Promise library, or a poor man's core.async
athos
3
400
Clojure 1.9 概要紹介
athos
4
1.4k
ここ最近のClojureScript
athos
5
1.7k
(= ? (+ nREPL Docker))
athos
0
480
clojure.specの話
athos
3
2.2k
clojure.specの話(仮)
athos
2
330
Other Decks in Programming
See All in Programming
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
4
1.5k
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
2k
Quine, Polyglot, 良いコード
qnighy
4
650
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.8k
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
Contemporary Test Cases
maaretp
0
140
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
Figma Dev Modeで変わる!Flutterの開発体験
watanave
0
140
Duckdb-Wasmでローカルダッシュボードを作ってみた
nkforwork
0
130
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
840
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
A Philosophy of Restraint
colly
203
16k
How STYLIGHT went responsive
nonsquared
95
5.2k
Happy Clients
brianwarren
98
6.7k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
What's in a price? How to price your products and services
michaelherold
243
12k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Building an army of robots
kneath
302
43k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Transcript
$MPKVSF֓ཁհ -JTQNFFUVQPO !BUIPT
֓ཁ ‣ ઌ ɺ3$͕ϦϦʔε BMQIBϦϦʔε CFUBϦϦʔε
3$ϦϦʔε ‣ pOBMϦϦʔεલͳͷͰɺͰͷओཁͳมߋʹ ͍͓ͭͯ͞Β͍
$MPKVSFͷओཁͳมߋ ‣ Τϥʔϝοηʔδͷվળ ‣ EBUBGZ ‣ ϝλσʔλʹΑΔϓϩτίϧͷ֦ு ‣ QSFQM ‣
UBQ
Τϥʔϝοηʔδͷվળ ‣ ࠓճͷϦϦʔεʹ͓͚ΔҰ൪ͷۄ ‣ Τϥʔϝοηʔδͱͯ͠ɺϢʔβʹͲ͏͍ͬͨใΛఏࣔ ͢Δ͔Λൈຊతʹཧ ‣ ඪ४3&1-ͰͷΤϥʔϝοηʔδվળ͚ͩͰͳ͘ଞͷ։ൃ ڥͰΤϥʔใΛศརʹ׆༻Ͱ͖ΔΑ͏ͳ"1*Λఏڙ ‣
·ͩඪ४ͷΤϥʔϝοηʔδඞ͔ͣ͠Γ͍͢Θ͚ Ͱͳ͍ͷͰɺࠓޙͷ։ൃڥଆͷվળ͕ظ͞ΕΔ
Τϥʔͷ͔Γʹ͘͞ͷݪҼ ‣ $MPKVSFͷଟ͘ͷؔΨʔϕδΠϯɾΨʔϕδΞτ ҾνΣοΫ͕ͳ͍ͨΊɺClassCastException IllegalArgumentExceptionɺతʹΤϥʔՕॴΛࣔ ͞ͳ͍Τϥʔ͕ग़ͯ͠·͏ DMPKVSFTQFDʹΑͬͯղܾ͞Ε͍ͯ͘ݟࠐΈ ʙ
‣ Τϥʔͷใྔ͕ଟ͗ͯ͢Կ͕ॏཁͳͷ͔͔Γʹ͍͘ ಛʹTQFDͷΤϥʔใ͕େʹͳΓ͕ͪ ‣ ॲཧܥଆͷݺͼग़͕͠ελοΫτϨʔεʹฆΕࠐΜͰ͠·͏ ॲཧܥ͕Ͳ͜ͰΤϥʔΛݟ͚͔ͭͨॏཁͰͳ͍
Τϥʔͷཧ ‣ ͲͷϑΣʔζͰग़ͨΤϥʔ͔ΛྨɺϑΣʔζຖʹ༗༻ͳใΛ࣋ͨͤΔ ϑΣʔζɿϦʔυ࣌ɺϚΫϩߏจνΣοΫ࣌ɺϚΫϩల։࣌ɺίϯύΠϧ ࣌ɺ࣮ߦ࣌ɺ݁Ռग़ྗ࣌ ‣ CompilerException ࣮ߦ࣌ΑΓલͷϑΣʔζͷΤϥʔ ͔Βex-data
ͰҎԼͷใΛڞ௨ͯ͠औಘՄೳʹ :clojure.error/phase Τϥʔ͕ൃੜͨ͠ϑΣʔζ :clojure.error/source Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧ :clojure.error/line Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧͷߦ൪߸ :clojure.error/column Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧͷܻ :clojure.error/symbol ΤϥʔͷݪҼʹͳͬͨγϯϘϧ :clojure.error/class ΤϥʔΫϥε໊ :clojure.error/cause Τϥʔϝοηʔδ :clojure.error/spec εϖοΫΤϥʔ ͋Ε
ॏཁͷ͍ใͷݮ εϖοΫΤϥʔ σʔλ ਓؒʹͱͬͯ༗ӹͰͳ͍ ใදࣔ͠ͳ͍Α͏ʹ ͷϚΫϩߏจΤϥʔ ͷϚΫϩߏจΤϥʔ
ΤϥʔՕॴͷࢦఠ ‣ ϦʔυΤϥʔ ‣ ίϯύΠϧΤϥʔ ʁ ຊʹΓ͍ͨͷॲཧܥ͕ͲͷॲཧதʹΤϥʔΛ ݟ͚͔ͭͨͰͳ͘ίʔυͷͲ͜ʹΤϥʔ͕͔͋ͬͨ ʁ
ex-triageex-str ‣ ࣮ߦ࣌ΤϥʔҰൠʹ+BWBͷྫ֎ɾΤϥʔͷՄೳੑ +BWBͷྫ֎ɾΤϥʔͷதʹɺ$MPKVSFʹ߹ͷ͍͍ଐੑΛ ࣋ͨͳ͍ͷ͋Δ ‣ ex-triage ͋ΒΏΔΤϥʔΛ౷ҰతͳϑΥʔϚοτͷϚοϓσʔλʹ
ม͢Δ ϦϞʔτͰͭͳ͕ΔڥͰΤϥʔใΛΓͱΓ͢ΔϑΥʔ Ϛοτͱͯ͑͠Δ ‣ ex-str ex-triageΛจࣈྻԽ͢Δඪ४తͳํ๏
EBUBGZ ‣ DMPKVSFEBUBGZ ‣ ৽͍͠ϓϩτίϧDatafiableͱNavigable͕Ճ ‣ ͲͪΒͷϓϩτίϧৄࡉͳઆ໌·ͩͳ͍ ‣ جຊతʹΦϒδΣΫτΛʮσʔλԽʯ͢ΔͨΊͷͷ
EBUBGZ ‣ :extend-via-metadataʹ͍ͭͯޙड़ (defprotocol Datafiable :extend-via-metadata true (datafy [o] “return
a representation of o as data”)) (defprotocol Navigable :extend-via-metadata true (nav [coll k v] "return v in the context of coll and k (a key/index or nil)"))
EBUBGZͷ͍ํ ‣ ݱ࣌ͰɺΫϥεྫ֎গͷ࣮͕ఏڙ͞Ε͍ͯΔͷΈ (require ‘[clojure.datafy :as datafy]) (datafy/datafy java.io.Closeable) ;=>
{:bases #{java.lang.AutoCloseable}, :flags #{:interface :public :abstract}, :members {close [#clojure.reflect.Method{…}, :name java.io.Closeable} (datafy/datafy (ex-info “error” {})) ;=> {:cause “error!!”, :data {:value 42}, :trace [[user$eval199 invokeStatic "NO_SOURCE_FILE" 1] [user$eval199 invoke "NO_SOURCE_FILE" 1] [clojure.lang.Compiler eval "Compiler.java" 7176] …] :via [{:type clojure.lang.ExceptionInfo, :message “error!!", :data {:value 42}, :at [user$eval199 invokeStatic "NO_SOURCE_FILE" 1]}]}
EBUBGZͷิ ‣ ʮσʔλԽʯͱ͍͏ͱ༻్͕෯͘ײ͡Δ͕ɺ Throwable->mapͷΑ͏ʹɺΦϒδΣΫτͷΠϯεϖΫ γϣϯ༻్͕ϝΠϯʹࢥ͑Δ ݸਓతײ SFJGZͰ࡞ͬͨΦϒδΣΫτ͕෦తʹอ࣋͢Δใͷެ։
ಛʹεϖοΫΦϒδΣΫτͷΠϯεϖΫγϣϯɺτϥόʔε ‣ ΦϒδΣΫτͷγϦΞϥΠζͷ༻్͋·Γఆ͞Εͯ ͍ͳ͍͜ͱ͕ެࣜʹ΄ͷΊ͔͞Ε͍ͯΔ
ϝλσʔλʹΑΔϓϩτίϧͷ֦ு ‣ EBUBGZಋೖͷաఔͰऔΓೖΕΒΕͨ ‣ ͜Ε·ͰϓϩτίϧϨίʔυσʔλܕͰ࣮͢Δ ͔ɺextend-protocolextend-typeͰ֦ு͢Δ͔ͩͬͨ ‣ ͔ΒϝλσʔλʹΑΓϓϩτίϧΛ֦ுͰ͖ΔΑ͏ ʹͳΓɺΦϒδΣΫτຖͷଟ૬తͳৼΔ͍ΛఆٛՄೳʹ
ैདྷͷϓϩτίϧͷར༻๏ (defprotocol P (m [this])) ;; ϨίʔυʹΑΔ࣮ (defrecord R []
P (m [this] 42)) (m (->R)) ;=> 42 ;; extend-protocol/extend-typeʹΑΔ֦ு (extend-protocol P Long (m [this] this)) (m 101) ;=> 101
ϝλσʔλʹΑΔ֦ு ‣ :extend-via-metadata true Λࢦఆ͢Δͱɺϓϩτίϧ͕ ϝλσʔλʹΑΓ֦ுՄೳʹ (defprotocol P :extend-via-metadata true
(m [this])) (def obj (with-meta {:x 42} {`m (fn [this] (:x this))})) (m obj) ;=> 42 (m (with-meta obj {`m (fn [this] 43)})) ;=> 43
ϝλσʔλʹΑΔ֦ுͷҙ ‣ ϓϩτίϧͷఆٛ࣌ʹ:extend-via-metadataͷࢦఆ͕ ͳ͚ΕϝλσʔλʹΑΔ֦ு༗ޮʹͳΒͳ͍ ‣ ϓϩτίϧͷ࣮ͷ༏ઌॱҐ ϨίʔυɾσʔλܕʹΑΔ࣮ ϝλσʔλʹΑΔ֦ு
extend-protocolextend-typeʹΑΔ֦ு ‣ ϝλσʔλʹΑΔ֦ுΛ༗ޮʹͨ͠ϓϩτίϧͷϝιου ݺͼग़͠ੑೳ໘ͰͷΦʔόʔϔου͕͋Δ
QSFQM ‣ lQSPHSBNNBCMFz3&1- ‣ ৽͍͠ετϦʔϜϕʔε3&1- ‣ $MPKVSFϑΥʔϜΛೖྗʹͱΓɺߏԽ͞Εͨग़ྗΛฦ͢ ‣ Ͱಋೖ͞Εͨιέοταʔό͔Βར༻͠ɺϦϞʔτ 3&1-Λ࣮ݱ͢ΔͨΊʹ͏͜ͱΛఆ͞Ε͍ͯΔ
‣ 6OSFQMϓϩτίϧʹྨࣅ͢Δ෦͕ଟ͍ IUUQTHJUIVCDPN6OSFQMVOSFQM
QSFQMͷ͍ํ ‣ ιέοταʔόͷىಈ ‣ ΫϥΠΞϯτ͔Βͷଓ ‣ $ clojure -J-Dclojure.server.repl="{:port 5555
:accept clojure.core.server/io-prepl}" $ nc localhost 5555 (map inc [1 2 3]) {:tag :ret, :val "(2 3 4)", :ns "user", :ms 19, :form "(map inc [1 2 3])”} (dotimes [i 3] (Thread/sleep 1000) (println i)) {:tag :out, :val "0\n"} {:tag :out, :val "1\n"} {:tag :out, :val "2\n"} {:tag :ret, :val "nil", :ns "user", :ms 3214, :form "(dotimes [i 3] (Thread/sleep 1000) (println i))”}
ैདྷͷ3&1-ͷ ‣ ैདྷͷ3&1-Λιέοταʔό͔Β͏͜ͱΛߟ͑Δͱʮධ Ձ݁Ռ͔͠ฦͤͳ͍ʯ͜ͱͷ͕خ͘͠ͳ͍͜ͱ ‣ ͨͱ͑ʜ ධՁ͍ͯ͠Δ్தͰग़ྗ݁ՌɺධՁ݁ՌҎ֎ͷͷΛฦ͢ ͷ͕͍͠
ྫ֎ɾΤϥʔධՁ݁Ռͱผʹѻ͍͍ͨɺΫϥΠΞϯτଆ ͰৄࡉͳใΛࣗ༝ʹऔಘ͍ͨ͠ ͍γʔέϯεͷলུදࣔɾల։ɺϚϧνϝσ ΟΞ ը૾ ͷ 3&1-ͰͷදࣔɺΫϥΠΞϯτͷϦονͳػೳͷఏڙ ‣ ݱঢ়Ͱɺ͜ΕΒͷO3&1-Ͱղܾ͞Ε͍ͯΔ
O3&1-ͱͷҧ͍ ‣ O3&1-ೖྗߏԽ͞Εͨϝοηʔδ ϋϯυϥʹϛυϧΣΞΛՃ͢Δ͜ͱͰॲཧͰ͖Δϝο ηʔδͷछྨΛ૿͢Έ O3&1-αʔόىಈޙʹػೳΛՃ͢Δͷ͍͠ ‣ QSFQMͷೖྗ୯ͳΔϑΥʔϜ
ػೳΛՃ͠Α͏ͱࢥ͑ͦͷػೳΛ࣮ݱ͢ΔϑΥʔϜΛ ྲྀ͠ࠐΉ͚ͩ ΫϥΠΞϯτଆ͔ΒඞཁͳػೳΛ͖ͳΑ͏ʹՃͰ͖Δ l3&1-UIFVMUJNBUFDPOUFOUOFHPUJBUJPOQSPUPDPMz DG6OSFQMCMPC
͞·͟·ͳQSFQM࣮ ‣ QSFQMɿඪ४ͷQSFQM ‣ JPQSFQM ඪ४ೖग़ྗܦ༝ͰΓͱΓ͢Δ࣮ ιέοταʔό͔Βݺͼग़͞ΕΔ͜ͱΛఆ ‣
SFNPUFQSFQM ϦϞʔτͰͪड͚ΔQSFQMαʔόʹଓ͢Δ࣮
UBQ ‣ άϩʔόϧʹར༻ՄೳͳγϯϓϧͳΠϕϯτγεςϜ ‣ σόοάϩΪϯάͷ༻్Λҙਤ͍ͯ͠Δ ‣ QSFQMಋೖʹͬͯऔΓೖΕΒΕͨ
UBQͷ͍ํ ‣ add-tapremove-tapͰϋϯυϥؔΛొɾআ ‣ tap>ͰΛૹ৴ɺͯ͢ͷϋϯυϥؔͰ͕ॲཧ͞ΕΔ (defn log [x] (println “tapped
value: “ x)) (add-tap log) (tap> 1) ;; tapped value: 1 ;=> 1 (tap> 2) ;; tapped value: 2 ;=> 2 (remove-tap log) (tap> 3) ;=> 3
QSFQMͰͷUBQ ‣ UBQQSFQM্Ͱಛผʹॲཧ͞ΕΔ ‣ QSFQM্ͰσόοάϩΪϯάɺϓϩάϨεͷදࣔʹར༻ Ͱ͖Δ $ nc localhost 5555
(dotimes [i 5] (Thread/sleep 1000) (tap> i)) {:tag :tap, :val "0"} {:tag :tap, :val "1"} {:tag :tap, :val "2"} {:tag :tap, :val "3"} {:tag :tap, :val "4"} {:tag :ret, :val "nil", :ns "user", :ms 5216, :form "(dotimes [i 5] (Thread/sleep 1000) (tap> i))"}
ͦͷଞͷมߋ ‣ +7.ͷ࠷খαϙʔτόʔδϣϯมߋ ࠷খαϙʔτόʔδϣϯ͕͔Βʹ ‣ SFRVJSJOHSFTPMWF ʮ࣮ߦ࣌ʹSFRVJSFͯ͠ݺͼग़͠ʯ͕؆୯ʹॻ͚ΔΑ͏ʹ ‣
SFBE TUSJOH Ϧʔυ݁Ռͱͯ͠ݩͷจࣈྻදݱҰॹʹऔಘͰ͖Δ
·ͱΊ ‣ $MPKVSFΤϥʔϝοηʔδͷվળͱQSFQMͷՃΛத ৺ͱͨ͠มߋ ‣ ݸʑͷಠཱͨ͠ػೳͱ͍͏ΑΓɺϦονͳ։ൃڥΛ։ൃ ͢ΔͨΊͷΈΛఏڙ͢ΔͨΊͷϦϦʔεͱ͍͏ҹ ‣ 4UBZUVOFE
ࢀߟจݙ ‣ DIBOHFTNE IUUQTHJUIVCDPNDMPKVSFDMPKVSFCMPCNBTUFSDIBOHFTNE ‣ 6OSFQM IUUQTHJUIVCDPN6OSFQMVOSFQM