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?
+3


source to share


2 answers


You can use future

to create threads. In this case, you can do something like:



(doseq [i (take-nth 2 (rest noms))]
  (future (print (str i " says hello from a lightweight thread!\n"))))

      

+2


source


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

+1


source







All Articles