Clojure

recur ignores rest args

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Resolution: Declined
  • Affects Version/s: None
  • Fix Version/s: Backlog
  • Component/s: None
  • Labels:
    None

Description

When you recur inside a function, the arguments are not assigned as expected:

(defn weird [& b]
(println b)
(when (< (first b) 2)
(recur (inc (first b)))))

(weird 1)

The first time it runs, b is a seq, but the second time it's just an integer.

After some discussion I found out this is because there's no way to apply recur, so technically making recur act as a normal function call means you can't pass a seq of args in. While this is arguably a decent workaround, it leads to very confusing, undocumented behaviour; at the very least it should be tracked in an issue until a better solution can be found.

Activity

Hide
Assembla Importer added a comment -
Show
Assembla Importer added a comment - Converted from http://www.assembla.com/spaces/clojure/tickets/283
Hide
Assembla Importer added a comment -

stu said: Recur doesn't re-enter the function, it just goes back to the top (the vararging doesn't happen again). Since b is a collection coming in, recur with a collection and you will be fine.

(defn weird [& b]
  (println b)
  (when (< (first b) 2)
    (recur (cons (inc (first b)) (rest b)))))

I find this intuitive, but when I launch the Assembla FAQ feel free to add an item for this if you like.

Show
Assembla Importer added a comment - stu said: Recur doesn't re-enter the function, it just goes back to the top (the vararging doesn't happen again). Since b is a collection coming in, recur with a collection and you will be fine.
(defn weird [& b]
  (println b)
  (when (< (first b) 2)
    (recur (cons (inc (first b)) (rest b)))))
I find this intuitive, but when I launch the Assembla FAQ feel free to add an item for this if you like.
Hide
Assembla Importer added a comment -

technomancy said: > I find this intuitive, but when I launch the Assembla FAQ feel free to add an item for this if you like.

OK. Anecdotally I asked four other seasoned Clojure users what they thought was going on here and only one had an explanation, so most folks are going to think this is an unintended result when they see it. I don't know if it's FA enough to qualify this for a FAQ, but even having this closed issue show up in search results is an improvement.

I know internally there's a difference between calling a function and executing the body of a function, but up till this point I considered that an implementation detail.

Show
Assembla Importer added a comment - technomancy said: > I find this intuitive, but when I launch the Assembla FAQ feel free to add an item for this if you like. OK. Anecdotally I asked four other seasoned Clojure users what they thought was going on here and only one had an explanation, so most folks are going to think this is an unintended result when they see it. I don't know if it's FA enough to qualify this for a FAQ, but even having this closed issue show up in search results is an improvement. I know internally there's a difference between calling a function and executing the body of a function, but up till this point I considered that an implementation detail.

People

  • Assignee:
    Unassigned
    Reporter:
    Anonymous
Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: