Chris Phillips
Chris Phillips

Reputation: 233

How do I use predicates in clojure?

I'm kinda new to clojure and I am unsure of how to use predicates. For instance, how do I make a function that returns the elements in a list that satisfies the predicate.

>(filter-in number? '(a 2 (1 3) b 7))
 (2 7)

 >filter in symbol? '(a (b c) 17 foo))
 (a foo)

I tried this but it does not work:

(defn filter-in [pred lst]
   (fn [x]
     (if (empty? lst)
       ()
       (if (pred (first lst))
         (cons (first lst) (filter-in pred (rest lst)))
         (filter-in pred (rest lst))))))

Thanks in advance.

Upvotes: 0

Views: 493

Answers (1)

YosemiteMark
YosemiteMark

Reputation: 675

As @Deigo_Basch points out in the comments, Clojure already has a built-in function 'filter' that does what you want.

However, if you're trying to create your own to help with your learning process, your solution is almost there:

(defn filter-in [pred lst]
     (if (empty? lst)
       '()
       (if (pred (first lst))
         (cons (first lst) (filter-in pred (rest lst)))
         (filter-in pred (rest lst)))))

Your original solution was actually defining a function that returned another function (the 'fn [x]' part). Higher-level functions like that that return other functions are often useful, but in this case you are looking for something that executes on its arguments directly.

Note also that your definition is not lazy, unlike Clojure's built-in filter. It also does not make use of Clojure's loop-recur mechanics, and thus may blow up the stack on large lists. These are features of Clojure that you will encounter soon as you learn more.

Upvotes: 1

Related Questions