On Mar 22, 10:54 am, Stuart Halloway <stuart.hallo...@gmail.com> wrote: > >> The questions below refer to the gist > >> athttps://gist.github.com/336674/9ab832a86d203731c6379404d20afded79fe5f5b > >> and to protocols in general: > > >> (1) Clojure automatically types hints the first argument when > >> extending a protocol to an interface or class, which is great. But > >> you cannot override this with your own type hint. Wanting to do > >> this would be very unusual, but see the RandomAccess/List case in > >> the example where one interface signifies the performance > >> characteristics but a different interface has the methods you want. > >> Should it be possible to override the type hint? > > > No. Your wanting to do this is a hint that extending the protocol to > > RandomAccess is not quite right. > > Can you elaborate a little here? I can't extend to List, since I don't > want all Lists, only those that are also RandomAccess. >
You can't do a good job extending this generically (e.g. (-> coll class .newInstance) is reflective and very slow, and not guaranteed to work on all types), so you should only support specific classes. > >> (2) The code for chop is repeated across multiple classes. What is > >> the idiomatic way to DRY this? Should I drop down to using raw > >> extend with maps, or is there more mixin support to come? > > > The idiomatic way is to write an ordinary function, e.g. chop is not > > primitive and can just be written in terms of the protocol. > > I considered this, but thought it would be less discoverable. > Does the > caller care that chop is not primitive? I will argue no. That last bit is what I'm saying, you should choose either a protocol fn or regular fn as appropriate, which one is an implementation detail as far as the caller is concerned. Non-protocol fns might become protocol fns (or be built on same) later on, without affecting clients at all. > The caller > wants, given (say) a String, an easy way to ask "what things can I do > with strings?" I don't see how protocols help you answer that one way or the other. There will always be an open set of non-co-located fns and protocols that might work with String. > Separating protocols from non-primitive functions > creates more places to look. > In fact using protocols to begin with > creates more places to look They are not separated, they are together, both being functions in a namespace. People will find them just as they have always found functions, in namespace documentation. > (right now the string functions all live > in clojure.contrib.string). > Not so. count, seq etc all work with strings and are not in c.c.string > >> (3) The code for slice is also repeated, but only for one arity. > >> Does that change the answer to #2? It's the same answer. Implementing a fn as a protocol fn is an implementation detail of primary interest to extenders. Consumers need only know that foo works on Bars, not how it does so. It will quite often be the case that some nice 10-function API might require the implementation of a 3-function protocol in order to extend it. A protocol is a minimal specification of an abstraction, not a totality of an API. > >> (5) It appears that the overhead for calling a protocol adds a hash > >> lookup (find-protocol-method) over the method invocation itself. Is > >> that the right way to summarize the performance implications? > > > No, since the result is cached. The real every-call overhead is > > having to go through the var to detect changes to the protocol, vs > > the inline-defined case where the implementation of the interface > > can't change given the same instance class. > > Am I saying something different? The cache requires a hash lookup, > right? Only once. There is call-site caching of protocol fns, with no per- call lookup as long as the target class remains the same. Rich -- 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 To unsubscribe from this group, send email to clojure+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.