Fork me on GitHub
#clojure
<
2018-06-19
>
urbanslug04:06:54

So I have a function and a spec that is failing orchestration like so:

(s/def ::my-vector (s/coll-of string? :kind vector))

(s/fdef bool-intersect?
  :args (s/and ::my-vector ::my-vector)
  :ret boolean?)

(defn bool-intersect?
  [vec-one vec-two]
  (let [set-one (set vec-one)
        set-two (set vec-two)]
    (intersection set-one set-two)))

(st/instrument)

(assert (bool-intersect? ["boys" "girls"] ["dads" "moms"]))

ExceptionInfo Call to #'advocado.core/bool-intersect? did not conform to spec:
In: [0] val: ["boys" "girls"] fails spec: :advocado.core/my-vector at: [:args] predicate: string?
In: [1] val: ["dads" "moms"] fails spec: :advocado.core/my-vector at: [:args] predicate: string?

yen04:06:12

(s/fdef bool-intersect?
  :args (s/and ::my-vector ::my-vector)
  :ret boolean?)
:args should be (s/cat :vec-one ::my-vector :vec-two ::my-vector) I think

urbanslug18:06:25

Sorry I should've replied 8 days ago with thank you.

urbanslug04:06:19

I don't really see why it's complaining about the arg being a vector of strings

seancorfield05:06:38

@urbanslug As @hello254 said your spec has an incorrect :args predicate. You pretty much always want s/cat for :args with a name and a spec for each argument.

seancorfield05:06:42

(s/and ::my-vector ::my-vector) is pretty much equivalent to just ::my-vector -- a single vector of strings. You're saying the entire arguments list should be a vector of strings and it should also be a vector of strings.

seancorfield05:06:47

If you called (bool-intersect? "boys" "girls") that would probably satisfy your spec...

seancorfield05:06:13

(and (set "boys") would create a set of the letters \b \o \y \s)

urbanslug05:06:33

Here's a question: Say I have a spec and code in core.clj and a different constants file that contains some maps that I plan to use as test data. Should the symbols/keys in the test data be namespaced to show that they come from the spec. Here's an example:

seancorfield05:06:15

The spec itself determines whether the the map keys should be namespaced or not: (s/keys :req-un [...]) for a map with unqualified keys; (s/keys :req [...]) for a map with qualified keys (that will match the namespaces in the spec).

urbanslug05:06:27

(s/def ::person (s/keys ::req [::name ::height]))

(s/fdef is-tall?
    :args (s/cat :hooman ::person)
    :ret boolean?)


(defn is-tall?
  [hooman]
  (> 5 (:height hooman)))

seancorfield05:06:51

With :req-un, the keys in the map are unqualified. The namespaces used in the spec are just to identify the specs for the keys.

seancorfield05:06:50

In your code, your ::person spec states that the keys are namespace-qualified.

urbanslug05:06:05

in a different constants I have:

(def example-person
  {:name "alice"
   :height 7})

seancorfield05:06:16

That doesn't satisfy the spec.

urbanslug05:06:26

would it be better not to namespace qualify the keys in the spec then or namespace qualify in the constants?

urbanslug05:06:47

it seems namespace qualifying is what's done

seancorfield05:06:00

It's up to you. You can write the spec for either approach.

urbanslug05:06:49

So an example like

(def example-person
  {:source-namespace/name "alice"
   :source-namespace/height 7})

urbanslug05:06:08

should be ok? I'm getting different errors but I'll work through them

urbanslug05:06:10

thanks a ton

seancorfield05:06:10

Also, the qualifiers used in specs don't actually need to match code namespaces -- if that makes your code more readable (and the qualifier is "unique enough" for your app).

👍 4
seancorfield05:06:51

So {:person/name "alice" :person/height 7} might be a reasonable way to write your data.

seancorfield05:06:23

And then your spec would be (s/def ::person (s/keys :req [:person/name :person/height]))

seancorfield05:06:57

The qualifier for ::person -- the namespace it is defined in -- doesn't have to match the qualifier in the keys.

👁️ 4
👍 4
yonatanel08:06:58

I'd like to have clojure on golang, specifically these two and preserving their strengths. How do I even start? :)

noisesmith15:06:31

one gotcha that many attempts to port Clojure run into is that normal Clojure code performs poorly without a high quality garbage collector. Last I heard Go didn't have a great gc, so that will likely be an issue.

yen10:06:18

Anyone using protocol buffers with Clojure? Which library is the best for that?

pesterhazy15:06:17

Has anyone written or used a Github Bot that runs cljfmt fix on your project? That would be super handy

Björn Ebbinghaus21:06:21

@alexmiller So I used (s/or) without parameters by accident and got some confusing results regarding valid? and explain. Is this a bug or am I missing something? Here an example.

(s/valid? (s/or) :something)
=> false
(s/explain (s/or) :something)
Success!
=> nil

Alex Miller (Clojure team)21:06:28

I’d say one of those is a bug :)

😆 4
Alex Miller (Clojure team)21:06:37

Feel free to file a ticket

Alex Miller (Clojure team)21:06:08

I’d say the valid? answer is right and the explain answer is the bug

dpsutton21:06:46

we found explain was more correct than valid

dpsutton21:06:13

valid doesn't correct handle predicates so it fails. explain correctly handles predicates so it explains success

Alex Miller (Clojure team)21:06:43

I think you’re confusing the issue

dpsutton21:06:48

possible 🙂

dpsutton21:06:51

sorry if so

Alex Miller (Clojure team)21:06:01

That ticket is about s/every which is not relevant here

Alex Miller (Clojure team)21:06:30

This is about the explain of s/or

dpsutton21:06:04

my memory is too hazy. i'll have to relook at it

dpsutton21:06:27

(s/valid? (fn [x] (s/or)) :something) true vs (s/valid? (s/or) :something) false I think is an example of it

Alex Miller (Clojure team)22:06:00

Well if you find it, put it on the ticket