I think map is a good example where the different arities have very different semantics, and maybe it would be practical to specify a separate spec for each arity.
In the unified spec, both :args and :ret have to resort to (more or less explicit) unions in order to express the sum of the separate cases, and :fn is complicated in order to disallow the undesired combinations. Francesco On Tuesday, June 14, 2016 at 1:22:23 PM UTC+2, Alex Miller wrote: > > I was suggesting that you could do something like this (although I'm > pretty sure this doesn't work right now): > > (s/fdef map > :args (s/cat :f (s/fspec :args (s/+ ::s/any)) > :colls (s/* seqable?)) > :ret (s/or :seq seqable? :transducer ifn?) > :fn #(if (zero? (count (-> % :args :colls))) > ;; transducer > (ifn? (-> % :ret)) > ;; lazy seq > (and (seqable? (-> % :ret)) > (= (count (-> % :args :f :args)) > (count (-> % :args :colls)))))) > > > > In the map :args, spec the mapping function as well, then use :fn which > can either relate the args and ret of the main function OR relationships > between the args, as I'm doing at the very end. The input to :fn is the > conformed output of the :args and :ret specs. > > But like I said, there are several problems with this right now and I need > to discuss more with Rich whether something like this should be possible > (mostly the args fspec is where I'm seeing issues. > > > On Monday, June 13, 2016 at 7:57:16 PM UTC-5, Alistair Roche wrote: >> >> 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 <grapent...@gmail.com >> <javascript:>> 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, >>>> >>>> >> -- 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.