The intent of making it a macro is that it allows short-circuit evaluation, like Clojure's or/and. There is no reason to evaluate comparisons between keys when an earlier comparison has already decided the ordering.
Hardwiring in the compare function and the order between %1 and %2 is an interesting idea I hadn't considered, partly because it is often the case that one would like an ascending sort order on one key, but descending on others, which is commonly done by swapping %1 and %2's position, but could also be done by negating the return value of compare. Andy On Wed, Dec 7, 2011 at 6:59 PM, Alan Malloy <[email protected]> wrote: > This should be a function, not a macro. In fact it is just: > > (defn multicmp [& xs] (first (remove zero? xs))) > > But what you really wanted to begin with is a comparator function, so > more like: > > (defn multicmp [& keys] > (fn [a b] > (or (first (remove zero? (map #(compare (% a) (% b)) > keys))) > 0))) > > (sort-by (multicmp < =) coll) > > On Dec 7, 5:51 pm, Andy Fingerhut <[email protected]> wrote: > > I've been going through the PLEAC web site, writing Clojure examples > > corresponding to the Perl code examples from the Perl Cookbook: > > > > http://pleac.sourceforge.net > > > > Michael Bacarella started a github repo to collect these together, and > I'm > > helping flesh some of them out. > > > > https://github.com/mbacarella/pleac-clojure > > > > One thing that is very convenient in Perl is doing sorts on multiple > > comparison keys -- since 0 is treated as logically false in Perl, they > can > > simply do what in Clojure would look like: > > > > (sort #(or (compare (key1 %1) (key2 %2)) > > (compare (key2 %1) (key2 %2)) > > ...) > > collection) > > > > This doesn't work in Clojure, because it only treats nil or false as > > logically false. It is easy to write a short-circuiting macro 'multicmp' > > that does the correct thing: > > > > (defmacro multicmp > > ([x] x) > > ([x & next] > > `(let [cmp# ~x] > > (if (not= cmp# 0) > > cmp# > > (multicmp ~@next))))) > > > > Then just replace 'or' in the first code snippet with 'multicmp'. > > > > Does something like this already exist in a library I'm unaware of? > Would > > others find it useful to have around? And any suggestions on where it > best > > belongs if so? > > > > Thanks, > > Andy > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to [email protected] > Note that posts from new members are moderated - please be patient with > your first post. > 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 -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. 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
