Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 511
Golo Roden Avatar asked Jul 26 '26 17:07

Golo Roden


2 Answers

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*)
like image 139
Nicolas Modrzyk Avatar answered Jul 29 '26 08:07

Nicolas Modrzyk


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.

like image 29
coredump Avatar answered Jul 29 '26 07:07

coredump