Upgrade to Pro — share decks privately, control downloads, hide ads and more …

clojure.specの話(仮)

OHTA Shogo
July 21, 2016
320

 clojure.specの話(仮)

OHTA Shogo

July 21, 2016
Tweet

Transcript

  1. DMPKVSFTQFDͷ࿩
    Ծ

    OJTIJTIJOKVDMPKVSF
    !BUIPT

    View Slide

  2. ࣗݾ঺հ
    ‣ 5XJUUFS!BUIPT
    ‣ χϟϯύεגࣜձࣾॴଐ
    ‣ $MPKVSFίϯτϦϏϡʔλ

    View Slide

  3. ૣ଎Ͱ͕͢

    View Slide

  4. $MPKVSFͷҰ൪
    ϜΧͭ͘ͱ͜Ζͬͯʁ

    View Slide

  5. Τϥʔϝοηʔδ
    ࠾༻
    εΫϦϓτΛ࡞Δ೉͠͞
    υΩϡϝϯτɾνϡʔτϦΞϧ
    ੩తܕ͕ͳ͍
    $MPKVSFTVSWFZʮ$MPKVSFͷҰ൪ϜΧͭ͘ͱ͜Ζ͸ʁʯ

    View Slide

  6. Τϥʔϝοηʔδ

    View Slide

  7. ‣ $MPKVSFͷΤϥʔͷ෼͔Γʹ͘͞͸Α͘ࢦఠ͞ΕΔ
    ‣ $MPKVSFͷ૊ࠐΈؔ਺ͷଟ͘͸ΨʔϕδΠϯΨʔϕδ
    Ξ΢τ
    ‣ Ҿ਺νΣοΫΛೖΕΔͱɺ+*5ίϯύΠϥͷ࠷దԽΛ
    ્֐͠ɺύϑΥʔϚϯεʹӨڹ͢ΔͨΊ

    View Slide

  8. Կ͕ωοΫ͔ʁ
    ‣ ύϑΥʔϚϯε໘͔Βߟ͑Δͱ࣮ߦ࣌ͷνΣοΫ͸
    ۃྗආ͚͍ͨ
    ‣ ͔͠͠ɺ੩తܕ͕ͳ͍Ҏ্ίϯύΠϧ͚࣌ͩͰνΣο
    Ϋ͖͠Δͷ͸೉͍͠
    ‣ ։ൃ͚࣌ͩΦϯʹͰ͖ΔҾ਺νΣοΫͷ࢓૊Έ͕͋
    Ε͹͍͍

    View Slide

  9. DMPKVSFTQFD

    View Slide

  10. DMPKVSFTQFD
    ‣ ࣍ظϦϦʔε$MPKVSFͰͷಋೖ͕ਐΊΒΕ͍ͯΔ৽ػೳ
    ‣ ੩తܕͰͳ͘ɺड़ޠͷ૊Έ߹ΘͤʹΑͬͯσʔλܕͷ࢓༷
    Λهड़͢Δ
    ‣ Ұ౓࢓༷ εϖοΫ
    Λॻ͚͹ҰཻͰԿ౓΋͓͍͍͠
    υΩϡϝϯςʔγϣϯ
    ܖ໿ϓϩάϥϛϯά
    ϓϩύςΟϕʔεςετ
    ϚΫϩͷߏจνΣοΫ

    View Slide

  11. DMPKVSFTQFDͷ࢖͍ํ
    ‣ [org.clojure/clojure “1.9.0-alphaXX”]
    Λ:dependenciesʹ௥Ճ
    ‣ ࠷৽൛͸BMQIB ݱࡏ

    ‣ (require ‘[clojure.spec :as s])

    View Slide

  12. DMPKVSFTQFDೖ໳

    View Slide

  13. ड़ޠ
    ‣ ड़ޠ CPPMΛฦؔ͢਺
    ͸ͦͷ··ͰεϖοΫͱͯ͠
    ࢖͑Δ
    user=> (s/valid? integer? 42)
    true
    user=> (s/valid? integer? “foo”)
    false

    View Slide

  14. WBMJE FYQMBJO
    ‣ WBMJE ͸εϖοΫΛຬ͔ͨ͢Ͳ͏͔Λฦ͢
    ‣ FYQMBJO͸εϖοΫΛຬͨ͞ͳ͍ՕॴΛࢦఠ͢Δ
    user=> (s/valid? integer? “foo”)
    false
    user=> (s/explain integer? “foo”)
    val: "foo" fails predicate:
    :clojure.spec/unknown
    nil
    user=> (s/explain integer? 42)
    Success!
    nil

    View Slide

  15. εϖοΫͷ߹੒
    ‣ BOE΍PSΛ࢖ͬͯෳ਺ͷεϖοΫΛ૊Έ߹ΘͤՄೳ
    user=> (s/valid? (s/and integer? even?) 0)
    true
    user=> (s/valid? (s/and integer? even?) 1)
    false
    user=> (s/valid? (s/or :int integer?
    :str string?)
    “foo”)
    true

    View Slide

  16. εϖοΫʹ໊લΛ͚ͭΔ
    ‣ EFGͰεϖοΫʹ໊લΛ͚ͭΔ͜ͱ͕Ͱ͖Δ
    ‣ εϖοΫࣗମΛ࠶ར༻Ͱ͖Δ
    user=> (s/def ::answer-to-everything
    (fn [x] (= x 42))
    :user/answer-to-everything
    user=> (s/valid? ::answer-to-everything 43)
    false
    user=> (s/valid? ::answer-to-everything 42)
    true

    View Slide

  17. ίϨΫγϣϯͷεϖοΫ
    ‣ coll-ofmap-ofͰίϨΫγϣϯͷཁૉ͕εϖοΫ
    Λຬ͍ͨͯ͠Δ͔νΣοΫͰ͖Δ
    user=> (s/valid? (s/coll-of integer?) [1 2 3])
    true
    user=> (s/valid? (s/coll-of integer?) [1 :a])
    false
    user=> (s/valid? (s/map-of keyword? integer?)
    {:a 0, :b 1})
    true
    user=> (s/valid? (s/map-of keyword? integer?)
    {:a 0, :b “foo”})
    false

    View Slide

  18. ίϨΫγϣϯͷεϖοΫ
    ‣ ΩʔʹΑͬͯ஋ͷܕ͕ҧ͏ϚοϓͷεϖοΫ΋ఆٛՄೳ
    user=> (s/def ::x integer?)
    :user/x
    user=> (s/def ::y string?)
    :user/y
    user=> (s/explain (s/keys :req-un [::x ::y])
    {:x 1, :y 2})
    In: [:y] val: 2 fails spec: :user/y at: [:y]
    predicate: string?
    nil
    user=> (s/valid? (s/keys :req-un [::x ::y])
    {:x 1, :y “foo”})
    true

    View Slide

  19. DMPKVSFTQFDʹΑΔ
    ܖ໿ϓϩάϥϛϯά

    View Slide

  20. ܖ໿ϓϩάϥϛϯάͱ͸
    ‣ ؔ਺ͷݺͼग़͠ʹؔͯ͠ɺࣄલ৚݅ɾࣄޙ৚݅ɾෆ
    ม৚݅ΛܾΊɺݺͼग़͢ଆͱݺͼग़͞ΕΔଆͷٛ຿
    Λ໌֬ʹ͢Δख๏
    ݺͼग़͢ଆɿ
    ؔ਺Λݺͼग़͢લʹࣄલ৚݅ͱෆม৚݅Λຬͨٛ͢຿Λෛ͏
    ݺͼग़͞Εͨଆɿ
    ؔ਺͔Β໭ͬͨޙʹࣄޙ৚݅ͱෆม৚݅Λຬͨٛ͢຿Λෛ͏

    View Slide

  21. ؔ਺ʹର͢ΔεϖοΫ
    ‣ fizzbuzzؔ਺ͷεϖοΫ͸্ͷΑ͏ʹఆٛͰ͖Δ
    ‣ :args :ret͕ͦΕͧΕࣄલ৚݅ɾࣄޙ৚݅ʹରԠ
    (s/fdef fizzbuzz
    :args (s/cat :n (s/and integer? #(> % 0)))
    :ret (s/or :int integer? :key keyword?))
    (defn fizzbuzz [n]
    (cond (= (mod n 15) 0) :fizzbuzz
    (= (mod n 5) 0) :buzz
    (= (mod n 3) 0) “fizz” ;;←όά
    :else n))

    View Slide

  22. JOTUSVNFOU
    ‣ ؔ਺ʹҾ਺͕εϖοΫΛຬ͍ͨͯ͠Δ͔ͷνΣοΫ
    ΛΦϯɾΦϑͰ͖Δ
    user=> (require ‘[clojure.spec.test :as t])
    nil
    user=> (t/instrument)
    [user/fizzbuzz]
    user=> (fizzbuzz 15)
    “fizzbuzz”
    user=> (fizzbuzz “foo”)
    ExceptionInfo Call to #'user/fizzbuzz did not conform to
    spec:
    In: [0] val: "foo" fails at: [:args :n] predicate: integer?
    :clojure.spec/args ("foo") …
    user=>

    View Slide

  23. DIFDL
    ‣ Ҿ਺ͷεϖοΫΛຬͨ͢஋Λࣗಈੜ੒ͯ͠ɺͦͷ஋Λؔ਺ʹ
    ౉ͨ݁͠Ռ͕໭Γ஋ͷεϖοΫΛຬ͔ͨ͢νΣοΫ͢Δ
    user=> (t/check)
    ({:spec …
    :clojure.spec.test.check/ret
    {:result
    #error {:cause "Specification-based check failed”
    :data {:clojure.spec/problems
    (… {:path [:ret :key],
    :pred keyword?,
    :val “fizz",
    :via [], :in [],
    :clojure.spec.test/args (3),
    :clojure.spec/failure :check-failed}…)}
    user=>

    View Slide

  24. DIFDL
    ‣ Ҿ਺ͷεϖοΫΛຬͨ͢஋Λࣗಈੜ੒ͯ͠ɺͦͷ஋Λؔ਺ʹ
    ౉ͨ݁͠Ռ͕໭Γ஋ͷεϖοΫΛຬ͔ͨ͢νΣοΫ͢Δ
    user=> (t/check)
    ({:spec …
    :clojure.spec.test.check/ret
    {:result
    #error {:cause "Specification-based check failed”
    :data {:clojure.spec/problems
    (… {:path [:ret :key],
    :pred keyword?,
    :val “fizz",
    :via [], :in [],
    :clojure.spec.test/args (3),
    :clojure.spec/failure :check-failed}…)}
    user=>
    Ͱݺͼग़ͨ͠ͱ͖ʹ
    ࣦഊ͢Δ͜ͱΛݕग़

    View Slide

  25. DMPKVSFTQFDʹΑΔ
    ϓϩύςΟϕʔεςετ

    View Slide

  26. ϓϩύςΟϕʔεςετͱ͸
    ‣ ී௨ͷςετ FYBNQMFCBTFEUFTUJOH
    ͷΑ͏ʹɺ
    ۩ମతͳςετέʔεʹର͢ΔςετͰ͸ͳ͘ɺ೚
    ҙͷೖྗʹରͯ͠੒Γཱͭੑ࣭Λهड़ͨ͠ςετ
    ‣ ೖྗ஋ͷϥϯμϜʹͨ͘͞Μੜ੒͠ɺͦͷ஋ʹର͠
    ͯςετΛ࣮ߦ͢Δ
    ‣ )BTLFMMͷ2VJDL$IFDL͕༗໊
    ‣ $MPKVSFͰ͸UFTUDIFDLΛ࢖͏ͷ͕ελϯμʔυ

    View Slide

  27. p[[CV[[ؔ਺ͷςετ
    ‣ εϖοΫΛຬͨ͢஋Λࣗಈੜ੒͠ɺ͢΂ͯͷ஋ʹର
    ͯ͠ੑ࣭͕੒Γཱ͔ͭͲ͏͔νΣοΫ͢Δ
    (ns fizzbuzz-test
    (:require [clojure.test.check.clojure-test :refer [defspec]]
    [clojure.test.check.properties :as prop]
    [clojure.spec :as s]
    [fizzbuzz :as fb]))
    (defspec fizzbuzz-prop
    (prop/for-all [n (s/gen (s/and integer? #(> % 0)))]
    (let [v (fb/fizzbuzz n)]
    (cond (= (mod n 3) 0) (contains? #{:fizz :fizzbuzz} v)
    (= (mod n 5) 0) (contains? #{:buzz :fizzbuzz} v)
    :else (= n v)))))

    View Slide

  28. ·ͱΊ
    ‣ DMPKVSFTQFD͸σʔλܕ΍ؔ਺ͷ࢓༷Λड़ޠͷ૊Έ
    ߹ΘͤͰهड़͢Δํ๏Λఏڙ͢Δ
    ‣ Ұ౓εϖοΫΛॻ͘ͱɺίʔσΟϯάத͚ͩͰͳ͘ɺ
    υΩϡϝϯςʔγϣϯ΍ςετ౳ʹ΋໾ཱͯΒΕΔ
    ‣ $MPKVSFͷ૊ࠐΈؔ਺ʹର͢ΔεϖοΫ͕༻ҙ͞Ε
    Ε͹Τϥʔϝοηʔδ΋վળ͞ΕΔ͔΋ʁ

    View Slide

  29. ࠓ೔࿩͞ͳ͔ͬͨ͜ͱ
    ‣ TDPOGPSN
    ‣ γʔέϯεʹର͢ΔεϖοΫ
    ‣ εϖοΫʹΑΔϚΫϩͷߏจղੳ
    ଓ͖͸ͷ-JTQNFFUVQͰʂʂ

    View Slide