anchor.diff:  [source,clojure]
   ----
   (s/explain-data ::name-or-id :foo)
  -;;=> {:clojure.spec/problems
  -;;    {[:name] {:pred string?, :val :foo, :via []},
  -;;     [:id] {:pred int?, :val :foo, :via []}}}
  -----
  -
  -We'll see some more examples later on.
  -
  -== Sequences
  -
  -Spec provides the standard https://en.wikipedia.org/wiki/Regular_expression[regular expression] operators to describe the structure of a sequential data value:
  -
  -* http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/cat[`cat`] - concatentation of predicates/patterns
  -* http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/alt[`alt`] - choice among alternative predicates/patterns
  -* http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/*[`pass:[*]`] - 0 or more of a predicate/pattern
  -* http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/%2B[`+`] - 1 or more of a predicate/pattern
  -* http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/%3F[`?`] - 0 or 1 of a predicate/pattern
  -
  -Like `or`, both `cat` and `alt` tag their "parts" - these tags are then used in the conformed value to identify what was matched, to report errors, and more.
  -
  -Consider an ingredient represented by a vector containing a quantity (number) and a unit (keyword). The spec for this data uses `cat` to specify the right components in the right order. Like predicates, regex operators are implicitly converted to specs when passed to functions like `conform`, `valid?`, etc.
  -
  -[source,clojure]
  -----
  -(s/def ::ingredient (s/cat :quantity number? :unit keyword?))
  -(s/conform ::ingredient [2 :teaspoon])
  -;;=> {:quantity 2, :unit :teaspoon}
  -----
  -
  -The data is conformed as a map with the tags as keys. We can use `explain` to examine non-conforming data.
  -
  -[source,clojure]
  -----
  -;; pass string for unit instead of keyword
  -(s/explain ::ingredient [11 "peaches"])
  -;; In: [1] val: \"peaches\" fails spec: ::ingredient at: [:unit] predicate: keyword?
  -
  -;; leave out the unit
  -(s/explain ::ingredient [2])
  -;; val: () fails spec: ::ingredient at: [:unit] predicate: keyword?,  Insufficient input
  -----
  -
  -Let's now see the various occurence operators `*`, `+`, and `?`:
  -
  -[source,clojure]
  -----
  -(s/def ::seq-of-keywords (s/* keyword?))
  -(s/conform ::seq-of-keywords [:a :b :c])
  -;;=> [:a :b :c]
  -(s/explain ::seq-of-keywords [10 20])
  -;; In: [0] val: 10 fails spec: :spec.examples.guide/seq-of-keywords predicate: keyword?
  -
  -(s/def ::odds-then-maybe-even (s/cat :odds (s/+ odd?)
  -                                     :even (s/? even?)))
  -(s/conform ::odds-then-maybe-even [1 3 5 100])
  -;;=> {:odds [1 3 5], :even 100}
  -(s/conform ::odds-then-maybe-even [1])
  -;;=> {:odds [1]}
  -(s/explain ::odds-then-maybe-even [100])
  -;; In: [0] val: 100 fails spec: :spec.examples.guide/odds-then-maybe-even at: [:odds] predicate: odd?
  -
  -;; opts are alternating keywords and booleans
  -(s/def ::opts (s/* (s/cat :opt keyword? :val boolean?)))
  -(s/conform ::opts [:silent? false :verbose true])
  -;;=> [{:opt :silent?, :val false} {:opt :verbose, :val true}]
  -----
  -
  -Finally, we can use `alt` to specify alternatives within the sequential data. Like `cat`, `alt` requires you to tag each alternative but the conformed data is a vector of tag and value.
  -
  -[source,clojure]
  -----
  -(s/def ::config (s/* 
  -                  (s/cat :prop string?
  -                         :val  (s/alt :s string? :b boolean?))))
  -(s/conform ::config ["-server" "foo" "-verbose" true "-user" "joe"])
  -;;=> [{:prop "-server", :val [:s "foo"]}
  -;;    {:prop "-verbose", :val [:b true]}
  -;;    {:prop "-user", :val [:s "joe"]}]
  -----
  -
  -If you need a description of a specification, use `describe` to retrieve one. Let's try it on some of the specifications we've already defined:
  -
  -[source,clojure]
  -----
  -(s/describe ::seq-of-keywords)
  -;;=> (* keyword?)
  -(s/describe ::odds-then-maybe-even)
  -;;=> (cat :odds (+ odd?) :even (? even?))
  -(s/describe ::opts)
  -;;=> (* (cat :opt keyword? :val boolean?))
  -----
  -
  -Spec also defines one additional regex operator, http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/&[`&`], which takes a regex operator and constrains it with one or more additional predicates. This can be used to create regular expressions with additional constraints that would otherwise require custom predicates. For example, consider wanting to match only sequences with an even number of strings:
  -
  -[source,clojure]
  -----
  -(s/def ::even-strings (s/& (s/* string?) #(even? (count %))))
  -(s/valid? ::even-strings ["a"])  ;; false
  -(s/valid? ::even-strings ["a" "b"])  ;; true
  -(s/valid? ::even-strings ["a" "b" "c"])  ;; false
  -(s/valid? ::even-strings ["a" "b" "c" "d"])  ;; true
  -----
  -
  -When regex ops are combined, they describe a single sequence. If you need to spec a nested sequential collection,
  -you must use an explicit call to http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/spec[`spec`]
  -to start a new nested regex context. For example to describe a sequence like `[:names ["a" "b"] :nums [1 2 3]]`,
  -you need nested regular expressions to describe the inner sequential data:
  -
  -[source,clojure]
  -----
  -(s/def ::nested
  -  (s/cat :names-kw #{:names}
  -         :names (s/spec (s/* string?))
  -         :nums-kw #{:nums}
  -         :nums (s/spec (s/* number?))))
  -(s/conform ::nested [:names ["a" "b"] :nums [1 2 3]])
  -;;=> {:names-kw :names, :names ["a" "b"], :nums-kw :nums, :nums [1 2 3]}
  -----
  -
  -If the specs were removed this spec would instead match a sequence like `[:names "a" "b" :nums 1 2 3]`.
  -
  -[source,clojure]
  -----
  -(s/def ::unnested
  -  (s/cat :names-kw #{:names}
  -         :names (s/* string?)
  -         :nums-kw #{:nums}
  -         :nums (s/* number?)))
  -(s/conform ::unnested [:names "a" "b" :nums 1 2 3])
  -;;=> {:names-kw :names, :names ["a" "b"], :nums-kw :nums, :nums [1 2 3]}
  -----
  +;;=> #:clojure.spec{
  +;;     :problems ({:path [:name], 
  +;;                 :pred string?,
  +;;                 :val :foo,
  +;;                 :via [:spec.examples.guide/name-or-id],
  +;;                 :in []}
  +;;                {:path [:id],
  +;;                 :pred int?,
  +;;                 :val :foo,
  +;;                 :via [:spec.examples.guide/name-or-id],
  +;;                 :in []})}
  +----
  +
  +[NOTE]
  +====
  +This result also demonstrates the new namespaced map syntax added in 1.9.0-alpha8. Maps may be prefixed with #: or #:: (for autoresolve) to specify a default namespace for all keys in the map. In this example, this is equivalent to `{:clojure.spec/problems ...}`
  +====
   
   == Entity Maps
   
  
positive.code: 
  A few helpers are provided for other special collection cases - http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/coll-of[`coll-of`], http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/tuple[`tuple`], and  http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/map-of[`map-of`].
  
  For the special case of a homogenous collection of arbitrary size, you can use `coll-of` to specify a collection of elements satisfying a predicate. `coll-of` must be provided a seed collection to use when generating elements - something like `[]`, `()`, or `(sorted-set)`.
  
  [source,clojure]
  ----
  (s/conform (s/coll-of keyword? []) [:a :b :c])
  ;;=> [:a :b :c]
  (s/conform (s/coll-of number? #{}) #{5 10 2})
  ;;=> #{2 5 10}
  ----
  
  [NOTE]
  ====
  Both `coll-of` and `map-of` will conform all of their elements, which may make them unsuitable for large collections. In that case, consisder http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/every[`every`] and http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/every-kv[`every-kv`], which will only sample their inputs and have additional controls for checking collection size and whether the elements are distinct.
  ====
  
  While `coll-of` is good for homogenous collections of any size, another case is a fixed-size positional collection with fields of known type at different positions. For that we have `tuple`.
  
negative.code: 
  [source,clojure]
  ----
  (stest/abbrev-result (first (stest/test `ranged-rand)))
  ;;=> ({:spec (fspec
  ;;            :args (and (cat :start int? :end int?) (fn* [p1__3468#] (< (:start p1__3468#) (:end p1__3468#))))
  ;;            :ret int?
  ;;            :fn (and
  ;;                  (fn* [p1__3469#] (>= (:ret p1__3469#) (-> p1__3469# :args :start)))
  ;;                  (fn* [p1__3470#] (< (:ret p1__3470#) (-> p1__3470# :args :end))))),
  ;;     :sym spec.examples.guide/ranged-rand,
  ;;     :result {:clojure.spec/problems [{:path [:fn],
  ;;                                       :pred (>= (:ret %) (-> % :args :start)),
  ;;                                       :val {:args {:start -3, :end 0}, :ret -5},
  ;;                                       :via [],
  ;;                                      :in []}],
  ;;              :clojure.spec.test/args (-3 0),
  ;;              :clojure.spec.test/val {:args {:start -3, :end 0}, :ret -5},
  ;;              :clojure.spec/failure :test-failed}}
  ----
  
  `test` has reported an error in the `:fn` spec. We can see the arguments passed were -3 and 0 and the return value was -5, which is out of the expected range.
  
  == Wrapping Up
  
  