This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-06
Channels
- # adventofcode (24)
- # aleph (1)
- # bangalore-clj (2)
- # beginners (196)
- # boot (148)
- # cider (18)
- # clara (83)
- # cljsrn (24)
- # clojure (210)
- # clojure-brasil (3)
- # clojure-china (1)
- # clojure-italy (11)
- # clojure-korea (8)
- # clojure-russia (82)
- # clojure-spec (115)
- # clojure-uk (130)
- # clojurescript (109)
- # core-async (7)
- # cryogen (1)
- # cursive (22)
- # datascript (11)
- # datomic (6)
- # devcards (2)
- # emacs (1)
- # garden (1)
- # hoplon (2)
- # incanter (1)
- # klipse (4)
- # luminus (4)
- # off-topic (89)
- # om (53)
- # onyx (78)
- # parinfer (9)
- # proton (3)
- # protorepl (20)
- # re-frame (107)
- # reagent (52)
- # rum (30)
- # spacemacs (1)
- # testing (3)
- # untangled (31)
- # vim (43)
- # yada (9)
not sure if this have been asked before, suppose i have 2 cases: ["a" 1 true "b" 2 false "c" 3 true]
and [["a" 1 true] ["b" 2 false] ["c" 3 true]]
, my understanding is (s/+ (s/*cat :first string? :second number? :third bool?))
will validate the first case. my question: how to write spec for the second case where each group is enclosed in a vector/list?
@hiredman great! thanks
another alternative would be (s/coll-of (s/tuple string? number? boolean?) :kind vector?)
I’d probably prefer the non-regex version in this case
Quoting Mr. Miller on clojure-dev:
> That said, current versions of those libs still exist for those wanting it and we could release point updates to those if needed later.
⇑ something rich didn't address in the criticism of semantic versioning -- sometimes a one-dimensional version-space is insufficient
maybe appending things to a timestamp-based versioning system would be good enough
version 201612061011.2
no thanks :)
@alexmiller I'm curious what alternative you have in mind
I don’t understand what problem you’re trying to solve
@alexmiller making a "point release" off of an older version -- they exact use case you were describing in the email I quoted
s/they/the/
I don’t see a problem with making a point release off of an older version?
in semantic versioning it's clear what's going on
if we upgrade from 0.8.0 to 0.9.0, but then want to add bugfixes for users stuck on 0.8.0, we release 0.8.1 and nobody thinks that 0.8.1 is a better version of 0.9.0
but if our versions are just timestamps, there's more confusion
relatively clear -- the non-linearity of the releases is clearer
I don't think Rich was saying that we should stop using versions
me neither
he spent a while criticizing the semantics of semantic versioning, and had a slide that suggested "YYYYMMDDHHMM" or something similar as an alternative
and I was thinking about how that sort of versioning system would need some sort of additional feature to support making changes for older releases
I'm probably communicating this poorly
the idea of a "major version" was one of the criticisms
i think it was cause the number is meaningless… the name is as well but it’s easier to think of a feature set of android nougat vs kitkat than to refer to them as their version numbers
I took much of the point to be that you would ship both old and new apis in your library (assuming you didn’t choose to fork to a new library name when you changed apis). Thus if you needed to augment the old api with a new feature, you’d release a new version of the whole library.
Is it possible to attach a generator to a predicate without defining an explicit spec? For example, I want to make a predicate queue?
, and generate instances of clojure.lang.PersistentQueue
from a spec like (s/coll-of int? :kind queue?)
, similar to how it works for vector?
.
@donaldball I'm not sure that would work in the case I brought up, where your library requires clojure 1.8 but you want to augment older versions for users that haven't upgraded to 1.8 yet
@dave.dixon I doubt it
@gfredericks Certainly doesn't look like it. clojure.spec.gen/gen-builtins
provides a nice shortcut for predicates in clojure.core
. It would be nice if this was extensible.
I suspect making that extensible might also invite a world of conflicts
@alexmiller Why was that done for the predicates in clojure.core then? Is the purpose of this purely for backward compatibility? It seems like the general workflow is write your predicate, write a spec that is defined as a call to that function, include a generator on that spec, and use that spec but clojure.core varies from this workflow.
That doesn't make any sense to me :)
valid? works be evaluating the predicates
The workflow seems exactly the same to me except the generator is already provided
Right. But why is it written like that in clojure.core instead of providing actual specs for us to use?
Preds are specs
The core fns have built in mappings because that lets you build up specs in many cases without needing to write custom gens
Like (s/and int? even?)
So then why is there no way for us to extend that built in mapping so we can so similar things with our own predicates?
I was not part of that decision process so I can’t say what exactly went into it. but certainly you can create specs by using s/spec or s/with-gen to add custom gens
my suspicion is that it opens a bunch of complexities with respect to libs providing their own competing generators
and maybe that was just a door Rich and Stu didn’t want to open
Yeah I’m just not sure. It’d be great to know if that was actually what they decided. It seems useful but I am also concerned that it could lead to complexities.
Technically you could have Spec
extend IFn
so you can define your predicate on the spec. But that feels a little hacky
(s/map-of string? string?)
#(contains? % “foo”)
?
I don’t know that I have enough info to actually answer your question :)
the problem with describing things entirely in terms of predicates is you lose the structure
hiredman, yep, I was thinking if it becomes to bothersome to do contains? everywhere to convert the string keys to keywords instead
i'm not sure how to best handle a case with a large map that has a bunch of strings for keys
one hack is to (s/and (s/conformer clojure.walk/keywordize-keys) (s/keys :req-un [::a]))
(didn’t try this, so could be typos there but you get the idea)
I have https://gist.github.com/hiredman/0668d1240e0a623904eca33fed11c45f , but I haven't hooked up generation yet
@hiredman fyi, we consider the protocols internal right now and there is a reasonable chance they will still change
protocol might even go away
the intention is that most people shouldn’t do it :)
I don't want to do it, but I also want to use spec as a data regex (including maps) without having to fiddle with the global registry
Do you mean you want the ability to spec a map with unnamespaced keywords without registering corresponding namespaced keywords in the spec registry?
you can easily say, with predicates, #(and (map? %) (contains? % "foo") (uuid? (get %) "foo"))
, but then you run in to issues if you want to spec the data
you can replace uuid?
there with a call to valid?
and some spec, but to conform and explain on the original spec it is a black box
dev=> (s/valid? (s/keys :req [::foo]) {})
false
dev=> (let [foo ::foo] (s/valid? (s/keys :req [foo]) {}))
true
dev=>
@eraserhd s/keys is a macro, so you need to compute the key at/prior to macroexpansion
boot.user=> (defmacro computed-foo []
#_=> (let [foo ::foo]
#_=> `(s/keys :req [~foo])))
#'boot.user/computed-foo
boot.user=> (s/valid? (computed-foo) {})
false
am i doing :ret wrong? user=> (s/fdef f :args (s/cat) :ret string?) user/f user=> (defn f [] 1) #'user/f user=> (stest/instrument `f) [user/f] user=> (f 5) ExceptionInfo Call to #'user/f did not conform to spec: In: [0] val: (5) fails at: [:args] predicate: (cat), Extra input :clojure.spec/args (5) :clojure.spec/failure :instrument :clojure.spec.test/caller {:file "form-init7158439094984280972.clj", :line 1, :var-scope user/eval100801} clojure.core/ex-info (core.clj:4725) user=> (f) 1
@bbloom instrument doesn't check :ret
something something instrument is for calls and generative testing is for rets
it does or does not make perfect sense depending on who you ask; I think there's an explanation somewhere
if this were irc we would just ask clojurebot for the link
if this were irc we would just increment a counter in clojurebot to keep track of that
@bbloom my guess is the intention is when you test something, you instrument all the stuff it calls to make sure that stuff gets called correctly; checking rets is for when you're testing that function in particular, which you can do with clojure.spec.test/check, or by calling/asserting manually
anyhow if you hate this you could add an alternative to instrument
in schpec
i have a recursive function that has a small :ret violation deep inside it and i want to catch the error earlier than the root call from the unit test