Slide 1

Slide 1 text

DMPKVSFTQFDͷ࿩ -JTQNFFUVQ !BUIPT

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

DMPKVSFTQFDͷ࢖͍ํ ‣ [org.clojure/clojure “1.9.0-alphaXX”] Λ:dependenciesʹ௥Ճ ‣ ࠷৽൛͸BMQIB ݱࡏ ‣ (require ‘[clojure.spec :as s])

Slide 5

Slide 5 text

όϦσʔλͱͯ͠ͷ DMPKVSFTQFD

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

WBMJE FYQMBJO ‣ valid?͸εϖοΫΛຬ͔ͨ͢Ͳ͏͔Λฦ͢ ‣ explain͸εϖοΫΛຬͨ͞ͳ͍ՕॴΛࢦఠ͢Δ user=> (s/valid? integer? “foo”) false user=> (s/explain integer? “foo”)

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

WBMJE FYQMBJO ‣ valid?͸εϖοΫΛຬ͔ͨ͢Ͳ͏͔Λฦ͢ ‣ explain͸εϖοΫΛຬͨ͞ͳ͍ՕॴΛࢦఠ͢Δ 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 user=>

Slide 12

Slide 12 text

εϖοΫͷ߹੒ ‣ and΍orΛ࢖ͬͯෳ਺ͷεϖοΫΛ૊Έ߹ΘͤՄೳ user=> (s/valid? (s/and integer? even?) 0) true user=> (s/valid? (s/and integer? even?) 1) false

Slide 13

Slide 13 text

εϖοΫͷ߹੒ ‣ and΍orΛ࢖ͬͯෳ਺ͷεϖοΫΛ૊Έ߹ΘͤՄೳ 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”)

Slide 14

Slide 14 text

εϖοΫͷ߹੒ ‣ and΍orΛ࢖ͬͯෳ਺ͷεϖοΫΛ૊Έ߹ΘͤՄೳ 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 user=>

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

εϖοΫʹ໊લΛ͚ͭΔ ‣ defͰεϖοΫʹ໊લΛ͚ͭΔ͜ͱ͕Ͱ͖Δ ‣ εϖοΫࣗମΛ࠶ར༻Ͱ͖Δ 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)

Slide 17

Slide 17 text

εϖοΫʹ໊લΛ͚ͭΔ ‣ defͰεϖοΫʹ໊લΛ͚ͭΔ͜ͱ͕Ͱ͖Δ ‣ εϖοΫࣗମΛ࠶ར༻Ͱ͖Δ 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 user=>

Slide 18

Slide 18 text

ίϨΫγϣϯͷεϖοΫ ‣ coll-ofmap-ofͰίϨΫγϣϯͷཁૉ͕εϖοΫ Λຬ͍ͨͯ͠Δ͔νΣοΫͰ͖Δ user=> (s/valid? (s/coll-of integer?) [1 2 3])

Slide 19

Slide 19 text

ίϨΫγϣϯͷεϖοΫ ‣ coll-ofmap-ofͰίϨΫγϣϯͷཁૉ͕εϖοΫ Λຬ͍ͨͯ͠Δ͔νΣοΫͰ͖Δ user=> (s/valid? (s/coll-of integer?) [1 2 3]) true user=> (s/valid? (s/coll-of integer?) [1 :a])

Slide 20

Slide 20 text

ίϨΫγϣϯͷεϖοΫ ‣ 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})

Slide 21

Slide 21 text

ίϨΫγϣϯͷεϖοΫ ‣ 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”})

Slide 22

Slide 22 text

ίϨΫγϣϯͷεϖοΫ ‣ 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 user=>

Slide 23

Slide 23 text

ίϨΫγϣϯͷεϖοΫ ‣ ΩʔʹΑͬͯ஋ͷܕ͕ҧ͏ϚοϓͷεϖοΫ΋ఆٛՄೳ 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})

Slide 24

Slide 24 text

ίϨΫγϣϯͷεϖοΫ ‣ ΩʔʹΑͬͯ஋ͷܕ͕ҧ͏ϚοϓͷεϖοΫ΋ఆٛՄೳ 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”})

Slide 25

Slide 25 text

ίϨΫγϣϯͷεϖοΫ ‣ ΩʔʹΑͬͯ஋ͷܕ͕ҧ͏ϚοϓͷεϖοΫ΋ఆٛՄೳ 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 user=>

Slide 26

Slide 26 text

%C$πʔϧͱͯ͠ͷ DMPKVSFTQFD

Slide 27

Slide 27 text

ؔ਺ͷεϖοΫ ‣ 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))

Slide 28

Slide 28 text

