How do I use lightweight threading in Clojure?
I tried to rewrite this Rust code in Clojure:
fn main() {
let nums = [1, 2];
let noms = ["Tim", "Eston", "Aaron", "Ben"];
let mut odds = nums.iter().map(|&x| x * 2 - 1);
for num in odds {
spawn(proc() {
println!("{:s} says hello from a lightweight thread!", noms[num]);
});
}
}
Here is the Clojure code that did almost the same with the above Rust code
(def noms ["Tim", "Eston", "Aaron", "Ben"])
(doseq [i (take-nth 2 (rest noms))]
(println i "says hello from a lightweight thread!"))
Also, it doesn't use a thread.
- How do I write a "lightweight" stream (or something equivalent in Clojure terms)?
- This code is almost a direct translation from the imperial programming style. What's the idiomatic way to write?
source to share
Beware of terminology: the clojure example using futures does not create an easy thread, but rather a native OS thread. Rust does the same by default, but has a green thread runtime that provides lightweight semantics. Link: http://rustbyexample.com/tasks.html
Clojure doesn't support lightweight streams by default, but you can create them through the core.async library . Thus, the code will look something like this:
(require '[clojure.core.async :as async :refer :all])
(doseq [i (take-nth 2 (rest noms))]
(go (print (str i " says hello from a lightweight thread!\n"))))
The macro go
above will create the correct light thread *
* It wasn't clear in the comments as pointed out in the comments, so I'll try and clarify: core.async is supported by the Java thread pool, however the macro go
turns your code into a state machine that uses "parking" instead of "blocking". This means that you can have tens of thousands of go blocks supported by a limited number of real threads.
However, when using blocking IO, this advantage is difficult, which is explained by post . @hsestupin links below.
To understand how core.async deals with lightweight threads in the JVM, I recommend starting here: https://www.youtube.com/watch?v=R3PZMIwXN_g - this is a great video inside a macro go
.
The macro itself is implemented here
source to share