I just want to point out that I incorrectly stated that Clojure generates 
abstract stubs for unimplemented protocol methods (or types, for that 
matter). In fact, Clojure does nothing about them. For classes to fully 
implement interfaces is enforced by the Java compiler, not the JVM.

On Thursday, March 8, 2012 11:40:20 PM UTC-8, Garth Sheldon-Coulson wrote:
>
> I think Tassilo's ideas about extenders deserve more discussion. But let 
> me continue the discussion with Armando for now.
>
> Thank you for offering the Eclipse API example, which is very helpful. I 
> agree that Java's OO paradigm creates the need for abstract classes. 
> However, I would like to look further at what is going on in the Eclipse 
> example and consider if protocols in Clojure are the same or different.
>
> To clarify the example: Eclipse allows the user to add the user's own 
> methods for certain kinds of event-handling. Because the language is Java, 
> these methods must be attached to a class. In order for Eclipse to specify 
> which methods it expects, Eclipse provides an interface that the user's 
> class must implement. For convenience, Eclipse also provides default 
> implementations of the required methods; these are provided in an abstract 
> class. When the user extends this abstract class, the user can elect to 
> override none, some, or all of the default methods.
>
> I have a few observations.
>
> 1) In the example, it is certainly true that the user may implement none 
> or just some of the methods of the interface. However, when the user 
> finally passes an object instance to Eclipse, *all* of the methods of the 
> interface are in fact implemented by that instance. This is because the 
> default implementations in the abstract class will fill any holes the user 
> leaves. Therefore, I respectfully disagree that this is case of "partial 
> implementation." It may appear so to the user, but not to the language.
>
> 2) It is true that a Java abstract class can partially implement an 
> interface. However, an abstract class cannot be instantiated. It must be 
> extended first. When extending an abstract class, the user must implement 
> any methods that the abstract class has not implemented. No concrete class 
> "partially implements" an interface.
>
> To me, the analogy to Java therefore supports the idea that the extends? 
> relationship ought to require a datatype/record to implement all of its 
> protocols' methods. A datatype/record is a piece of data, not a collection 
> of default methods; it is therefore like an object instance, not an 
> abstract class. Object instances must implement all of their interfaces' 
> methods.
>
> As I said in my last post, it would seem strange for a language to provide 
> protocols (rather than just fast, un-grouped multimethods) if a piece of 
> data that "satisfies" a protocol does not necessarily implement even one of 
> the protocol's methods.
>
> 3) Armando's worry is valid that requiring implementation of protocol 
> methods would result in "proliferation of interfaces and protocols that 
> would prevent reuse; something like 
> ListWithoutModificationOrBulkOperations." 
>
> However, to me the beauty of protocols is that they can be highly 
> granular. They are not tied to a rigid inheritance paradigm. They support 
> direct implementation composition. If, per Armando's example, a protocol 
> designer felt the need to have a BasicList protocol, a ModifiableList 
> protocol, and a BulkOperations protocol, to be combined as necessary, that 
> would be just fine. 
>
> 4) In /The Joy of Clojure/, a few of the examples involve extending a type 
> to implement just one of a protocol's multiple methods (pp. 193-195). The 
> authors consider this a valid use case. To leave the /JoC/ examples roughly 
> intact while giving protocols a bit more bite, let me throw out two ideas 
> for discussion.
>
> Idea 1
> ======
>
> Types may be extended to a strict subset of a protocol's methods, but 
> satisfies? and extends? will return FALSE, not true, in this case. That is:
>
> => (defprotocol Fixo
>      (fixo-push [fixo value])
>      (fixo-pop [fixo]))
> Fixo
>   
> => (extend-type clojure.lang.IPersistentVector
>      Fixo
>      (fixo-push [vector value]
>        (conj vector value)))
> [succeeds]    
>
> => (extends? Fixo clojure.lang.IPersistentVector)
> FALSE, not true
>
>
> Idea 2
> ======
>
> Types may be extended to new protocols only if *all* of the protocol's 
> methods are implemented. However, types may be always extended tonew, 
> ungrouped *methods*. That is:
>
> => (defprotocol Fixo
>      (fixo-push [fixo value])
>      (fixo-pop [fixo]))
> Fixo
>   
> => (extend-type clojure.lang.IPersistentVector
>      Fixo
>      (fixo-push [vector value]
>        (conj vector value)))
> [should FAIL - protocol name not allowed here unless all methods are 
> implemented]  
>
> => (extend-type clojure.lang.IPersistentVector
>      nil
>      (fixo-push [vector value]
>        (conj vector value)))
> [should SUCCEED - fixo-push is like a fast multimethod, without a named 
> protocol]
>
> => (extends? Fixo clojure.lang.IPersistentVector)
> FALSE, not true
>
>
> I invite discussion and criticism.
>
> All the best, Garth
>
>
> On Thursday, March 8, 2012 11:24:42 AM UTC-5, Armando Blancas wrote:
>>
>> (Don't know why I can only respond to the first message.)
>>
>> I come across partial implementation all the time, and with proxy, too. 
>> In Eclipse this is so common that this is typical:
>>
>> "This adapter class provides default implementations for the methods 
>> described by the SelectionListener interface.
>> Classes that wish to deal with SelectionEvents can extend this class and 
>> override only the methods which they are interested in."
>>
>> You may have seen the idea of optional operation in java.util.List and 
>> how it's handled in places like AbstractList with default implementations. 
>> Clojure itself has partial implementations of List in PersistentList and 
>> Collection in PersistentQueue. I suppose the alternative would be a 
>> proliferation of interfaces and protocols that would prevent reuse; 
>> something like ListWithoutModificationOrBulkOperations could have a full 
>> implementation but little use.
>>
>> I can see the value of your view of protocol as spec, but maybe for 
>> domain-realted concepts and less for plumbing. 
>>
>

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

Reply via email to