JOTUSVNFOU ‣ ؔ਺ʹҾ਺͕εϖοΫΛຬ͍ͨͯ͠Δ͔ͷνΣοΫ ΛΦϯɾΦϑͰ͖Δ user=> (require ’[clojure.spec.test :as t]) nil user=> (t/instrument)

Slide 29

Slide 29 text

JOTUSVNFOU ‣ ؔ਺ʹҾ਺͕εϖοΫΛຬ͍ͨͯ͠Δ͔ͷνΣοΫ ΛΦϯɾΦϑͰ͖Δ user=> (require ’[clojure.spec.test :as t]) nil user=> (t/instrument) [user/fizzbuzz] user=> (fizzbuzz 15)

Slide 30

Slide 30 text

JOTUSVNFOU ‣ ؔ਺ʹҾ਺͕εϖοΫΛຬ͍ͨͯ͠Δ͔ͷνΣοΫ ΛΦϯɾΦϑͰ͖Δ user=> (require ’[clojure.spec.test :as t]) nil user=> (t/instrument) [user/fizzbuzz] user=> (fizzbuzz 15) “fizzbuzz” user=> (fizzbuzz “foo”)

Slide 31

Slide 31 text

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=>

Slide 32

Slide 32 text

DIFDL ‣ Ҿ਺ͷεϖοΫΛຬͨ͢஋Λࣗಈੜ੒ͯ͠ɺͦͷ஋Λؔ਺ʹ ౉ͨ݁͠Ռ͕໭Γ஋ͷεϖοΫΛຬ͔ͨ͢νΣοΫ͢Δ user=> (t/check)

Slide 33

Slide 33 text

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=>

Slide 34

Slide 34 text

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=> Ͱݺͼग़ͨ͠ͱ͖ʹ ࣦഊ͢Δ͜ͱΛݕग़

Slide 35

Slide 35 text

͕࣌ؒ͋Γͦ͏ͳΒ Ԡ༻ྫΛ঺հ

Slide 36

Slide 36 text

δΣωϨʔλͱͯ͠ͷ DMPKVSFTQFD

Slide 37

Slide 37 text

HFO ‣ εϖοΫ͔ΒUFTUDIFDL༻ͷδΣωϨʔλΛ࡞Δ ‣ εϖοΫΛຬͨ͢ϥϯμϜͳ஋Λੜ੒Ͱ͖Δ ‣ 3&1-Ͱαϯϓϧσʔλ͕΄͍͠ͱ͖ʹศར user=> (require ’[clojure.test.check.generators :as gen]) nil user=> (gen/generate (s/gen (s/coll-of integer?)))

Slide 38

Slide 38 text

HFO ‣ εϖοΫ͔ΒUFTUDIFDL༻ͷδΣωϨʔλΛ࡞Δ ‣ εϖοΫΛຬͨ͢ϥϯμϜͳ஋Λੜ੒Ͱ͖Δ ‣ 3&1-Ͱαϯϓϧσʔλ͕΄͍͠ͱ͖ʹศར user=> (require ’[clojure.test.check.generators :as gen]) nil user=> (gen/generate (s/gen (s/coll-of integer?))) [16719156 -26693 47] user=> (gen/generate (s/gen (s/coll-of integer?)))

Slide 39

Slide 39 text

HFO ‣ εϖοΫ͔ΒUFTUDIFDL༻ͷδΣωϨʔλΛ࡞Δ ‣ εϖοΫΛຬͨ͢ϥϯμϜͳ஋Λੜ੒Ͱ͖Δ ‣ 3&1-Ͱαϯϓϧσʔλ͕΄͍͠ͱ͖ʹศར user=> (require ’[clojure.test.check.generators :as gen]) nil user=> (gen/generate (s/gen (s/coll-of integer?))) [16719156 -26693 47] user=> (gen/generate (s/gen (s/coll-of integer?))) [-158637744 -8 -461005 -238354 59127 -4365] user=>

Slide 40

Slide 40 text

HFOΛ࢖ͬͨϓϩύςΟϕʔεςετ ‣ εϖοΫΛຬͨ͢஋Λࣗಈੜ੒͠ɺ͢΂ͯͷ஋ʹର ͯ͠ੑ࣭͕੒Γཱ͔ͭͲ͏͔νΣοΫ͢Δ (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)))))

Slide 41

Slide 41 text

ςετ࣮ߦ݁Ռ $ lein test

Slide 42

Slide 42 text

ςετ࣮ߦ݁Ռ $ lein test lein test fizzbuzz-test {:result false, :seed 1469711295643, :failing-size 4, :num- tests 5, :fail [96], :shrunk {:total-nodes-visited 6, :depth 5, :result false, :smallest [3]}, :test-var "fizzbuzz-prop"} lein test :only fizzbuzz-test/fizzbuzz-prop FAIL in (fizzbuzz-prop) (clojure_test.cljc:21) expected: result actual: false Ran 1 tests containing 1 assertions. 1 failures, 0 errors. Tests failed. $

