anchor.diff:  ;; Fails required key check
   (s/explain ::person
     {::first-name "Elon"})
  -;; val: {:my.domain/first-name "Elon"} fails spec: :my.domain/person 
  +;; val: #:my.domain{:first-name "Elon"} fails spec: :my.domain/person
   ;;  predicate: [(contains? % :my.domain/last-name) (contains? % :my.domain/email)]
   
   ;; Fails attribute conformance
  
positive.code: 
  [source,clojure]
  ----
  (stest/check-var #'ranged-rand)
  ;;{:result {:clojure.spec/problems {[] {:pred (>= (:ret %) (-> % :args :start)),
  ;;                                      :val {:args {:start -1, :end 3}, :ret -3},
  ;;                                      :via [],
  ;;                                      :in []}},
  ;;          :failed-on :fn},
  ;; :seed 1466023411366,
  ;; :failing-size 0,
  ;; :num-tests 1,
  ;; :fail [(-1 3)],
  ;; :shrunk {:total-nodes-visited 2,
  ;;          :depth 1,
  ;;          :result {:clojure.spec/problems {[] {:pred (>= (:ret %) (-> % :args :start)),
  ;;                                               :val {:args {:start 0, :end 3}, :ret -2},
  ;;                                               :via [],
  ;;                                               :in []}},
  ;;                   :failed-on :fn},
  ;;          :smallest [(0 3)]}}
  ----
  
  `test` has reported an error in the `:fn` spec. We can see the arguments passed were -1 and 3 and the return value was -3, which is out of the expected range. At the bottom, test.check takes one step further though and "shrinks" the invalid inputs to find simpler/smaller inputs that yield the same error. Here the "simpler" inputs were 0 and 3, which is not much different, but on complicated data, shrinking is a killer feature for finding failing examples.
  
  == Wrapping Up
  
  
negative.code: ;=> true
  (s/explain :event/event
    {:event/type :event/restart})
  ;; val: #:event{:type :event/restart} fails spec: :event/event 
  ;;   at: [:event/restart] predicate: my.domain/event-type,  no method
  (s/explain :event/event
    {:event/type :event/search
     :search/url 200})
  ;; val: {:event/type :event/search, :search/url 200} fails spec: :event/event 
  ;;   at: [:event/search] predicate: [(contains? % :event/timestamp)]
  ;; In: [:search/url] val: 200 fails spec: :search/url 
  ;;   at: [:event/search :search/url] predicate: string?
  ----
  
  The `multi-spec` approach allows us to create an *open* system for spec validation, just like multimethods and protocols. New event types can be added later by just extending the `event-type` multimethod.
  