This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-04
Channels
- # arachne (1)
- # beginners (41)
- # boot (92)
- # capetown (8)
- # cider (10)
- # cljsjs (4)
- # cljsrn (42)
- # clojure (94)
- # clojure-india (1)
- # clojure-russia (48)
- # clojure-sanfrancisco (1)
- # clojure-spec (34)
- # clojure-uk (13)
- # clojurescript (29)
- # cursive (12)
- # datavis (4)
- # datomic (10)
- # dirac (63)
- # editors-rus (16)
- # emacs (57)
- # funcool (5)
- # hoplon (22)
- # jobs (2)
- # lein-figwheel (3)
- # leiningen (5)
- # onyx (51)
- # other-languages (2)
- # proton (1)
- # protorepl (2)
- # re-frame (34)
- # remote-jobs (1)
- # sfcljs (5)
- # spacemacs (1)
- # specter (2)
- # sql (20)
- # test-check (54)
- # yada (1)
good morning. is there a short answer to
are clojure.spec's - a replacement for {:pre ... :post ...} condition-map parameters?
? (assuming sparse usage of the latter)@misha from my perspective, mostly yes
@gfredericks: thanks
@thegeez you can definitely use conform to destructure values if that’s useful (particularly useful in macros when decoding syntax). Cost is not free of course but will get better.
@gfredericks it’s easy to add a generator with s/with-gen
. There are combinations of gen/bind
and gen/fmap
that can help you work from a model of your data towards generated values. The next (I think) screencast from Stu is going to talk about this more.
@alexmiller: but it's not easy to use with-gen to modify the default generator, unless I'm missing something
It could be easier :)
But if you have just the base spec, you can pull its gen and feed it into fmap
is there any easy way to spec a map where the required keywords depend on the values in the map?
> e.g. if (:a m)
is 5
then m
should also have a :b
keyword
I realize this can be done with manually defined predicates and then manually defined generators
Seems like you could cobble it together with s/or
, defining each possible combination separately (&, in your example, presumably two separate specs for the options for :a). But that’s hardly elegant...
with one alternative containing the former as well as the :b
keyword, and the other alternative containing the latter and not containing :b
.
I’m specifically asking for an elegant way, before I go and write a macro that does it
Is it preferred to put specs in a separate namespace, like how clojure.java.jdbc
does it? --> https://github.com/clojure/java.jdbc/blob/f9fe3dde5b4bc5f1a5b5a79ffb5374fad3377b0b/src/main/clojure/clojure/java/jdbc/spec.clj
@bsima: I think java.jdbc does it to be backwards compatible with older versions of clojure
@bsima: FWIW, we’re following a similar pattern at World Singles where our specs are in one namespace and we pull that into other namespaces as needed — but that’s partly because nearly all of our specs so far are very data-focused rather than function-focused.
We haven’t yet decided how that will play out when we’re defining system boundary APIs on top of those specs.
And, yes, java.jdbc
needs to support Clojure back to 1.4.0, as @gfredericks says.
in a recent cognicast rich hickey mentioned using specs as a way to version a codebase, like "if your code matches this set of spec keys then we didn't break anything with this new release" (paraphrasing)
so, I think that's an interesting way to approach specs, and an argument for separating specs from code
most of the specs i've written so far have been fdef
s, it almost feels like racket's contract system
for another data point, we are currently working on putting clojure.core specs in the namespace clojure.core.specs
not saying that following the pattern is the only way or best way to do it for anyone else’s particular situation though
FWIW - I've been experimenting with the specs in a sidecar namespace, but with the fdef
s in the foo
namespace beneath the functions... not been using spec much yet though - so not sure how it'll work out
I've been placing the fdef
right above the function definition. I find that's the most valuable place from the perspective of providing documentation. I like seeing the specs, the arg names, and the docstring all in one place.
but i suspect that specs for common data types will go in a different namespace that can be used in many namespaces
you can do that? I'd assumed because fdef
takes a symbol for the function its annotating that it would have to come after the definition of the function
@rickmoynihan: yeah it works for me:
(s/fdef my-new-fn
:args (s/cat :int integer?))
(defn my-new-fn [x]
(+ x x))
(stest/instrument `my-new-fn)
(comment
(= 2 (my-new-fn 1)) ; => true
(= 2 (my-new-fn nil)) ; spec error
)
right enough: https://github.com/clojure/clojure/blob/d920ada9fab7e9b8342d28d8295a600a814c1d8a/src/clj/clojure/spec.clj#L294
agree that they're better above the definition
Just remember that if your fdef
s are elsewhere, you need a qualified symbol name (see https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc/spec.clj where I updated this for Alpha 10 — unqualified symbols worked in an earlier Alpha if you just referred them in unqualified).