Mark Engelberg wrote:
> Protocols:
> 
> I don't understand whether there's any way to provide a partial
> implementation or default implementation of a given
> protocol/interface, and I believe this to be an important issue.
> 
> For example, a protocol for < and > that provides a default
> implementation of > in terms of < and a default implementation of < in
> terms of >, so that you only need to implement one and you get the
> other for free.
> 

How about this?

(defprotocol MyComparable
   (comparinate [x y] "Returns a negative integer if x < y, zero if they
                   are equal and a positive integer if x > y.")
   (equal-to [x y]     "True if x is equal to y.")
   (less-than [x y]    "True if x is smaller than y.")
   (greater-than [x y] "True if x is greater than y."))

(defn mixin-comparable [type compare-fn]
   (extend type
      MyComparable
      {:comparinate compare-fn
       :equal-to     (fn [x y] (zero? (comparinate x y)))
       :less-than    (fn [x y] (neg?  (comparinate x y)))
       :greater-than (fn [x y] (neg?  (comparinate x y)))}))

(mixin-comparable Integer -)
(mixin-comparable String #(- (count %1) (count %2)))

(less-than 8 2)        ; => false
(less-than "x" "xxxx") ; => true

> I'm also thinking about the relationship in Clojure's source between
> ISeq and ASeq.  ASeq provides the partial, default implementation of
> more in terms of next, for example.  How does this kind of thing look
> with the new protocol system?

See above.  But another way would just be to define ASeq as a map and 
then merge with it:

(def aseq-impl {:more  (fn [obj] (if-let [s (next obj)] s '() ))
                 :count (fn [obj] ...)})

(extend MyList
   ISeq
   (merge
     aseq-impl
     {:next (fn [lst] ...)
      :count (fn [lst] ...) ; overrides the count from aseq-impl
      :cons (fn [lst x] ...)}))

Code is data. :-)

I don't know whether doing things this way is a good idea or not, but 
protocols are new: lets experiment and find out what works and what doesn't.

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