On Sunday, June 12, 2016 at 9:22:24 AM UTC-5, Leon Grapenthin wrote:
>
> That looks great already. I'm also interested in what the official 
> workflow for adding specs to core is going to be and whether contributions 
> are desired.
>

Still much to be determined about this but I expect that specs for core 
will be provided and maintained by us, because while there are a lot of 
obvious specs in core, there are also a lot of far more subtle ones. Some 
of the predicates added in the latest alpha5 (seqable?, and the 
simple/qualified ident/keyword/symbol) will not coincidentally be useful in 
these. There are also a lot of cases where there is a judgement call on how 
precise to be (any likely tradeoffs with testing, performance, conciseness).

Also, there is a significant difference between specs for macros and 
functions in core. Macro args specs will always be checked during 
macroexpansion and this is a path toward better error messages for things 
like defn, ns, etc. I think it would make a lot of sense to deliver those 
with core. Specs for the functions in core are things you likely want 
instrumented at dev time, not at prod time, and fights a bit with direct 
linking. So, one option would be a dev build of Clojure, without direct 
linking and with automatic instrumentation of the functions in core. 
Another would be providing the core function specs externally or optionally 
alongside Clojure. We've only begun discussing how this will wind up.

I don't agree with the map spec provided because I expect the args and ret 
to be seqable?, not sequential?. For example, you can map over sets, which 
are seqable but not sequential. This kind of subtlety is why I expect we 
will provide the specs for core. Once they exist, we'll be interested in 
tickets on them of course.

There are also interesting :fn specs you can write on map - you could check 
that if the count of the coll args is 0 that the return is ifn? (a 
transducer) and that if there is at least one coll then the ret is a coll. 
If the colls are all finite, the return coll will have count equal to the 
minimum of the count of the arg colls. I think the transducer/coll 
difference is definitely worth spec'ing and would trigger errors in cases 
where some forgets the coll and accidentally gets a transducer. Is the 
cardinality check worth it? Probably not.

identity could have a :fn spec that checks that the input and output are 
identical. That's really the only thing you care about (other than the 
cardinality of the input). Is this spec really helping you though? Not 
every spec pays for it's weight and this may be one that isn't worth doing.
 

> The last example seems like it could be better because the user has to 
> infer how identity was called within map.
>
> So what we'd want is a codependent spec where we can say if you give N 
> sequences you have to give a fnN. Is this possible with the current ops?
>

Yes, with fspec - you could have a :fn spec on map that checked that the 
arity of the fn passed to map matched the number of colls you were passed. 
That would be better here than the identity spec.
 

>
>
> On Sunday, June 12, 2016 at 3:52:33 PM UTC+2, Ryan Fowler wrote:
>>
>> Is there an effort to write specs for Clojure's core namespaces? Apologies 
>> if this has already been addressed.
>>
>> I've been tinkering with trivial (and probably wrong) fdefs on 
>> clojure.core/map and clojure.core/identity. It seems that the spec 
>> exception messages are way better than what we have now.
>>
>> Code is here: 
>> https://gist.github.com/ryfow/69a64e966d48258dfa9dcb5aa74005eb 
>> <https://www.google.com/url?q=https%3A%2F%2Fgist.github.com%2Fryfow%2F69a64e966d48258dfa9dcb5aa74005eb&sa=D&sntz=1&usg=AFQjCNF-D1x8PJNLKRUrdziNcKrzqh87LQ>
>>
>>
>> =========================================================
>> Before instrumenting clojure.core/map
>> =========================================================
>> Form:             (into [] (map nil [1 2 3] [1 2 3]))
>> Exception Class:  java.lang.NullPointerException
>> Message:          nil
>>
>> Form:             (into [] (map 1 [1 2 3] [1 2 3]))
>> Exception Class:  java.lang.ClassCastException
>> Message:          java.lang.Long cannot be cast to clojure.lang.IFn
>>
>> Form:             (into [] (map identity 4))
>> Exception Class:  java.lang.IllegalArgumentException
>> Message:          Don't know how to create ISeq from: java.lang.Long
>>
>> =========================================================
>> After instrumenting clojure.core/map
>> =========================================================
>> Form:             (into [] (map nil [1 2 3] [1 2 3]))
>> Exception Class:  clojure.lang.ExceptionInfo
>> Message:          Call to #'clojure.core/map did not conform to spec:
>> In: [0] val: nil fails at: [:args :fn] predicate: ifn?
>> :clojure.spec/args  (nil [1 2 3] [1 2 3])
>>
>>
>> Form:             (into [] (map 1 [1 2 3] [1 2 3]))
>> Exception Class:  clojure.lang.ExceptionInfo
>> Message:          Call to #'clojure.core/map did not conform to spec:
>> In: [0] val: 1 fails at: [:args :fn] predicate: ifn?
>> :clojure.spec/args  (1 [1 2 3] [1 2 3])
>>
>>
>> Form:             (into [] (map identity 4))
>> Exception Class:  clojure.lang.ExceptionInfo
>> Message:          Call to #'clojure.core/map did not conform to spec:
>> In: [1] val: 4 fails at: [:args :seq] predicate: sequential?
>> :clojure.spec/args  (#object[clojure.core$identity 0x15a04efb 
>> "clojure.core$identity@15a04efb"] 4)
>>
>>
>> =========================================================
>> Before instrumenting clojure.core/identity
>> =========================================================
>> Form:             (into [] (map identity [1 2 3] [1 2 3]))
>> Exception Class:  clojure.lang.ArityException
>> Message:          Wrong number of args (2) passed to: core/identity
>>
>> =========================================================
>> After instrumenting clojure.core/identity
>> =========================================================
>> Form:             (into [] (map identity [1 2 3] [4 5 6]))
>> Exception Class:  clojure.lang.ExceptionInfo
>> Message:          Call to #'clojure.core/identity did not conform to spec:
>> In: [1] val: (4) fails at: [:args] predicate: (cat :one-argument 
>> identity),  Extra input
>> :clojure.spec/args  (1 4)
>>
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to