Skip to content
beskid The Beskid Book

Beskid

Jump to a Beskid service

Beskid

Jump to a Beskid service

09.3 Effects and purity

Where Beskid tracks compile-time effects vs runtime IO, spawn, and foreign calls.

Effects and purity

“Effects” in Beskid draws boundaries, not a monad tutorial: what happens at compile time in mods, what happens at runtime in fibers and syscalls, and what the type system can prove before you ship.

Metaprogramming is explicit:

  • Mod work runs through AOT-compiled type: Mod artifacts (no interpreted Beskid at compile time except via linked mod entrypoints).
  • Generators emit typed AST; analyzers register rewrites; hosts merge and re-parse under bounded rounds.
  • Those effects are compile-time only; they become ordinary program semantics after lowering.
flowchart TB
  accTitle: Compile-time effects to runtime
  accDescr: Mod work produces a merged typed AST, which passes through the semantic pipeline before runtime execution.
  mod[Mod collect / generate / analyze]
  ast[Merged typed AST]
  sem[Semantic pipeline]
  rt[Runtime execution]
  mod --> ast --> sem --> rt

User-visible runtime behavior (spawn, channel IO, syscall-backed console, FFI) lives under Evaluation, Execution runtime, and Core library. The language does not pretend println is pure; it routes IO through documented surfaces (panic-io and syscalls).

Beskid does not ship Haskell-style IO tracking in v0.x tutorials. Practical purity guidance:

PreferWhen
Pure functions + explicit ResultDomain logic you unit-test
spawn + channels for concurrencyCross-fiber communication (Fibers and spawn)
extern / [Extern] only at boundariesNative libraries with profile rules (FFI and extern)

Full index: Contracts and effects.

Panic vs contract