Fork me on GitHub
#clojure-spec
<
2016-06-13
>
t3chnoboy00:06:25

Is there a way to validate core.async chan type?

t3chnoboy00:06:57

I want to define a spec for a function which returns the following map:

{:in-chan (chan)
 :out-chan (chan)}

jfntn00:06:34

@t3chnoboy: you should be able to make a predicate for a ManyToManyChannel instance, or perhaps more generically test that (satisfies? ReadPort in-chan) and (satisfies? WritePort out-chan) also both defined somewhere in core.async...

t3chnoboy00:06:44

@jfntn something like:

#(instance? cljs.core.async.impl.channels.ManyToManyChannel %)
?

t3chnoboy00:06:08

Doesn’t look pretty...

jfntn00:06:49

indeed, think you could import ManyToManyChannel and reference it directly though

jfntn00:06:14

The protocol check is probably a better way to go however

dominicm08:06:00

@gfredericks: Yep, my specs make db queries. Spec has s/valid? to accomodate runtime validations (not just function checking in development time). I honestly think having two libraries, one for "types" and one for "db connecting checkers" would be wasted effort.

jimmy11:06:17

hi guys, I want to discuss a bit about spec. Spec is amazing, I can see the workflow that we can try out things in dynamic clojure, then add spec to it later to ready for production. But would spec have an optimization behind to check for example: we define a function with the args which is an integer? then spec will also generate a function with type hint integer beside doing the validation ? Then we can have something that is very flexible at output error and very fast code as well. Just my thought.

shem12:06:16

is there a way to write a spec that says "this map should contain these keywords, and only once each"?

stathissideris12:06:18

@shem: but keys can only appear once each in a map... by definition!

shem12:06:42

ergh, right. was eyeing generator output that spat several instances of the map. need more coffee

jimmy12:06:48

hi guys, how do we define a spec that can validate both namespaced key and non namespace key, for example : user/first-name and first-name one of those would be valid.

manderson14:06:55

@nxqd:

(s/def ::first-name string?)
=> :user/first-name

(s/def ::map-spec (s/keys :opt [::first-name]
                          :opt-un [::first-name]))
=> :user/map-spec

(s/valid? ::map-spec {::first-name "joe"})
=> true

(s/valid? ::map-spec {:first-name "joe"})
=> true

settinghead15:06:26

has anyone tried using core.async with clojure.spec? i ended up having a lot of functions that returns a channel in my code (`(defn [] (go …))`). i’d like to spec these functions beyond checking its type is ManyToManyChannel (i.e. checking what comes out the channel is valid based on a spec). I’m thinking of adding transducers to the returning channels. but is there a better overall approach? should i write my functions this way to begin with?

jimmy15:06:19

@manderson: I meant

(s/valid? ::map-spec {:user/first-name "joe"})
and (s/valid ::map-spec {:first-name "joe"})

manderson15:06:12

::first-name is the same as :user/first-name so either should work with above spec. Is that what you're asking?

manderson15:06:47

^ is the same if you are in the same namespace. :: simply appends the current namespace qualification to the keyword

jimmy16:06:22

@manderson: sorry, I was out. I will check on this, I think I miss understand something here.

jimmy16:06:25

yeah I did mis understand, it works fine. with user/first-name. thanks

jimmy16:06:48

@manderson: ah I have another question, if I refer the spec in another ns, it shouldn't work with :user/first-name case as long as I understand ?

manderson16:06:31

using the definition of :user/map-spec as defined above, it will validate fine for :user/first-name or :first-name. The namespaced keywords reflect the namespace they were defined in if set with ::.

jimmy16:06:31

ok, I see. in s/keys is there a way that we can validate something like :first-name or :user/first-name, one of those is required.

manderson17:06:56

hm, good question. this seems to work:

(s/def ::map-spec2 
  (s/or :qual (s/keys :req [::first-name] 
                        :req-un []) 
         :simple (s/keys :req [] 
                         :req-un [::first-name])))

manderson17:06:47

the keywords in or are just tags...

wotbrew19:06:26

Question, when should one specify a property of a function in the :fn of an fdef rather than in a proper test.check property?

danielcompton20:06:05

I’m pretty sure the answer will be “no”, but is there any way to use spec to define newtype’s, i.e. I have a username and a full-name which are both strings. Can I spec functions to stop passing a username where a full-name is required? For this discussion, assume that both strings have no distinguishing features you could use.

wotbrew20:06:03

You might be able to use conform with a custom conformer for 'full-name'. edit: never mind, it won't work - as you say such a conforming fn would never know the difference between the two values