Reputation: 150654
I have the following snippet of Common Lisp code:
(loop repeat len
do
(rotatef
(nth (random len) list)
(nth (random len) list))
finally
(return list)))))
that I would like to get to run using Clojure.
Anyway, the compiler tells me that
loop requires a vector for its binding
What exactly does this mean? Where do I have to introduce a vector?
Upvotes: 3
Views: 149
Reputation: 38809
The purpose of your example is to shuffle a list. For completeness's sake, in Common Lisp, you could use alexandria:shuffle
to perform the same task on generalized sequences and the equivalent function in clojure is clojure.core/shuffle
.
There is a library called clj-iter
which is inspired by CL's iterate
function, which itself is a based on loop
. However, people tend to avoid using such constructs in Clojure and prefer functional composition, etc.
Only very trivial expressions like (+ 3 4)
can be parsed and interpreted as both Clojure and Common Lisp code. Clojure does not try to be compatible in any way with existing Lisp or Scheme languages and has its own computation model which discourages the use of mutable structures, like done with rotatef
in your example. Hence, porting Common Lisp code to Clojure requires to redesign the existing code just as-if you had to rewrite it in Scala (or Python or Ruby).
I don't really know what you are trying to perform, but if you want to run Common Lisp code on the JVM, you can use ABCL (Armed Bear Common Lisp), which is an efficient implementation of CL in Java.
Upvotes: 3
Reputation: 14197
This is how you use loop:
(loop [n 0]
(if (> n 10)
n
(recur (inc n))))
The "loop requires a vector for its binding" message comes from the first argument to loop, in the example above this is [n 0], which is a vector, saying we initialize the variable n to 0. later on when we use recur, we mean we want to repeat the body of the loop with a new value of n.
Reminder, loop in clojure is a function of a vector and some expressions as body:
(loop [bindings*] exprs*)
Upvotes: 3