This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-08
Channels
- # aws (9)
- # beginners (69)
- # boot (14)
- # cider (26)
- # cljs-dev (56)
- # cljsrn (9)
- # clojars (4)
- # clojure (229)
- # clojure-brasil (1)
- # clojure-france (11)
- # clojure-greece (2)
- # clojure-italy (4)
- # clojure-mke (6)
- # clojure-serbia (6)
- # clojure-spec (83)
- # clojure-uk (38)
- # clojurescript (171)
- # core-async (3)
- # cursive (11)
- # data-science (11)
- # datomic (27)
- # emacs (113)
- # funcool (6)
- # hoplon (4)
- # jobs (1)
- # luminus (13)
- # lumo (44)
- # off-topic (148)
- # onyx (5)
- # overtone (1)
- # pedestal (4)
- # powderkeg (1)
- # proton (2)
- # re-frame (150)
- # reagent (16)
- # ring-swagger (43)
- # spacemacs (4)
- # specter (36)
- # vim (4)
- # yada (10)
https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/generators.cljc#L91 one could use this to write the generator for refs, right? (gen/fmap deref (s/gen internal-spec))
also, I think my problem is a bit more generic than writing specs for refs. I was trying to write a spec for a type defined in cats. after seeing gen/fmap
, looks doable
yes technically that will work
normal test.check usage is aimed at writing generators for data, not stateful objects
I'm not sure what will happen if spec starts having specs for reference types
@caio I made a generator for reified protocols, which are similar enough to records https://github.com/bhagany/snowth/blob/master/src/snowth/satellites.cljs#L215
yeah, I did something like that (though my record was way simpler) https://github.com/funcool/cats/pull/201
@gfredericks this is not stateful. IDeref was implemented as a syntatic sugar
@caio okay that's not bad then
@bhagany btw the bind+return thing there can be simplified to fmap
@gfredericks thanks 🙂
any reason why (s/assert x) compiles to x instead of nothing (like core/assert) when s/*compile-asserts*
is false?
@looveh wrap >!
with validating fn? you can put anything on a channel, so any limitation would need to be enforced by client code, I think.
@misha That’s one way to do it, but it would also be useful to be able to spec channels as function arguments
wrapping >!
would bail right away. wrapping <!
would bail sometime later/never. Whichever would suite you best.
Yeah that would work, feels a bit hacky though imo since channels are part of a core lib
I'd imagine you need to add something to the channel-thing itself to be able to use different specs for different channels.
so either spec entry/exit points, or wrap, and spec/pass around/expect wrapped channels.
@misha @looveh specs could be put on a filter
transducer on the channel, or a call to map that throws. On an exception the exception would be handed to the channels' exception handler.
@tbaldridge I think @looveh's intention was to "spec a function, so that wrong kind of channel passed as an argument would throw", not "make sure channel would not accept random stuff". I like "spec as a filter" much more than macro above, thank you.
@tbaldridge can that channel's filter be used as a dispatch value once channel is constructed? is it accessible from outside?
@reefersleep what does explain-data show for the spec code?
@tbaldridge: Nothing more.
(spec/explain-data (spec/coll-of ::person []) [{:id 1 :name "john"} {:id 2 :name :heather}])
{:cljs.spec/problems {[] {:pred (coll-checker :sleepydo.db/person), :val [{:id 1, :name "john"} {:id 2, :name :heather}], :via [], :in []}}}
Note that I'm talking about cljs, not clj. 🙂
@reefersleep why is there []
in (spec/coll-of ::person [])
?
clojure gives me
(s/explain-data (s/coll-of string? []) ["a" "b" 1])
CompilerException java.lang.IllegalArgumentException: No value supplied for key: []
and in cljs (js) I can imagine it fails silently somewhere, but produces compromised output anywayI thought I should use :kind vector?
as well, until I tried it.
(spec/explain-data (spec/coll-of ::person :kind vector?) [{:id 1 :name "john"} {:id 2 :name :heather}])
---- Could not Analyze <cljs form> line:1 column:20 ----
Wrong number of args (3) passed to: spec/coll-of
1 (spec/explain-data (spec/coll-of ::person :kind vector?) [{:id 1 :name "john"} {:id 2 :name :heather}])
^---
---- Analysis Error ----
Then I tried without any :kind
-indication:
(spec/explain-data (spec/coll-of ::person) [{:id 1 :name "john"} {:id 2 :name :heather}])
---- Could not Analyze <cljs form> line:1 column:20 ----
Wrong number of args (1) passed to: spec/coll-of
1 (spec/explain-data (spec/coll-of ::person) [{:id 1 :name "john"} {:id 2 :name :heather}])
^---
---- Analysis Error ----
So I looked up the documentation:
(cljs.repl/doc spec/coll-of)
-------------------------
cljs.spec/coll-of
([pred init-coll])
Macro
Returns a spec for a collection of items satisfying pred. The generator will fill an empty init-coll.
if you remove that invalid trailing [], clojure says:
user=> (spec/explain (spec/coll-of ::person) [{:id 1 :name "john"} {:id 2 :name :heather}])
In: [1 :name] val: :heather fails spec: :user/name at: [:name] predicate: string?
alexmiller: So I guess what I'm seeing is a feature of clj spec missing (as of now) from the cljs port. I kind of suspected this, as I thought I'd seen more useful output in guides/tutorials at the time spec came out.
which seems better than the schema message to me
Hello. When I have keys #{:a :b :c}
and a spec ::foo
, how do I get
{:a (gen/genereate (s/gen ::foo))
:b (gen/genereate (s/gen ::foo))
:c (gen/genereate (s/gen ::foo))}
generated for me? (edited)
Now with (s/map-of #{:a :b :c} ::foo)
I've got only some keys, not all three usedso simple 😄
@misha but I think s/keys
takes both value type and key names from it's arguments
(and I have these different)
i.e. N keys and single value type
@misha thanks for answering btw 🙂
(s/def :foo/bar integer?)
(s/def :my/a :foo/bar)
(s/def :my/b :foo/bar)
(s/def :my/c :foo/bar)
(s/def :my/map (s/keys :req-un [:my/a :my/b :my/c]))
=> :my/map
(s/exercise :my/map 2)
=>
([{:a -1, :b 0, :c 0} {:a -1, :b 0, :c 0}]
[{:a -1, :b -1, :c -1} {:a -1, :b -1, :c -1}])
sure, but I'll need to repeat for 4 or 5 different types of ::foo
or provide your own generator, which would make sure all the keys are present. (I'd just alias things, custom generators might screw up s/explain-data
error address within the structure)
yep the custom generators are obviously "approach from the opposite side"
and well, honestly also having N keys as I do might mean semantically the sequence, not a map
yep, would take a look at every
function
I thought I should use :kind vector?
as well, until I tried it.
(spec/explain-data (spec/coll-of ::person :kind vector?) [{:id 1 :name "john"} {:id 2 :name :heather}])
---- Could not Analyze <cljs form> line:1 column:20 ----
Wrong number of args (3) passed to: spec/coll-of
1 (spec/explain-data (spec/coll-of ::person :kind vector?) [{:id 1 :name "john"} {:id 2 :name :heather}])
^---
---- Analysis Error ----
Then I tried without any :kind
-indication:
(spec/explain-data (spec/coll-of ::person) [{:id 1 :name "john"} {:id 2 :name :heather}])
---- Could not Analyze <cljs form> line:1 column:20 ----
Wrong number of args (1) passed to: spec/coll-of
1 (spec/explain-data (spec/coll-of ::person) [{:id 1 :name "john"} {:id 2 :name :heather}])
^---
---- Analysis Error ----
So I looked up the documentation:
(cljs.repl/doc spec/coll-of)
-------------------------
cljs.spec/coll-of
([pred init-coll])
Macro
Returns a spec for a collection of items satisfying pred. The generator will fill an empty init-coll.
alexmiller: So I guess what I'm seeing is a feature of clj spec missing (as of now) from the cljs port. I kind of suspected this, as I thought I'd seen more useful output in guides/tutorials at the time spec came out.
I think you must be using an older version of ClojureScript - that’s not what I see with the latest
afaik, ClojureScript is basically at parity with the Clojure version wrt spec
cljs.user=> (s/explain-data (s/coll-of ::person :kind vector?) '({:id 1 :name "John"}))
{:cljs.spec/problems [{:path [], :pred vector?, :val ({:name "John", :id 1}), :via [], :in []}]}
cljs.user=> (s/conform (s/coll-of ::person :kind vector?) [{:id 1 :name "John"}])
[{:name "John", :id 1}]
I’m using ClojureScript 1.9.293 btw
I thought I was up to date, but apparently, I misread the version number... 1.9.93
. 🙂
I'll try updating the version, I'm sure that'll make things better for me!
Thanks all!
what’s 200 commits between friends? :)
Now I'm having a different problem, not spec-related - I'm trying to destruct with (let [{:keys [a b] :as full} (fn-call something...)] ...
I've not changed the code for that destructuring or what goes on underneath between cljs version changes. However, the output of (fn-call ...)
, which is a map {:a "a's value" :b "b's value"}
, - I can tell by printing at the end of my fn-call
- turns into {[:a "a's-value] [:b "b's value"}
upon destruction (I can tell by printing full
), so I cannot destruct`a` or b
.
So weird.
(asking in #clojurescript , too)
about specing a deftype, this is what I came up with in the end: https://gist.github.com/caioaao/d15260076bb8ee6f48908507ae73155b
would be nice if someone could validate if this is safe. I had to go through spec's code for doing this, and some stuff were not really clear to me
also saw something in spec-tools
that they do some checking on conform
that made me think it may not be thread-safe. idk if that's the case
What' is either supposed to do?
Is this just a non conforming or of two choices?
@caio about spec-tools - if the conform doesn’t use threads, I should be ok. But not optimal. would be nice to use just 3rd parameter in conform (http://dev.clojure.org/jira/browse/CLJ-2116)
You can say it's a non conforming or between two choices If you want to push it (and probably piss someone 😆 )
great article, with the “Safe Dynamic Scope” chapter: https://stuartsierra.com/2013/03/29/perils-of-dynamic-scope.
I’m getting a strange error that seems related to the switch to spec.alpha. In my code this works: (clojure.core/require [pagespace-sym] :reload)
. But if I change it to :reload-all
I get the following error:
java.lang.ClassCastException: clojure.spec.alpha$regex_spec_impl$reify__1340 cannot be cast to clojure.lang.IFn
clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: clojure.spec.alpha$regex_spec_impl$reify__1340 cannot be cast to clojure.lang.IFn, compiling:(clojure/tools/logging.clj:1:1)
This is a known issue with spec.alpha not being aot compiled
It's been fixed in a new build of spec.alpha - 0.1.108. We haven't released a new Clojure alpha yet that depends on it but you can specify that to override
@alexmiller thanks!