Golo Roden
Golo Roden

Reputation: 150654

Does Clojure support the loop repeat form?

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

Answers (2)

coredump
coredump

Reputation: 38809

Shuffling

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.

Loop construct

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.

Clojure is a separate language

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

ABCL

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

Nicolas Modrzyk
Nicolas Modrzyk

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

Related Questions