Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-mediator

In-process messaging for Pudu: requests, notifications, streams, pipeline behaviors, processors, and exception handling

0.1.0Apache-2.01

InstallClose

Erasure.pudu

Pudu38 lines1.3 KB

GitHub ↗
1/** @Utils.Erasure.Module — values carried without naming their type */2module PuduLangMediator.Utils.Erasure34import Std.Sync as Sync56/** @Utils.Erasure.Packed — a value whose type only its slot knows */7export type Packed = fn() -> ()89/** @Utils.Erasure.Slot — the one place a packed value of `T` reads back */10export type Slot[T] = { lock: Sync.Mutex, held: Sync.Cell[Option[T]] }1112/// A slot of its own: values packed through it read back only through it.13export fn slot[T]() -> Slot[T] { Slot{lock: Sync.mutex(), held: Sync.cell(None)} }1415/// The value packed so that only `target` reads it back.16export fn pack[T](target: &Slot[T], value: T) -> Packed {17  let held = target.held18  fn() -> () { let _stored = Sync.set(&held, Some(value)) }19}2021/// The value packed through `source`, or `None` when it was packed through another slot.22export fn unpack[T](source: &Slot[T], packed: &Packed) -> Option[T] {23  let held = source.held24  let run = *packed25  let read = Sync.withLock(&source.lock, fn() -> Option[T] {26      let _cleared = Sync.set(&held, None)27      run()28      match Sync.swap(&held, None) {29        case Ok(found) => found30        case Err(problem) => panic("an erased value could not be read: " + show(problem))31      }32    })33  match read {34    case Ok(found) => found35    case Err(problem) => panic("an erased value could not be locked: " + show(problem))36  }37}38