On Wed, Jun 15, 2011 at 10:08 AM, Kevin Sookocheff
<[email protected]> 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 [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