Perhaps my choice of function names (abstract and concrete) for my
original post is not very appropriate.  I did not mean to apply the OO
concept of abstract class, abstract methods, etc.  Since it seems that
my original post did not convey my query clearly, I would try to
depict it with some "concrete" :) examples in the following.

Suppose I want to filter a list '(1 2 3 4 5 6 7 8 9) for all the
numbers which is less than 5, but I do not want to use the clojure
filter function.  I decide to roll out my own function using recursion
and con'sing as follows.

(defn smaller-than [a-list n]
  (cond (empty? a-list) '()
        'else (if (< (first a-list) n)
                (cons (first a-list)
                      (smaller-than (rest a-list) n))
                (smaller-than (rest a-list) n))))

Later, I want to filter for all numbers which is more than 7 from the
list.  I do not want to copy and paste and modify smaller-than.  To
maintain a single place of control, I introduce a function call
filter1.  I do a little bit abstraction and define some functions as
follows.

(defn filter1 [comparator a-list n]
  (cond (empty? a-list) '()
        'else (if (comparator (first a-list) n)
                  (cons (first a-list)
                      (filter1 comparator (rest a-list) n))
                  (filter1 comparator (rest a-list) n))))

(defn smaller-than [a-list n]
  (filter1 < a-list n))

(defn more-than [a-list n]
  (filter1 > a-list n))

Or I can define filter1 as follows:

(defn filter1 [comparator]
  (fn anonymous [a-list n]
    (cond (empty? a-list) '()
          'else (if (comparator (first a-list) n)
                    (cons (first a-list)
                        (anonymous (rest a-list) n))
                    (anonymous (rest a-list) n)))))

and use it the following way

(def smaller-than (filter1 <))
(smaller-than '(1 2 3 4 5) 3)

Or even ((filter1 <) '(1 2 3 4 5) 3)

I may define filter1 as is, what is now being done, accepting a
predicate as the parameter. There are just many choices on how to do
abstraction.

So back to my query on my original post.  Given that there are many
choices, how do I choose which way to do and why?  Is there really a
"better" way?  Or just by convention?  By preference?  Or is the
answer "it depends"?  But depends on what?  I would be glad to hear
your opinion.  Thanks.

P.S. a side note on recursion:  I may change the above filter1
function into tail call by introducing an accumulator parameter and
modify the function a little bit.  Is it generally a good thing to do
it?  I would like to hear some comments.  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
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