On Tue, Nov 4, 2008 at 10:00 AM, Christian Vest Hansen
<[EMAIL PROTECTED]> wrote:
>
> On Tue, Nov 4, 2008 at 3:12 PM, Rich Hickey <[EMAIL PROTECTED]> wrote:
>> On Nov 4, 9:00 am, "Christian Vest Hansen" <[EMAIL PROTECTED]>
>> wrote:
>>> "Generally" by custom but not required by contract of the Comparable
>>> interface. And those are all Numbers, right?
>>>
>>> Comparable imposes natural ordering, and the individual implementor is
>>> free to decide how to handle objects of different types; throwing a
>>> ClassCastException only being one of the possible reactions.
>>>
>>
>> True, except the individual implementors of Integer, Long, Double etc
>> have already decided to have them compare only to their exact type, so
>> we're stuck with that fact.
>
> So it does. I did not expect that; thought the standard numeric
> coercion rules applied.


For discussion's sake, here are a couple (lightly tested) functions
that might be helpful in determining the "greatest thing in a
sequence", given an arbitrary comparator or an arbitrary coercion
function. Two coercion-based fns are given -- a simpler one, and a
more efficient one (for expensive coercions).

Best,
Graham

(defn greatest-by
    "Return the 'largest' argument, using compare-fn as a comparison function."
    [compare-fn & args]
  (reduce #(if (pos? (compare-fn %1 %2)) %1 %2) args))

(defn greatest-coerce
    "Return the 'largest' argument by first coercing each argument to
    some type using coerce-fn, which must return a Comparable
    instance."
  [coerce-fn & args]
  (apply greatest-by  #(compare (coerce-fn %1) (coerce-fn %2)) args))

(defn greatest-coerce-2
    "Return the 'largest' argument by first coercing each argument to
    some type using coerce-fn, which must return a Comparable
    instance. This one performs a minimum number of coercions, which
    may be important if the coercion function is expensive."
    [coerce-fn & args]
  (second (reduce (fn [[bc b] a]
                      (let [ac (coerce-fn a)]
                        (if (pos? (compare ac bc))
                            [ac a]
                            [bc b])))
                  [(coerce-fn (first args)) (first args)]
                  (rest args))))

;; example

(let [nums [1 23423424.234234 2.1 4/5 1/10 1/256 2341/2]]
  (list (apply greatest-coerce float nums)
        (apply greatest-coerce-2 float nums))) ;; both should return same value

--~--~---------~--~----~------------~-------~--~----~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to