On Wed, Jun 15, 2011 at 10:08 AM, Kevin Sookocheff
<kevin.sookoch...@gmail.com> wrote:
> Hi, I'm going through some Scheme code to learn Clojure.  I defined a
> function
>
> rember
>
> as
>
>
> (defn rember [atom l]
>         (loop [a atom lat l]
>            (cond
>              (empty? lat) `()
>              (= (first lat) a) (rest lat)
>              :else (cons (first lat) (recur a (rest lat))))))
>
>
> To which the REPL responds:
>
> Can only recur from tail position
>   [Thrown class java.lang.UnsupportedOperationException]
>
> Is the call to recur not in tail position here?

Nope. The return from recur has to be, directly, the return from the
enclosing loop form for it to be a tail position. Here you're consing
something onto it in between. Generally that means you need to add a
result accumulator to the loop, something like:

(defn rember [atom l]
  (loop [a atom lat l res []]
    (cond
      (empty? lat) res
      (= (first lat) a) (rest lat)
      :else (recur a (rest lat) (conj res (first lat))))))

though I can think of further improvements, like hoisting a out of the
loop (it doesn't change) and using seq/next like so:

(defn rember [atom l]
  (loop [lat (seq l) res []]
    (if lat
      (let [f (first lat)]
        (if (= f atom)
          (rest lat)
          (recur (next lat) (conj res f))))
      res)))

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
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