This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-11
Channels
- # bangalore-clj (1)
- # beginners (24)
- # boot (134)
- # boulder-clojurians (2)
- # cider (3)
- # cljs-dev (2)
- # cljsjs (44)
- # clojars (9)
- # clojure (60)
- # clojure-greece (2)
- # clojure-quebec (1)
- # clojure-russia (44)
- # clojure-spec (15)
- # clojure-uk (1)
- # clojurescript (37)
- # core-matrix (1)
- # datomic (7)
- # emacs (1)
- # hoplon (154)
- # liberator (3)
- # mount (2)
- # om (20)
- # onyx (2)
- # pedestal (3)
- # planck (12)
- # re-frame (26)
- # reagent (32)
- # uncomplicate (4)
I’m going through the spec tutorial on http://clojure.org . Is there any difference between using spec/or
and using spec/alt
? It seems to work the same for the example from the tutorial:
`
(s/def ::config-alt (s/*
(s/cat :prop string?
:val (s/alt :s string?
:b boolean?))))
;;=> :testspec.core/config-alt
(s/conform ::config-alt [ "-server" "foo"
"-verbose" true
"-user" "joe"])
;;=> [{:prop "-server", :val [:s "foo"]} {:prop "-verbose", :val [:b true]} {:prop "-user", :val [:s "joe"]}]
(s/def ::config-or (s/*
(s/cat :prop string?
:val (s/or :s string?
:b boolean?))))
;;=> :testspec.core/config-or
(s/conform ::config-or [ "-server" "foo"
"-verbose" true
"-user" "joe"])
;;=> [{:prop "-server", :val [:s "foo"]} {:prop "-verbose", :val [:b true]} {:prop "-user", :val [:s "joe"]}]`
Yes (although there are situations where they can yield the same result)
in this particular example we are describing the structure of a sequential thing and regex ops are being used to specify that structure
s/alt is the proper choice here as it is the regex op version
it matters in the context where it is used - when used inside another regex op, it does not start a new nested context, rather it matches elements out of the current context
however s/or is effectively opaquely matching a value
so an example where alt works but or does not is:
user=> (s/def ::a (s/alt :i int? :s (s/cat :a string? :b string?)))
:user/a
user=> (s/conform ::a [1])
[:i 1]
user=> (s/conform ::a ["a" "b"])
[:s {:a "a", :b "b”}]
here an alt by itself implies a sequential context but that’s not true with s/or
but the nested s/cat does (b/c also a regex op):
user=> (s/def ::o (s/or :i int? :s (s/cat :a string? :b string?)))
:user/o
user=> (s/conform ::o 5) ;; note 5 is a bare value, not in a collection
[:i 5]
user=> (s/conform ::o ["a" "b"])
[:s {:a "a", :b "b”}]
and you can nest an alt inside another regex without requiring a new sequential context:
user=> (s/conform (s/cat :k keyword? :nested-a ::a) [:foo 5])
{:k :foo, :nested-a [:i 5]}
user=> (s/conform (s/cat :k keyword? :nested-a ::a) [:foo "a" "b"])
{:k :foo, :nested-a [:s {:a "a", :b "b"}]}
here ::a is embedded inside something else but just describes more elements of the sequence
Thanks @alexmiller! The guide to spec is great so far, will keep working through it!