简体   繁体   中英

loop / return in Clojure. What is 'tail' position?

I'm just building up a function at the REPL and ran into this.
I define a symbol S and give it a value:

(def S '(FRUIT COLORS (YELLOW GREEN) SKIN (EDIBLE INEDIBLE)))

I want, eventually, a function that takes the first entry in the parameter list and any and all subsequent parameter pairs and applies them to the first entry. I never got that far in my coding. I want to use a loop / recur construct ( should I?), and here's how far I got in the REPL:

(loop [KV# (rest S)]
    (if (empty? KV#)
        nil
        (
            (pprint S, (first KV#), (second KV#))
            (recur (rest (rest KV#)))
        )
    )
)

I get a " can only recur from tail position " compiler error.
After looking everywhere about this including 7 or 8 articles in Stack Overflow, I can only ask: Huh?!
I'm new at this. If recur isn't in the tail position, could someone please explain to me why?
Something to do with 'if' statement syntax? GAHH. Clojure's not for the weak! Thank you.

You've made one of my favorite mistakes in Clojure - you've tried to use parentheses to group code. You need to use a (do...) form to group forms together, as in:

(loop [KV# (rest S)]
    (if (empty? KV#)
        nil  ; then
        (do  ; else
          (pprint S, (first KV#), (second KV#))
          (recur (rest (rest KV#)))
        )
    )
)

This gets rid of the "recur not in tail position" problem, but still fails - an arity exception on pprint - but I'll leave that for you to solve.

How did I spot this? My rule is that any time I find two left-parens together I immediately assume I've made a mistake and I need to figure out what I did wrong. In this case it was a little harder to spot because the left-parens were separated by intervening white space - but still, from the view of the lexical scanner they're adjacent to one another. So you just have to learn to think like a lexical scanner. :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM