Channel Buffering in PureScript

PureScript doesn’t have built-in channels like Go, but we can simulate similar behavior using the Effect monad and mutable references. Here’s an example that demonstrates a similar concept to buffered channels:

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Effect.Ref as Ref

main :: Effect Unit
main = do
  -- Here we create a mutable reference that can hold up to 2 values
  messages <- Ref.new []

  -- Because this reference is mutable, we can add these
  -- values without a corresponding concurrent read
  _ <- Ref.modify (_ <> ["buffered"]) messages
  _ <- Ref.modify (_ <> ["channel"]) messages

  -- Later we can receive these two values as usual
  values <- Ref.read messages
  log $ show $ values !! 0
  log $ show $ values !! 1

By default, PureScript doesn’t have a direct equivalent to Go’s buffered channels. However, we can use mutable references (Ref) to achieve similar functionality. In this example, we’re using a Ref to store a list of strings, which acts as our “buffer”.

We create a mutable reference messages that can hold a list of strings. This is analogous to creating a buffered channel in Go.

We then use Ref.modify to append values to our list. This is similar to sending values to a buffered channel in Go. We can do this without immediately reading from the reference, just as we can send to a buffered channel in Go without an immediate receive.

Finally, we read from the reference using Ref.read and log the values. This is analogous to receiving from a channel in Go.

To run this program, you would typically compile it with the PureScript compiler and then run it with Node.js:

$ spago build
$ node -e "require('./output/Main').main()"
"buffered"
"channel"

This example demonstrates how we can achieve behavior similar to Go’s buffered channels in PureScript, even though the language doesn’t have this exact feature built-in.