This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-03-28
Channels
- # aleph (48)
- # announcements (3)
- # bangalore-clj (1)
- # beginners (131)
- # cider (30)
- # cljdoc (6)
- # cljs-dev (53)
- # cljsrn (24)
- # clojure (312)
- # clojure-austin (2)
- # clojure-europe (4)
- # clojure-finland (6)
- # clojure-nl (24)
- # clojure-spec (24)
- # clojure-uk (66)
- # clojurescript (185)
- # core-async (46)
- # cursive (10)
- # data-science (9)
- # datomic (15)
- # devcards (2)
- # emacs (50)
- # fulcro (28)
- # jobs (1)
- # jobs-discuss (2)
- # kaocha (11)
- # lein-figwheel (12)
- # nyc (1)
- # off-topic (105)
- # other-languages (80)
- # pedestal (6)
- # re-frame (50)
- # reagent (5)
- # reitit (1)
- # remote-jobs (2)
- # ring (10)
- # rum (1)
- # shadow-cljs (10)
- # spacemacs (19)
@ikitommi If you want to always validate, also in prod, why not use s/valid?
for this?
or if you don’t like using s/get-spec
you can write the args spec separately and use that in fdef
, you’ll still get the docstring
we use s/valid?
in asserts for things that should never happen and both s/valid?
and s/conform
in control flow (`if`, condp
, match
, etc). not advocating to do that, but sharing a related need we felt and what we’re trying out to address it
user=> (s/fdef foo :args (s/cat :i int?))
user/foo
user=> (def args-spec (:args (s/get-spec `foo)))
#'user/args-spec
user=> (defn foo [i] (if (s/valid? args-spec [i]) i (throw (ex-info "n00" (s/explain-data args-spec [i])))))
#'user/foo
user=> (foo 1)
1
user=> (foo "1")
Execution error - invalid arguments to user/foo at (REPL:1).
"1" - failed: int? at: [:i]
@borkdude thanks! looks just right. In my case, it's a framework calling the specced functions at runtime, so I can use apply
& args to make a generic functional proxy.
... or just extract the function spec if that exist and validate by the framework. indeed.
that said, tempted to add an s/defn
with identical syntax as Schema somewhere. There are several ones (all bit different) out there already. The Lisp Curse?
fwiw, I think we’re probably going to add something with spec 2 (or maybe Clojure 1.11)
I like https://github.com/Provisdom/defn-spec syntax as it's friendly out-of-the-box to Cursive IDE (specs are defined inside defn metadata). but maybe orchestra's macro is also supported by Cursive
The other day, I asked a question about speccing Java object fields
https://clojurians.slack.com/archives/C1B1BB2Q3/p1553612761304000
I thought I'd check back in, and say that I got intimate with s/conformer
! My solution is to use a conformer to convert the Java object into a clojure map of {<fieldname-keyword> <field-value>}
, and then just use s/keys
(s/def ::device (s/and (s/conformer (conform-java-fields ::summary #(.getSummary %)
::report #(.getReport %)))
(s/keys :req [::summary ::report])))
I learnt something! 🙂note that this spec won't work backwards with unform though
in general, this kind of thing is frowned upon as it bakes transformation into the spec and doesn't give registry consumers the option of whether to do the transformation. I would probably recommend to instead actually convert the objects to Clojure data, then use simple data specs on it.
So, doing the transformation in code, instead of within a spec?
conformer was really imagined primarily as a tool for spec op creators, not for api users
OK, that makes sense. Thanks for the advice. I'm making progress
re: https://clojurians.slack.com/archives/C1B1BB2Q3/p1553807158018600 it would be nice if spec offered a bit more integration between fdef args and defn args somehow
well the big thing likely here is to integrate the requires/provides semantics via select, and also to introduce a way to talk about returns in terms of args more descriptively. the :ret/:fn as it stands now is likely to change