This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-02
Channels
- # aleph (6)
- # beginners (57)
- # boot (1)
- # cider (27)
- # clara (23)
- # cljs-dev (166)
- # clojure (287)
- # clojure-dev (23)
- # clojure-greece (1)
- # clojure-italy (2)
- # clojure-russia (13)
- # clojure-spec (34)
- # clojure-uk (36)
- # clojurescript (68)
- # core-async (63)
- # core-logic (1)
- # cursive (1)
- # data-science (1)
- # datomic (26)
- # duct (1)
- # emacs (10)
- # figwheel (8)
- # fulcro (2)
- # garden (16)
- # graphql (8)
- # hoplon (20)
- # jobs (2)
- # leiningen (10)
- # off-topic (16)
- # onyx (2)
- # portkey (5)
- # quil (1)
- # re-frame (63)
- # reagent (95)
- # reitit (6)
- # remote-jobs (1)
- # ring (6)
- # rum (1)
- # shadow-cljs (76)
- # spacemacs (26)
- # specter (11)
- # sql (7)
- # unrepl (68)
- # vim (2)
- # yada (2)
I don’t really understand why Cloujre spec is any better than simple pre conditions for simple validation. example:
(defn mk-protobuf
[{:keys [reward-value available event-uri event-name event-at schema revision
hostname fake environment shopper-uri service-agent shopper-name reward-uri reward-name action-at]
:or {service-agent service-agent
hostname (hostname)
environment (str env)
event-at (c/to-epoch (t/now))
schema (str schema)}}]
:pre [(string? event-uri)
(string? reward-uri)
(string? shopper-uri)
(string? reward-value)
(instance? Boolean available)]
won’t these preconditions be sufficient run time validation? what willl i get from spec that i cant get from these?docs, generated examples, automated generative testing
@ben.borders what’s the error message if you pass in something incorrect? What if one of the args was not just a string, but, say, a vector of strings?
ex:
Exception in thread "async-dispatch-12" java.lang.AssertionError: Assert failed: (integer? event-uri)
I think the different may be starker if you pass in nested data e.g. a vector of maps that must contain keys
but for simpler predicates like string?
(as in your example), the differences in error messages won’t be as significant
I don’t recall what exactly but this ended up causing trouble for me down the line (maybe it was nested is
? I don’t remember now)
and get things like
;FAIL in clojure.lang.PersistentList$EmptyList@1 (scratch.clj:5)
;expected: (string? s1)
;actual: (not (string? 10))
Yes, although it becomes a little less clear for nested data e.g. a vector of strings
@ben.borders np. here’s an example of error message with is
vs explain
(using expound) https://gist.github.com/bhb/44d68a7ab878187b68d4fd48579d591b
I copied and pasted from my REPL session and omitted my mistakes, so hopefully I didn’t miss anything important 😉
so then to get the same desired runtime validation, would it be advised to place s/valid? in the :pre block of the function? or are there better ways to do this?
i’ll probably end up exploring this.. it does indeed seem to be much better self documenting
gotcha. and for speccing the example map above, would i have to create an s/def for every key in the map? for example some of the keys in the map should contain the same type and structure of data, so it would be nice to reuse something like
(s/def ::non-empty-string not-empty string?)
for multiple keys instead of (s/def thing1 ::nonempty-string) (s/def thing2 ::Nonempty-string
yes, you will need one for every key
that puts it in the spec registry which is used by s/keys
if you have many repetitive such things, macros can help
maybe eventually we’ll provide something to def multiple things at a time