This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-10-20
Channels
- # aws-lambda (7)
- # beginners (113)
- # boot (17)
- # cider (4)
- # cljs-dev (4)
- # clojure (65)
- # clojure-greece (3)
- # clojure-italy (7)
- # clojure-russia (10)
- # clojure-spec (37)
- # clojure-uk (20)
- # clojurescript (76)
- # community-development (2)
- # cursive (24)
- # data-science (9)
- # datomic (9)
- # emacs (1)
- # fulcro (2)
- # graphql (11)
- # hoplon (13)
- # juxt (15)
- # leiningen (1)
- # off-topic (36)
- # om (1)
- # onyx (59)
- # parinfer (41)
- # pedestal (7)
- # portkey (60)
- # protorepl (4)
- # re-frame (345)
- # reagent (7)
- # ring-swagger (16)
- # shadow-cljs (121)
- # spacemacs (30)
- # sql (6)
- # uncomplicate (2)
- # unrepl (9)
- # vim (13)
- # yada (2)
@alexmiller Thanks for the quick answers. Explained: https://redd.it/77if23 If the answer is "you need a separate namespace per data type with colliding keywords", so be it.... just wanted to have the discussion.
@eriktjacobsen Yes, the answer is to provide unique namespace-qualifiers for each of the colliding keywords -- remember that those namespaces do not have to exist, but they should have names that represent the different concepts being modeled.
The whole point of namespaces is to provide unique ways to name things that are distinct (but otherwise have the same unqualified name).
Right, it's just unfortunate to lose the relationship of between using the spec and knowing where it's defined, losing ability to use the ::
and aliases (until patched), and other limitations mentioned. I understand that might be the answer, its just my team is unhappy if that's the final answer.
:foo.bar/baz.hullabaloo
is a valid keyword I think
I don't suppose it's likely to make anybody happy though
Correct, but when used in a (spec.keys :req-un)
it will require the keyword to be :baz.hullabaloo
, correct? Rather than :hullabaloo
. That is basically the same solution as my first proposal, just with .
instead of /
yep. it's just sadness all over
it does seem like differentiation between specspace and namespace seem slightly confused, or dare I say complected.
OTOH it would be weird and confusing to have many parallel namespace systems e.g. those lisps that keep functions separate from the other kind of thing
Because the incoming data I'm trying to spec is generally using unqualified keys. Such as from parsing json.... I suppose I could add a step before doing spec validation that transforms all the unqualified keys into qualified keys using some mapping scheme, validates with spec, then unqualifies them again for usage downstream, but that's basically the functionality i'm looking for from spec and seems like a lot of overhead
@eriktjacobsen FWIW, I am struggling with similar issues. I tried (briefly) using spec keywords in "fictional" namespaces (e.g. not corresponding to clojure ns), but then I end up with an explosion of long namespaced keywords. Lots of typing, lots of things to read and process when looking at code. The ::
really helps in reducing that.
Somewhat related: I'm also thinking about dropping :req-un
and moving to fully-qualified keys everywhere. But there is a price to be paid in storage (JSON database), transmission (websocket trafic isn't compressed, Transit helps but I'm not sure to what extent), code complexity (need to include keyword namespaces in all destructuring code), and ClojureScript code building keywords from strings. I'm not sure what that price is.
i use a macro that creates "relative" aliased ns and tend to spec maps using it following a pattern like ::map ::map/foo ::map/bar ::map/baz etc
you can just do (rel-ns 'foo.bar.baz.bad) if deeply nested and then use it as ::foo.bar.baz.bad/xxx, it's quite readable imo
Thank you! We have thought of similar workarounds, mostly wanted to bring the discussion up for a solution from the core.specs team, though we could incorporate this if we have to workaround it.
Hi! Given ::allowed-val
"enum spec", is there a way to print all the allowed values in the error message? Currently it prints (into #{} allowed-vals)
.
And let's consider it's the requirement that I need allowed-vals
extracted as a var because I need to iterate over it in other places.
(def allowed-vals [1 2 3])
(s/def ::allowed-val (into #{} allowed-vals))
(s/explain ::allowed-val 5)
=>
val: 5 fails spec: :cljs.user/allowed-val predicate: (into #{} allowed-vals)
:cljs.spec.alpha/spec :cljs.user/allowed-val
:cljs.spec.alpha/value 5
user=> (s/def ::foo #{:a :b :c})
:user/foo
user=> (s/form ::foo)
#{:c :b :a}
user=> (doseq [i (s/form ::foo)] (prn i))
:c
:b
:a
nil
user=>
yeah, it's a bit backwards but should work, thanks
right 🙂 I meant that it's backwards in a sense that I'd like the variable to be the source of allowed values instead of putting them into spec
and what if the enum values cannot be hardcoded like that in spec? e.g. when I need to read them from file
right now calling eval
to build specs is probably the best choice, but work is apparently underway on making spec more "programmable" -- make specs from external stuff
how would I spec a function with variadic keyword args like (myfn :a 1 :b 2)
? I’m trying to use (spec/* (spec/keys :req-un [::a ::b]))
but that’s not right
I have a function which takes 2 maps as input and returns a vector with 2 maps.
defmulti my-function (fn [map1 map2] (:type map2)
defmethod my-function :type1
[map1 map2]
(let ....
...
...
...)
[ret-map1 ret-map2]
defmethod my-function :type1
[map1 map2]
.
.
.
This is what I tried for fdef
-
(s/fdef my-function
:args (s/cat :map1 map? :map2 map?)
:ret vector?)
Not sure exactly what’s not working but this works for me:
(defmulti my-function (fn [map1 map2] (:type map2)))
(defmethod my-function :type1 [map1 map2]
[map1 map2])
(defmethod my-function :type2 [map1 map2]
[map2 map1])
(s/fdef my-function
:args (s/cat :map1 map? :map2 map?)
:ret vector?)
(stest/instrument `my-function)