Goroutines in Clojure

Goroutines

In this example, we’ll explore how to use goroutines, which are lightweight threads of execution. We’ll show a function execution both synchronously and asynchronously using goroutines.

(ns goroutines
  (:require [clojure.java.io :as io]
            [clojure.core.async :refer [go]]))

(defn f [from]
  (doseq [i (range 3)]
    (println from ":" i)))

(defn -main []
  ;; Synchronous function call
  (f "direct")

  ;; Asynchronous function call using a goroutine
  (go (f "goroutine"))

  ;; Anonymous function call via goroutine
  (go (println "going"))

  ;; Sleep to wait for goroutines to finish
  (Thread/sleep 1000)
  (println "done"))
  1. Defining the Function: We define a function f that takes a string argument from and prints it along with a loop counter i.

    (defn f [from]
      (doseq [i (range 3)]
        (println from ":" i)))
  2. Main Function: The -main function demonstrates different ways to call the function f.

    • Synchronous call:

      (f "direct")
    • Asynchronous call using go macro from core.async to simulate goroutines:

      (go (f "goroutine"))
    • Anonymous function call via go macro:

      (go (println "going"))
    • Sleep to ensure the main thread waits for the goroutines to finish:

      (Thread/sleep 1000)
      (println "done")
  3. Execution: To run the program, save the code in a file (e.g., goroutines.clj) and execute it within a Clojure environment.

    $ clj -M -m goroutines

Example Output

When this program runs, you will see the output of the synchronous call first, followed by the mixed output of the goroutines, as they run concurrently.

direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
done

This example illustrates how to use asynchronous execution in Clojure, leveraging core.async for functionality similar to goroutines.