Fork me on GitHub
#clojure-spec
<
2020-10-31
>
borkdude14:10:21

The ::invalid keyword occurs 67 times in the spec repo:

$ ./grasp ~/git/spec.alpha/src -w -e "(fn [k] (= :clojure.spec.alpha/invalid (unwrap k)))" | wc -l
      67

teodorlu14:10:46

And you're finding both fully qualified :clojure.spec.alpha/invalid and shorthand ::invalid / ::s/invalid uses? Nice! I'm curious about use-cases for grasp in tooling for refactoring.

borkdude15:10:45

yes

đź‘Ť 3
kirill.salykin16:10:19

Hi please advice, how I can write a spec for :fileds

(s/explain-data ::fields [{:name "aaa" :type "bbbb"} {:name 1 :type "cccc"}])
so it checks that fields/name is unique - fails on every non unique entry and the spec also contains path of the non unique row Thanks

borkdude18:10:46

@kirill.salykin The uniqueness of the name is a property of the collection, not of one item

user=> (s/def ::unique-names (fn [xs] (= (map :name xs) (distinct (map :name xs)))))
:user/unique-names
user=> (s/explain ::unique-names [{:name :foo} {:name :bar}])
Success!
nil
user=> (s/explain ::unique-names [{:name :foo} {:name :foo}])
[{:name :foo} {:name :foo}] - failed: (fn [xs] (= (map :name xs) (distinct (map :name xs)))) spec: :user/unique-names

kirill.salykin19:10:49

I understand and agree thought there is a dark magic to get indecies of non-unique elements, but apparently no thanks for the answer

borkdude19:10:12

There might be, but I don't know if it's pretty

kirill.salykin19:10:47

maybe there is a way shape spec output in a way as it reports per failed element (eg with s/problems, path (`:in []`) and predicate?)

borkdude19:10:06

@kirill.salykin Maybe something like this:

user=> (s/def ::unique-names (s/and #(group-by :name %) (s/every-kv any? #(= 1 (count %)))))
:user/unique-names
user=> (s/explain ::unique-names [{:name :foo} {:name :foo}])
Execution error (UnsupportedOperationException) at user/fn (REPL:1).
nth not supported on this type: PersistentArrayMap
but I'm getting an exception

kirill.salykin19:10:14

interesting… so (s/and ) behaves like ->?

borkdude19:10:39

It needed s/conformer around the first spec

borkdude19:10:45

@kirill.salykin Ah, I needed s/conformer:

user=> (s/def ::unique-names (s/and (s/conformer #(group-by :name %)) (s/every-kv any? #(= 1 (count %)))))
:user/unique-names
user=> (s/explain ::unique-names [{:name :foo} {:name :foo}])
[{:name :foo} {:name :foo}] - failed: (= 1 (count %)) in: [:foo 1] at: [1] spec: :user/unique-names

3
Dmytro Bunin19:10:43

til, thanks 🙂

kirill.salykin19:10:17

you are magician! thank you so much!

borkdude20:10:57

I've made binary versions of grasp available in the #grasp channel now. Clojure spec on the command line, yeah :)