$30 off During Our Annual Pro Sale. View Details »

Clojure 1.10 概要紹介

OHTA Shogo
November 29, 2018

Clojure 1.10 概要紹介

2018/11/29のLisp meetup #70の発表資料です。

OHTA Shogo

November 29, 2018
Tweet

More Decks by OHTA Shogo

Other Decks in Programming

Transcript

  1. ֓ཁ ‣ ઌ೔  ɺ3$͕ϦϦʔε  BMQIBϦϦʔε  CFUBϦϦʔε 

    3$ϦϦʔε ‣ pOBMϦϦʔε΋໨લͳͷͰɺͰͷओཁͳมߋʹ ͍͓ͭͯ͞Β͍
  2. Τϥʔͷ෼͔Γʹ͘͞ͷݪҼ ‣ $MPKVSFͷଟ͘ͷؔ਺͸ΨʔϕδΠϯɾΨʔϕδΞ΢τ  Ҿ਺νΣοΫ͕ͳ͍ͨΊɺClassCastException΍ IllegalArgumentException౳ɺ௚઀తʹΤϥʔՕॴΛࣔ ͞ͳ͍Τϥʔ͕ग़ͯ͠·͏  DMPKVSFTQFDʹΑͬͯղܾ͞Ε͍ͯ͘ݟࠐΈ ʙ

     ‣ Τϥʔͷ৘ใྔ͕ଟ͗ͯ͢Կ͕ॏཁͳͷ͔෼͔Γʹ͍͘  ಛʹTQFDͷΤϥʔ৘ใ͕๲େʹͳΓ͕ͪ ‣ ॲཧܥଆͷݺͼग़͕͠ελοΫτϨʔεʹฆΕࠐΜͰ͠·͏  ॲཧܥ͕Ͳ͜ͰΤϥʔΛݟ͚͔ͭͨ͸ॏཁͰ͸ͳ͍
  3. Τϥʔͷ੔ཧ ‣ ͲͷϑΣʔζͰग़ͨΤϥʔ͔Λ෼ྨɺϑΣʔζຖʹ༗༻ͳ৘ใΛ࣋ͨͤΔ  ϑΣʔζɿϦʔυ࣌ɺϚΫϩߏจνΣοΫ࣌ɺϚΫϩల։࣌ɺίϯύΠϧ ࣌ɺ࣮ߦ࣌ɺ݁Ռग़ྗ࣌ ‣ 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 εϖοΫΤϥʔ ͋Ε͹
  4. 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)"))
  5. 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]}]}
  6. EBUBGZͷิ଍ ‣ ʮσʔλԽʯͱ͍͏ͱ༻్͕෯޿͘ײ͡Δ͕ɺ Throwable->mapͷΑ͏ʹɺΦϒδΣΫτͷΠϯεϖΫ γϣϯ༻్͕ϝΠϯʹࢥ͑Δ ݸਓతײ૝   SFJGZͰ࡞ͬͨΦϒδΣΫτ͕಺෦తʹอ࣋͢Δ৘ใͷެ։ 

    ಛʹεϖοΫΦϒδΣΫτͷΠϯεϖΫγϣϯɺτϥόʔε ‣ ΦϒδΣΫτͷγϦΞϥΠζ౳ͷ༻్͸͋·Γ૝ఆ͞Εͯ ͍ͳ͍͜ͱ͕ެࣜʹ͸΄ͷΊ͔͞Ε͍ͯΔ
  7. ैདྷͷϓϩτίϧͷར༻๏ (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
  8. ϝλσʔλʹΑΔ֦ு ‣ :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
  9. 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))”}
  10. ैདྷͷ3&1-ͷ໰୊఺ ‣ ैདྷͷ3&1-Λιέοταʔό͔Β࢖͏͜ͱΛߟ͑Δͱʮධ Ձ݁Ռ͔͠ฦͤͳ͍ʯ͜ͱͷ͕خ͘͠ͳ͍͜ͱ΋ ‣ ͨͱ͑͹ʜ  ධՁ͍ͯ͠Δ్தͰग़ྗ݁Ռ౳ɺධՁ݁ՌҎ֎ͷ΋ͷΛฦ͢ ͷ͕೉͍͠ 

    ྫ֎ɾΤϥʔ͸ධՁ݁Ռͱ͸ผʹѻ͍͍ͨɺΫϥΠΞϯτଆ Ͱৄࡉͳ৘ใΛࣗ༝ʹऔಘ͍ͨ͠  ௕͍γʔέϯεͷলུදࣔɾల։ɺϚϧνϝσ ΟΞ ը૾ ͷ 3&1-Ͱͷදࣔ౳ɺΫϥΠΞϯτ΁ͷϦονͳػೳͷఏڙ ‣ ݱঢ়Ͱ͸ɺ͜ΕΒͷ໰୊͸O3&1-Ͱղܾ͞Ε͍ͯΔ
  11. O3&1-ͱͷҧ͍ ‣ O3&1-͸ೖྗ΋ߏ଄Խ͞Εͨϝοηʔδ  ϋϯυϥʹϛυϧ΢ΣΞΛ௥Ճ͢Δ͜ͱͰॲཧͰ͖Δϝο ηʔδͷछྨΛ૿΍͢࢓૊Έ  O3&1-αʔόىಈޙʹػೳΛ௥Ճ͢Δͷ͸೉͍͠ ‣ QSFQMͷೖྗ͸୯ͳΔϑΥʔϜ

     ػೳΛ௥Ճ͠Α͏ͱࢥ͑͹ͦͷػೳΛ࣮ݱ͢ΔϑΥʔϜΛ ྲྀ͠ࠐΉ͚ͩ  ΫϥΠΞϯτଆ͔ΒඞཁͳػೳΛ޷͖ͳΑ͏ʹ௥ՃͰ͖Δ l3&1-UIFVMUJNBUFDPOUFOUOFHPUJBUJPOQSPUPDPMz   DG6OSFQMCMPC
  12. 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
  13. QSFQMͰͷUBQ ‣ UBQ͸QSFQM্Ͱಛผʹॲཧ͞ΕΔ ‣ 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))"}