This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-19
Channels
- # announcements (1)
- # architecture (24)
- # beginners (7)
- # boot (7)
- # cider (1)
- # cljdoc (4)
- # clojure (20)
- # clojure-austin (1)
- # clojure-brasil (2)
- # clojure-dev (1)
- # clojure-italy (1)
- # clojure-spec (36)
- # clojure-uk (11)
- # clojurescript (44)
- # data-science (3)
- # datascript (1)
- # datomic (8)
- # figwheel-main (2)
- # fulcro (29)
- # graphql (9)
- # kaocha (2)
- # keyboards (1)
- # leiningen (3)
- # lumo (5)
- # nrepl (4)
- # off-topic (39)
- # onyx (5)
- # re-frame (2)
- # shadow-cljs (42)
- # tools-deps (18)
- # yada (65)
spec 2 stuff
@alexmiller Want me to go back to my spec2 branch and start testing our code against this again? Happy to do so starting Monday if you think this should have parity with current spec?
Sure, go for it
Thank you!
(originally posted in #announcements by accident!)
I see that s/keys
is still part of the api in spec2. I'm a bit surprised given RH's talk on how he wants to separate that out into s/schema
and s/select
. Are these going to be added in addition to s/keys
then or is s/keys
going away in favor of them in the next iteration? If they'll all exist together, will it ever make sense to use s/keys
over s/schema
/`s/select`?
@madstap That's a bit unfair -- the refactor to spec2 started before Conj.
The shape/required stuff is further down the pike.
The work in spec2 is groundwork to prepare for that.
Sure, my question is more about the direction spec will take. Is s/keys
"living on borrowed time" so to speak?
Yeah, I'd say s/keys
is living on borrowed time. Spec is still alpha so it's subject to API breakage.
Given the namespace changes, you can have both libraries loaded and both types of specs defined while you transition.
That's the important part of namespace changes.
Yeah, just like RH talked about in his penultimate(?) keynote. Pretty cool to see how that approach works out in practice.
This is why next.jdbc
will be a new namespace at least and a new artifact more likely 🙂
Unknown yet on s/keys. We haven’t started any of the work yet for the stuff rich talked about at conj
Look, people complain when we work in a private repo, then drop something at the end. We’re trying to do something different here which means you get to see all the steps along the way, so things will be changing over a probably months
Some of it will be experimental
I love that you're dropping stuff we can test against.
Just saying, don’t expect it all at once
I don't much care which way you're going with the API -- we'll follow, regardless, even if we have to keep changing code 🙂
One observation about that though: The way spec op macros are implemented now breaks clojure.walk/macroexpand-all
, which will stack overflow if the form contains any spec macros.
That's good feedback for the development of spec2. Last time I tried our code against spec2, a lot of stuff broke. I'll be trying it again on Monday when I get back to work. Breakage is to be expected in prerelease work and if folks pitch in and try it, the core team get more feedback which is helpful!
I have this spec in spec1:
#?(:clj (s/def ::java-map
(s/with-gen #(instance? java.util.Map %)
(fn [] (gen/fmap #(java.util.HashMap. %)
(s/gen ::map))))))
On spec2 I get:
Caused by: java.lang.IllegalArgumentException: no conversion to symbol
at clojure.core$symbol.invokeStatic(core.clj:596)
at clojure.core$symbol.invoke(core.clj:589)
at clojure.spec_alpha2$explicate_1$fn__904.invoke(spec_alpha2.clj:314)
I have to look into this more, I just briefly tried itThe key thing is that specs have to start off as forms, not function objects. So here the anonymous function is getting evaluated too early and I suspect you need to quote the (fn ... ). That may be fixable though in spec since I turned with-gen into a macro. I’ll take a look when I’m at a computer.
same with:
#?(:clj (s/def ::char-sequence
(s/with-gen
#(instance? java.lang.CharSequence %)
(fn []
(gen/one-of (map #(gen/fmap %
(s/gen ::string))
[#(StringBuffer. %)
#(StringBuilder. %)
#(java.nio.CharBuffer/wrap %)
#(String. %)]))))))
This spec breaks:
(defn seqable-of
"every is not designed to deal with seqable?, this is a way around it"
[spec]
(s/with-gen (s/and seqable?
(s/or :empty empty?
:seq (s/and (s/conformer seq)
(s/every spec))))
#(s/gen (s/nilable (s/every spec :kind coll?)))))
(s/def ::seqable-of-map-entry (seqable-of ::map-entry))
with the message:
Caused by: java.lang.IllegalArgumentException: No method in multimethod 'create-spec' for dispatch value: speculative.specs/seqable-of
I tried to fix it like this: https://github.com/borkdude/speculative/blob/spec-alpha2/src/speculative/specs.cljc#L86 But I get:
user=> (s/valid? ::ss/seqable-of-map-entry {:a 1 :b 2})
Execution error (IllegalArgumentException) at clojure.spec-alpha2/pred-impl (spec_alpha2.clj:132).
I’ll leave it at this for now.
Broken code is indicated with FIXME’s here: https://github.com/borkdude/speculative/blob/spec-alpha2/src/speculative/specs.cljcHello, I have a case where having the keys of a map spec forced to be namespaced qualified, leads to a case like this:
(defn do-this [args]
;; ...
{:foo :bar
:resource {:key-a 1}})
(s/def ::foo keyword?)
(s/def ::key-a int?)
(s/def ::resource (s/keys req-un [::key-a]))
(s/fdef do-this
:ret (s/keys :req-un [::foo ::resource]))
(defn do-that [args]
;; ...
{:foo :bar
:resource {:key-b "plop"}})
(s/def ::key-b string?)
;; (s/def ::resource (s/keys req-un [::key-b])) <-- problem here: the spec is being redefined
(s/fdef do-this
:ret (s/keys :req-un [::foo ::resource]))
Here I would like to have to functions in the same namespace that return two different "partial views" of a resource along with other information in a map.
It seems that I can't due to the fact that two pieces of information are glued together: the unqualified key and the spec.
I feel like I miss kind of a scoped spec declaration or a function like this : (s/key :resource <spec>)
that I can embed in the declaration: (s/keys :req-un [(s/key :resource <spec>) ::foo])
.
But I feel also that I am maybe misusing the library.
Has someone bumped into this problem already?
Thanks@dam since you use :req-un
in all 3 s/keys
, you can pick another namespace for second ::resource
:
(s/def :baz/resource (s/keys req-un [::key-a]))
(s/def :quux/resource (s/keys req-un [::key-b]))
(s/fdef do-this :ret (s/keys :req-un [::foo :baz/resource]))
(s/fdef do-that :ret (s/keys :req-un [::foo :quux/resource]))