This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-02
Channels
- # adventofcode (5)
- # arachne (2)
- # bangalore-clj (1)
- # beginners (8)
- # boot (195)
- # cider (28)
- # cljs-dev (35)
- # cljsrn (4)
- # clojure (295)
- # clojure-brasil (5)
- # clojure-gamedev (2)
- # clojure-greece (2)
- # clojure-korea (13)
- # clojure-russia (60)
- # clojure-spec (58)
- # clojure-uk (92)
- # clojurescript (31)
- # clojurex (4)
- # css (1)
- # cursive (13)
- # datomic (40)
- # devcards (2)
- # emacs (17)
- # events (1)
- # flambo (3)
- # garden (9)
- # hoplon (31)
- # jobs (3)
- # klipse (1)
- # lein-figwheel (1)
- # london-clojurians (1)
- # luminus (2)
- # mount (36)
- # off-topic (13)
- # onyx (8)
- # pamela (1)
- # pedestal (1)
- # planck (3)
- # proto-repl (16)
- # protorepl (11)
- # re-frame (78)
- # reagent (4)
- # rethinkdb (6)
- # ring-swagger (1)
- # specter (8)
- # untangled (10)
- # vim (1)
@alexmiller destructuring like that throws an exception: (let [{::stats/keys [foo bar]} {::stats/foo 2}] foo)
:stats/keys
works, but that’s not what I meant
because I have this in my require [spec-provider.stats :as stats]
@bbloom The relevant ticket to vote on is http://dev.clojure.org/jira/browse/CLJ-1965 🙂
@stathissideris That should work AFAICT. What's the exception you get?
spec-provider.trace> (let [{::stats/keys [foo bar]} {::stats/foo 2}] foo)
ExceptionInfo Call to clojure.core/let did not conform to spec:
In: [0 0] val: #:spec-provider.stats{:keys [foo bar]} fails spec: :clojure.core.specs/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0 0] val: ([:spec-provider.stats/keys [foo bar]]) fails spec: :clojure.core.specs/seq-binding-form at: [:args :bindings :binding :seq] predicate: (cat :elems (* :clojure.core.specs/binding-form) :rest (? (cat :amp #{(quote &)} :form :clojure.core.specs/binding-form)) :as (? (cat :as #{:as} :sym :clojure.core.specs/local-name))), Extra input
In: [0 0 :spec-provider.stats/keys] val: [foo bar] fails spec: :spec-provider.stats/keys at: [:args :bindings :binding :map :spec-provider.stats/keys :clojure.spec/pred] predicate: map?
In: [0 0 :spec-provider.stats/keys] val: [foo bar] fails spec: :spec-provider.stats/keys at: [:args :bindings :binding :map :spec-provider.stats/keys :clojure.spec/nil] predicate: nil?
:clojure.spec/args ([#:spec-provider.stats{:keys [foo bar]} #:spec-provider.stats{:foo 2}] foo)
clojure.core/ex-info (core.clj:4725)
I’m on clojure 1.9.0-alpha14
Yeah, same here. Something must be off in your namespace @stathissideris
weird, thanks for trying @bronsa and @dergutemoritz
@stathissideris You're welcome! If all else fails, try rebooting the REPL 😉
REPL reboot didn’t help
I think I’ll try in a fresh project
@stathissideris hmm, do you have a ::stats/keys
spec by any chance?
That'd be nasty
Good thinking @bronsa
interesting, not sure if this was intentional but one can do this:
user=> (require '[clojure.spec :as s])
nil
user=> (s/def ::keys (s/coll-of '#{foo bar} :kind vector?))
:user/keys
user=> (let [{::keys [foo]} {}])
nil
user=> (let [{::keys [baz]} {}])
ExceptionInfo Call to clojure.core/let did not conform to spec:
In: [0 0] val: #:user{:keys [baz]} fails spec: :clojure.core.specs/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0 0] val: ([:user/keys [baz]]) fails spec: :clojure.core.specs/seq-binding-form at: [:args :bindings :binding :seq] predicate: (cat :elems (* :clojure.core.specs/binding-form) :rest (? (cat :amp #{(quote &)} :form :clojure.core.specs/binding-form)) :as (? (cat :as #{:as} :sym :clojure.core.specs/local-name))), Extra input
In: [0 0 :user/keys 0] val: baz fails spec: :user/keys at: [:args :bindings :binding :map :user/keys] predicate: (quote #{bar foo})
:clojure.spec/args ([#:user{:keys [baz]} {}])
clojure.core/ex-info (core.clj:4725)
if intentional, your issue is not a bug, otherwise I'd say it's a spec/`:clojure.core.spec/ns-keys` bug
@bronsa OH! yes, I do have a ::stats/keys
spec
it doesn’t have to be called that, but it was the most natural name for what I’m doing
@bronsa good spot!
minimal repro:
user=> (s/def ::foo nil?)
:user/foo
user=> (s/def ::bar (s/keys :opt-un [::foo]))
:user/bar
user=> (s/valid? ::bar {:a/foo 1})
true
user=> (s/def :a/foo nil?)
:a/foo
user=> (s/valid? ::bar {:a/foo 1})
false
@bronsa How's that wrong?
You need to redef bar for that to take effect
Specs are lazily compiled on use
Note that bit from the s/keys
docstring: "In addition, the values of all namespace-qualified keys will be validated (and possibly destructured) by any registered specs."
And cached
@dergutemoritz ah, then it's not a bug :)
Oh, that too
I think this is unrelated to the keys destructuring issue @stathissideris ran into
@dergutemoritz no, that's the same issue @stathissideris is having
There are some weird corners with unqualified keys
OK then I didn't get the connection, yet 🙂
the let binding destructuring specs are defined in terms of s/keys
, which is why he's getting ::stats/keys
validated against his ::stats/keys
spec
Ah, I see
Yeah, that's pretty subtle :)
I wonder if this is intended behavior in this particular situation, though 🙂
it feels a bit weird that that happens purely because of how those specs are defined (i.e. it depends on an implementation detail)
We've talked about this a bit and I think this is a case where some effort could be taken to detect and warn (or maybe error)
realistically this means using ::keys
or ::strs
as spec is going to lead to those issues most of the times (unless your ::keys
spec is literally a coll of simple-syms)
It is in the ballpark of being open in your map specs or kwarg options
An option to disable this behavior for particular keys
specs might be useful, too
I'll think about it
That's already a pretty tricky hybrid map spec
Great find everyone, I'm happy I probably won't have to run into this case myself some day and scratch my head in confusion 😄
We are absolutely not doing that
I don't expect to make any adjustments to keys for this, but rather alter how the destructuring spec is written