Goroutines in PureScript

A goroutine is a lightweight thread of execution.

module Main where

import Prelude
import Effect (Effect)
import Effect.Aff (Aff, delay, launchAff_)
import Effect.Class.Console (logShow)

f :: String -> Effect Unit
f from = for_ [0, 1, 2] \i -> logShow (from <> " : " <> show i)

main :: Effect Unit
main = do
  -- Synchronous call
  f "direct"

  -- Concurrent call using Aff for asynchronous effect
  launchAff_ $ do
    f "goroutine"
    delay 1000.0
    logShow "done"

  -- Concurrent call using an anonymous function
  launchAff_ $ do
    logShow "going"
    delay 1000.0
    logShow "done"

Suppose we have a function call f("s"). Here’s how we’d call that in the usual way, running it synchronously.

f "direct"

To invoke this function concurrently as in goroutine, we use launchAff_ from the Effect.Aff module to execute it asynchronously.

launchAff_ $ f "goroutine"

You can also start a concurrent execution for an anonymous function call.

launchAff_ $ do
  logShow "going"
  delay 1000.0
  logShow "done"

Our two function calls are running asynchronously in separate contexts now. Wait for them to finish by adding appropriate delays or using more robust approaches like using promises or callbacks.

When we run this program, we see the output of the blocking call first, then the output of the two async calls. The async calls’ output may be interleaved, because they are being run concurrently.

$ spago run
direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
done
done