Touch Grass

Common effect definitions for your Eat Your Greens (EYG) runtime.

Package Version Hex Docs

Every interaction between an EYG program and the outside world is managed via an effect. This includes filesystems, network sockets, clocks, randomness, environment variables and anything else.

Note, this library defines only interfaces, the types and encode/decode functions, not a concrete implementation. Your runtime will need to do that.

Usage

gleam add touch_grass

This example creates an EYG runner that allows programs to talk to the outside world via the Fetch effect.

import eyg/interpreter/break
import eyg/interpreter/expression as r
import eyg/interpreter/value
import gleam/fetch
import gleam/string

/// Accept the source as an EYG IR tree
pub fn run(source) {
  let scope = []
  loop(r.execute(source, scope))
}

/// Handle the raised effect if it is a fetch effect and resume.
/// Treat all other break reasons as an error.
fn loop(return) {
  case return {
    Ok(value) -> promise.resolve(Ok(value))
    Error(#(reason, _meta, env, k)) ->
      case reason {
        break.UnhandledEffect("Fetch", lift) ->
          case fetch.decode(lift) {
            Ok(request) ->
              loop(r.resume(fetch.encode(do_fetch(request)), env, k))
            Error(reason) -> promise.resolve(Error(reason))
          }
        _ -> promise.resolve(Error(reason))
      }
  }
}

fn do_fetch(request)  {
  send_bits(request)
  |> result.map_error(string.inspect)
}

fn send_bits(request) {
  use response <- promise.try_await(fetch.send_bits(request))
  fetch.read_bytes_body(response)
}

Design principles

The touch_grass library is influenced by patterns like Hardware Abstraction Layer (HAL) and ports and adapters.

Search Document