Warning: Effeck is v0. The language will change in major, breaking ways. It is not suitable for production use.

Dual APIs

Many Effect APIs accept either the data followed by options or options followed by the data. These are the data-first and data-last forms of a dual API. Effeck preserves both forms. With the pipe operator, |>, and method syntax on Effect's data types, the data-first form usually reads best.

Data first or data last

const source = Stream.make(5, 10, 15)
const direct = source.map((n) => n / 5)
const stage = Stream.map((n: number) => n / 5)
const piped = pipe(source, stage)

function compare() {
  return [direct.runCollect(), piped.runCollect()]
}
// Both arrays are [1, 2, 3].

The direct form supplies source in the first call. The data-last form first builds a stage, then pipe supplies source. Both build the same kind of Stream value and defer stream processing until consumption. These builders and their returned stages are trusted Effect library functions.

Direct calls and program pipelines

function lookup() {
  sleep("10 millis")
  return "found"
}

function directLookup() {
  return timeout(lookup(), "1 second")
}

function pipedLookup() {
  return lookup() |> retry(%, { times: 2 }) |> timeout(%, "1 second")
}

Each % stands for the expression before its |>. Where % is an argument that expects a program, as the first argument of retry and timeout does, that expression is passed by name: retry runs lookup() again on each attempt, and timeout limits the whole retried computation. Where % is an argument that expects a value, the expression runs once and % is its result.

Choosing a form

function boundedLookup() {
  return retry(lookup(), { times: 2 })
}

const reusableLookup = () => lookup() |> retry(%, { times: 2 }) |> timeout(%, "1 second")

A direct call suits one operator; a pipe keeps several operators readable. Wrap the complete pipe in a function when you want a reusable program rather than its result. For transformations that only use a completed value, ordinary statements are usually clearer than Effect.map or Effect.flatMap.