This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-09
Channels
- # aleph (21)
- # architecture (5)
- # boot (25)
- # cider (1)
- # cljs-dev (115)
- # clojure (59)
- # clojure-brasil (3)
- # clojure-dev (4)
- # clojure-italy (20)
- # clojure-nl (2)
- # clojure-portugal (6)
- # clojure-russia (12)
- # clojure-spec (43)
- # clojure-uk (37)
- # clojurescript (76)
- # datomic (123)
- # emacs (3)
- # graphql (2)
- # hoplon (5)
- # jobs-discuss (1)
- # jobs-rus (4)
- # keechma (7)
- # lein-figwheel (13)
- # leiningen (7)
- # lumo (2)
- # off-topic (17)
- # om (6)
- # onyx (26)
- # parinfer (19)
- # planck (2)
- # re-frame (80)
- # reagent (9)
- # ring (1)
- # spacemacs (45)
- # testing (1)
- # vim (28)
@mrkaspa clojure.spec provides a basis for that sort of thing but leaves other tools to craft user friendly messages.
Expound is getting a bit of attention: https://github.com/bhb/expound
There are others.
The other JSON api consideration is that clojure.spec deals in clojure data structures (maps, sequences...) not javascript objects and arrays.
You can do something like js->clj to translate the data into a format clojure.spec likes
The error messages might be a little confusing where they say "this keyword is missing" when a JS consumer might expect "this property is missing"
@mrkaspa I'm returning everything (problems + extra info of the cause) to clients, specs can be serialized via s/form
. Not sure how usefull this is thou. Spec-tools has utility for adding human readable :reason
for specs (like struct does).
use case is:
first, I get some function symbols from config, resolve them vars, and see if those are actually functions.
next, I want to enforce common function signature on those, so I want to dynamically do (s/def 'some-handler :lib.specs/handler)
.
This is all cool, but I want to clean specs registry from those dynamically set specs on some tear down event (some reload in REPL, or what not).
(or at least to know I don't have to do cleaning up at all, because spec registry thing was designed to not worry about it.)
so far I found only this https://dev.clojure.org/jira/browse/CLJ-2060
actually, I control the call site, and can ensure args are ok, but does fspec actually check the arity of a function? or does it check args, and if a function (not args) does not conform to the spec – it will blow up, but not in the spec-way, but in usual invalid arity one?
yup
(s/fdef user/foo :args (s/cat :x int? :y int?) :ret nil?)
;; => user/foo
(defn foo [x])
;; => #'user/foo
(st/instrument)
;; => [user/foo]
(apply foo [1 2])
;; clojure.lang.Compiler$CompilerException: clojure.lang.ArityException:
so the best UX I can provide, is to make "handler" fspec
available, so user could instrument handlers during development at will.
Generating queue
, am I doing it right?
(:import
#?(:clj [clojure.lang PersistentQueue])))
(s/exercise
(s/coll-of int?
:kind #(instance? PersistentQueue %)
:into (PersistentQueue/EMPTY))
1)
;([#object[clojure.lang.PersistentQueue 0x66b3bed3 "clojure.lang.PersistentQueue@c98f581"]]
; (0 0 0 0 -1 -1 -1 0 -1 -1 0 0 -1 -1 0 0 0 -1 0 -1))
@misha Looks OK to me. I would have written :into PersistentQueue/EMPTY
(no parens), but in practice, it doesn’t seem to make a difference
@bbrinck you might be right (originally I had a (q)
cljc function call there, edited for brevity). Still need to see how it'd work in cljs.
to create spec for keyword with arbitrary namespace, I need to (create-ns ...)
first, right (if there is no file for that ns in a project)?
@misha I’m not sure if this works for your use case, but specs just need to be namespaced, but that namespace doesn’t have to be a clojure namespace. e.g. (s/def :user/name string?)
is totally valid.
The jury is still out on the pros/cons, but I’ve tended to build my specs based on my logical domain, not my Clojure namespaces. I never get to use the ::
syntax, but the plus side is that when I print out my specs (or get spec failures), things are a bit more succinct
For the example above, namespacing further by app or company helps avoid conflicts e.g. :my-app.user/name
@bbrinck ah, I went step further, and it complained about aliased namespace, which I need to create before aliasing.
So if I want to use ::u/name
, I need to (create-ns 'user)
and (alias 'u 'user)
first.
that’s totally fine (and something Rich has ideas about ways to improve specifically re working with keyword namespace aliases)
@alexmiller any news on unregistering specs?
yeah, there’s a ticket out there, should be in next spec batch
plan is to have (s/def ::foo nil)
do this
Question: I'm not sure I understand what fmap is for. When would I want to use it. Its one of the few functions that has no doc.
all of the gen namespace functions are dynamically loaded and thus don’t have doc, but they are just aliases for the equivalent function in clojure.test.check.generators
fmap is used to construct a generator based on applying an arbitrary function to some other generator
there is an example in the guide https://clojure.org/guides/spec
test.check.generators doc is at http://clojure.github.io/test.check/clojure.test.check.generators.html
and more examples at http://clojure.github.io/test.check/generator-examples.html
although fmap is not really covered there
it appears that s/? breaks up the merging of the s/cat
@dspiteself https://dev.clojure.org/jira/browse/CLJ-2105 & https://dev.clojure.org/jira/browse/CLJ-2003
Thanks
@alexmiller Thanks. I meant test.check doesn't have a doc for fmap. I get it now though.
Question: Is there a way I can specify that a spec can be one of a set of specs? Such as (s/def ::user-info #{::name ::address}). Where (s/def ::name (s/keys [::first ::last])) and (s/def ::address [::street ::city ::country]))
Okay, I think multi-spec is what I want: https://clojure.org/guides/spec#_multi_spec