Slide 43

Slide 43 text

ύʔαͱͯ͠ͷ DMPKVSFTQFD

Slide 44

Slide 44 text

γʔέϯεͷεϖοΫ SFHFY ‣ SFHFYͰཁૉͷฒͼʹରͯ͠εϖοΫΛఆٛͰ͖Δ user=> (s/valid? (s/* integer?) ’(1 2 3)) true user=> (s/valid? (s/alt :i integer? :s string?) ’(“foo”))

Slide 45

Slide 45 text

γʔέϯεͷεϖοΫ SFHFY ‣ SFHFYͰཁૉͷฒͼʹରͯ͠εϖοΫΛఆٛͰ͖Δ user=> (s/valid? (s/* integer?) ’(1 2 3)) true user=> (s/valid? (s/alt :i integer? :s string?) ’(“foo”)) true user=> (s/valid? (s/cat :i integer? :s string?) ’(1 “foo”))

Slide 46

Slide 46 text

γʔέϯεͷεϖοΫ SFHFY ‣ SFHFYͰཁૉͷฒͼʹରͯ͠εϖοΫΛఆٛͰ͖Δ user=> (s/valid? (s/* integer?) ’(1 2 3)) true user=> (s/valid? (s/alt :i integer? :s string?) ’(“foo”)) true user=> (s/valid? (s/cat :i integer? :s string?) ’(1 “foo”)) true user=> (s/valid? (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 3 “foo” “bar”))

Slide 47

Slide 47 text

γʔέϯεͷεϖοΫ SFHFY ‣ SFHFYͰཁૉͷฒͼʹରͯ͠εϖοΫΛఆٛͰ͖Δ user=> (s/valid? (s/* integer?) ’(1 2 3)) true user=> (s/valid? (s/alt :i integer? :s string?) ’(“foo”)) true user=> (s/valid? (s/cat :i integer? :s string?) ’(1 “foo”)) true user=> (s/valid? (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 3 “foo” “bar”)) true user=>

Slide 48

Slide 48 text

DPOGPSN ‣ εϖοΫʹ͕ͨͬͯ͠σʔλΛύʔε͢Δ ‣ ύʔεʹࣦഊͨ͠Β:clojure.spec/invalid͕ฦΔ user=> (s/conform (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 3 “foo” “bar”))

Slide 49

Slide 49 text

DPOGPSN ‣ εϖοΫʹ͕ͨͬͯ͠σʔλΛύʔε͢Δ ‣ ύʔεʹࣦഊͨ͠Β:clojure.spec/invalid͕ฦΔ user=> (s/conform (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 3 “foo” “bar”)) {:i* [1 2 3], :s* ["foo" "bar"]} user=> (s/conform (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 “foo” 3 “bar”))

Slide 50

Slide 50 text

DPOGPSN ‣ εϖοΫʹ͕ͨͬͯ͠σʔλΛύʔε͢Δ ‣ ύʔεʹࣦഊͨ͠Β:clojure.spec/invalid͕ฦΔ user=> (s/conform (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 3 “foo” “bar”)) {:i* [1 2 3], :s* ["foo" "bar"]} user=> (s/conform (s/cat :i* (s/* integer?) :s* (s/* string?)) ’(1 2 “foo” 3 “bar”)) :clojure.spec/invalid user=>

Slide 51

Slide 51 text

ζϯυίΩϤγͷεϖοΫ (ns zundoko (:require [clojure.spec :as s])) (s/def ::zun*4-doko (s/cat :1 ’#{ζϯ} :2 ’#{ζϯ} :3 ’#{ζϯ} :4 ’#{ζϯ} :5 ’#{υί})) (s/def ::has-no-zun*4-doko? (fn [xs] (every? #(not (s/valid? ::zun*4-doko %)) (partition 5 1 xs)))) (s/def ::zun-doko-kiyoshi (s/cat :preamble (s/& (s/* ’#{ζϯ υί}) ::has-no-zun*4-doko?) :zun*4-doko ::zun*4-doko :kiyoshi ’#{ΩϤγ}))

Slide 52

Slide 52 text

ζϯυίΩϤγͷεϖοΫ user=> (s/conform ::zun-doko-kiyoshi ’(υί ζϯ υί ζϯ ζϯ ζϯ ζϯ υί ΩϤγ))

Slide 53

Slide 53 text

ζϯυίΩϤγͷεϖοΫ user=> (s/conform ::zun-doko-kiyoshi ’(υί ζϯ υί ζϯ ζϯ ζϯ ζϯ υί ΩϤγ)) {:preamble [υί ζϯ υί], :zun*4-doko {:1 ζϯ, :2 ζϯ, :3 ζϯ, :4 ζϯ, :5 υί}, :kiyoshi ΩϤγ} user=> (s/explain ::zun-doko-kiyoshi ’(υί ζϯ υί ζϯ ζϯ ζϯ ζϯ υί))

Slide 54

Slide 54 text

ζϯυίΩϤγͷεϖοΫ user=> (s/conform ::zun-doko-kiyoshi ’(υί ζϯ υί ζϯ ζϯ ζϯ ζϯ υί ΩϤγ)) {:preamble [υί ζϯ υί], :zun*4-doko {:1 ζϯ, :2 ζϯ, :3 ζϯ, :4 ζϯ, :5 υί}, :kiyoshi ΩϤγ} user=> (s/explain ::zun-doko-kiyoshi ’(υί ζϯ υί ζϯ ζϯ ζϯ ζϯ υί)) val: () fails spec: :zundoko/zun-doko-kiyoshi predicate: (alt), Insufficient input nil user=>

Slide 55

Slide 55 text

ϚΫϩͷߏจղੳ (s/def ::binding (s/cat :name simple-symbol? :init any?)) (s/def ::bindings (s/and (s/* ::binding) vector?)) (s/def ::with-open (s/cat :bindings ::bindings :body (s/* any?)) (s/fdef with-open :args ::with-open :ret any?) user=> (s/conform ::with-open ’([in (open-file)] (slurp in))) {:bindings [{:name in, :init (open-file)}], :body [(slurp in)]} user=>

Slide 56

Slide 56 text

ϚΫϩͷߏจղੳ (defmacro with-open [bindings & body] (let [[binding & more] (s/conform ::bindings bindings)] (if-not binding `(do ~@body) `(let ~[(:name binding) (:init binding)] (try (with-open ~(vec (s/unform ::bindings more)) ~@body) (finally (.close ~(:name binding)))))))) user=> (with-open [x] (slurp x)) ;;←ϚΫϩͷ࢖͍ํΛޡΔ CompilerException java.lang.IllegalArgumentException: Call to intro-to-spec.macros/with-open did not conform to spec: In: [0] val: () fails spec: :intro-to-spec.macros/bindings at: [:args :bindings :init] predicate: any?, Insufficient input :clojure.spec/args ([x] (slurp x)) , compiling:(*cider-repl intro-to-spec*:1476:22) user=>

Slide 57

Slide 57 text

·ͱΊ ‣ DMPKVSFTQFD͸σʔλܕ΍ؔ਺ͷ࢓༷Λड़ޠͷ૊Έ ߹ΘͤͰهड़͢Δํ๏Λఏڙ͢Δ ‣ Ұ౓εϖοΫΛॻ͘ͱɺؔ਺ͷόϦσʔγϣϯ͚ͩ Ͱͳ͘ɺ3&1-Ͱͷ։ൃ࣌ͷαϯϓϧσʔλੜ੒΍ ςετɺϚΫϩͷύʔε౳͍Ζ͍Ζ࢖͑Δ ‣ $MPKVSFʹ͓͚Δ։ൃͷ࢓ํ͕େ͖͘มΘΔՄೳੑ ͷ͋Δػೳ

Slide 58

Slide 58 text

ݱঢ়͸ʜ ‣ ·ͩBMQIBϦϦʔεͰ"1*͕มΘΓ·ͬͯ͘Δஈ֊ $MPKVSF4DSJQUͱͷ଍ฒΈ΋ଗͬͯͳ͍ ͷͰ࣮ઓ ౤ೖ͸ΘΓͱݫ͍͠ ௥هɿݱঢ়Ͱ͸$MPKVSFBMQIBͱ $MPKVSF4DSJQUͰ"1*Ϩϕϧͷޓ׵ੑ͕͋Δ໛༷ ‣ Τϥʔϝοηʔδ͸৘ใෆ଍ͷঢ়ଶ͸ղফ͞Ε͍ͯ Δ͕ɺݱঢ়Ͱ͸৘ใաଟͰҰݟͯ͠෼͔Γʹ͍͘ ศརʹ࢖͑ΔΑ͏ʹͳΔʹ͸։ൃ؀ڥଆͷαϙʔτ΋ඞཁ

Slide 59

Slide 59 text

ࢀߟจݙ ‣ DMPKVSFTQFD3BUJPOBMFBOE0WFSWJFX IUUQDMPKVSFPSHBCPVUTQFD ‣ TQFD(VJEF IUUQDMPKVSFPSHHVJEFTTQFD ‣ $PHOJDBTUDMPKVSFTQFDXJUI3JDI)JDLFZ IUUQCMPHDPHOJUFDUDPNDPHOJDBTU