Search code examples
clojurebreaktail-recursion

Clojure: Implementing the some function


I'm new to clojure and tried to implement the some function (for some specific tests):

(my-some even? [1 2 3 4]) => true

(my-some #{3 4} [1 2 3 4]) => 3

(my-some zero? [1 2 3 4]) => nil

That's what I came up with so far:

(defn my-some [f x]
 (loop [[y & t] x]
  (if (empty? t) nil
   (if (f y)
    (f y)
   (recur t)))))

I could imagine there are more idiomatic approaches. Any suggestions?


Solution

  • Firstly, you have a bug: [[y & t] x] destructures x, but the following empty? check on t means you are ignoring the last element in the sequence. You can see this with

    (my-some even? [2])
    => nil
    

    You can replace (if (empty? x) nil (else-form)) with when and seq:

    (when (seq x) ...)
    

    you can then use first and next to deconstruct the sequence:

    (defn my-some [f x]
      (when (seq x)
        (if (f (first x))
          (f (first x))
          (recur f (rest x)))))
    

    the call to recur is then back into my-some so you need to pass the predicate f.

    you can replace (if x x (else ....)) with (or x (else ...)):

    (defn my-some [f x]
      (when (seq x)
        (or (f (first x)) (recur f (next x)))))
    

    you can compare this with the implementation of some