Look at the implementation of nth. Or how polymorphic unification works in ClojureScript core.logic for ISequential. I misspoke a bit, should have clearer that I simply meant that ILast (probably something else entirely) needs to be carefully considered since the logic needs too be moved to the actual fn or into a protocol default case in order to cover ISeq (which isn't a good idea anyway - IBoundedSeq or some such makes more sense to me).
On Saturday, June 30, 2012, Mark Engelberg wrote: > This is a continuation of issues raised in the thread about making the > core "last" function behave in a polymorphic manner. > > The separation of interfaces from implementation in Java serves several > purposes, but one thing it does is it allows the creation of abstract data > types, i.e., a type that is defined in terms of what it can do, rather than > what it is comprised of or how it is implemented. > > Right now, in Clojure, ISeq is an interface, and by extension, it is an > abstract type. One benefit this has is that we can polymorphically > dispatch, via a protocol, for example, on whether something is an ISeq. We > can easily create a function that applies to anything to which you can > "first" and "rest", and at the same time, we can leave the function open to > extension by other types. > > However, once ISeq is made into a protocol (which has already been done in > ClojureScript and may conceivably be done in the future in Clojure), there > is a problem. No longer can you dispatch via protocols on whether > something is an ISeq. In other words, by using a protocol to define ISeq. > we have lost its capabilities to express an abstract data type. Protocols > provide a way to polymorphically dispatch to various concrete data types > but appear to lose the ability to dispatch based on the abstract data type, > i.e., dispatching on what the object can *do*. > > A hypothetical polymorphic last function, proposed in that previous > thread, is a great example of why one would want to do this. A naive > implementation of a polymorphic last could take the form "(cond (vector? s) > ... (seq? s) ...)", but this is a closed implementation. If we want to > keep the implementation open for extension, you could use something like > the protocol-based code I wrote there, but it absolutely relies on these > abstract data types being represented as Java interfaces rather than other > protocols. > > David says that in 10,000 lines of code, there hasn't yet been something > that required protocols to dispatch on other protocols, but in nearly the > same breath he says that a polymorphic last function is impractical because > of this limitation. The difficulty, he notes, is that a hypothetical ILast > protocol can't be made to automatically work for all implementers of ISeq. > Every single person who ever wanted to implement ISeq would also have to > implement ILast. I would argue that as soon as you're ruling out ideas > such as a polymorphic last function specifically because it would make it > too difficult to maintain in a protocol-based system, that is clear > evidence that indeed, we *are* running into a real limitation of protocols. > > So, I would like to better understand this limitation, and brainstorm with > everyone about workarounds. > > I have some thoughts and ideas about this, but I want to better understand > the ClojureScript architecture first. David, could you walk me through the > implementation of nth, which is a very similar kind of function? I was > able to find the part of the code on Github where you define an IIndexed > protocol which provides a protocol for nth. However, I was unable to find > the place in the code where you implement nth in linear time for all those > who implement ISeq and faster for random-access collections. Can you point > me to the relevant source code? Is nth open to extension to other abstract > data types? Is nth guaranteed to work and gain the default implementation > for new data types that implement ISeq? Do coders need to remember to > implement IIndexed any time ISeq is implemented, and if so, how is that > documented? > > Thanks! > > -- > 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<javascript:_e({}, 'cvml', > '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 <javascript:_e({}, 'cvml', > 'clojure%2bunsubscr...@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 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