Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrays and loops in Clojure

Tags:

clojure

I am trying to learn the programming language Clojure. I have a hard time understanding it though. I would like to try to implement something as simple as this (for example):

int[] array = new int[10];
array[0] =1; 
int n = 10; 

for(int i = 0; i <= n; i++){
    array[i] = 0; 
}
return array[n]; 

Since I am new to Clojure, I don't even understand how to implement this. It would be super helpful if someone could explain or give a similar example of how arrays/for-loops works in Clojure. I've tried to do some research, but as for my understanding Clojure doesn't really have for-loops.

like image 802
coder Avatar asked Jan 30 '26 03:01

coder


1 Answers

The Clojure way to write the Java for loop you wrote is to do consider why you're looping in the first place. There are many options for porting a Java loop to Clojure. Choosing among them depends on what your goal is.

Ways to Make Ten Zeroes

As Carcigenicate posted, if you need ten zeros in a collection, consider:

(repeat 10 0)

That returns a sequence – a lazy one. Sequences are one of Clojure's central abstractions. If instead the ten zeros need to be accessible by index, put them in a vector with:

(vec (repeat 10 0))

or

(into [] (repeat 10 0))

Or, you could just write the vector literal directly in your code:

[0 0 0 0 0 0 0 0 0 0]

And if you specifically need a Java array for some reason, then you can do that with to-array:

(to-array (repeat 10 0))

But remember the advice from the Clojure reference docs on Java interop:

Clojure supports the creation, reading and modification of Java arrays [but] it is recommended that you limit use of arrays to interop with Java libraries that require them as arguments or use them as return values.

Those docs list some functions for working with Java arrays primarily when they're required for Java interop or "to support mutation or higher performance operations". In nearly all cases Clojurists just use a vector.

Looping in Clojure

What if you're doing something other than producing ten zeros? The Clojure way to "loop" depends on what you need.

You may need recursion, for which Clojure has loop/recur:

(loop [x 10]
  (when-not (= x 0)
    (recur (- x 2))))

You may need to calculate a value for every value in some collection(s):

(for [x coll])
  (calculate-y x))

You might need to iterate over multiple collections, similar to nested loops in Java:

(for [x ['a 'b 'c] 
      y [1 2 3]]
  (foo x y))

If you just need to produce a side effect some number of times, repeatedly is your jam:

(repeatedly 10 some-fn)

If you need to produce a side effect for each value in a collection, try doseq:

(doseq [x coll]
  (do-some-side-effect! x))

If you need to produce a side effect for a range of integers, you could use doseq like this:

(doseq [x (range 10)] 
  (do-something! x))

...but dotimes is like doseq with a built-in range:

(dotimes [x 9] 
  (do-something! x))

Even more common than those loopy constructs are Clojure functions which produce a value for every element in a collection, such as map and its relatives, or which iterate over collections either for special purposes (like filter and remove) or to create some new value or collection (like reduce).

like image 145
Dave Liepmann Avatar answered Jan 31 '26 16:01

Dave Liepmann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!