Oh, I see what you mean now, Leon. Apologies for not reading more closely!
Yours is a much more interesting puzzle.

Here's an attempt I made
<https://gist.github.com/atroche/2248efce0dee46a92d021a8bf7e96237>, groping
towards it using reflection, but I couldn't even get that to work. Would be
curious to see what the solution is there, and even more so (like you) to
see if it can be done without reflection.

On 13 June 2016 at 17:21, Leon Grapenthin <grapenthinl...@gmail.com> wrote:

> Thank Alistair, but that does not really address my question. Alex
> suggested using :fn of fspec to check arity of a higher-order argument.
>
> But I could not find a tool to check function arity. Also I doubt :fn is
> going to work since I'd expect it to be invoked /after/ the call - i. e.
> the call would fail before the arity check.
>
> Note that in your example you can only use spec/generic testing to check
> arity because you know the argument types. You can't test a generic higher
> order fn for just arity like this because the generator won't know the
> correct types to generate.
>
>
> On Monday, June 13, 2016 at 4:00:30 AM UTC+2, Alistair Roche wrote:
>>
>> Hi Leon,
>>
>> I think you're looking for fspec
>> <https://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/fspec>,
>> unless I'm misunderstanding something. I wrote up an example
>> <https://gist.github.com/atroche/731f80376985773c60d5e943b38d8052> that
>> might be helpful.
>>
>> @Ryan thanks for starting this thread, and @Alex thanks for responding.
>> It's been an interesting discussion!
>>
>> Cheers,
>>
>>
>> On Monday, 13 June 2016 07:17:56 UTC+10, Leon Grapenthin wrote:
>>>
>>> Alex, thank you for the long and detailed response.
>>>
>>> The direct linking issue and Ryans last example make me wonder whether
>>> the hard rule
>>>
>>> "If A and B are both instrumented and if A ever calls B violating B's
>>> spec, A's spec is broken"
>>>
>>> holds? If so the direct-linking issue would probably be  a non-concern
>>> since instrumentation within the standard library would not matter because
>>> one could assume that the core lib has been tested already against it's own
>>> specs. If the latter is true (I'm not quite sure) it would appear
>>> worthwhile to look for a counter-example against the former in the standard
>>> library.
>>>
>>> I'd highly appreciate if you could give an example for checking the
>>> arity of a passed in function since I don't see how to do that right now
>>> except for maybe using reflection?
>>>
>>> On Sunday, June 12, 2016 at 5:45:17 PM UTC+2, Alex Miller wrote:
>>>>
>>>>
>>>> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/d_3V9MfLZmY/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
-- Alistair

-- 
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