Keywords · WITH

WITH

A WITH block temporarily swaps one module's implementation for another over its indented body.

Format

The grammar of a single WITH line:

WITH ::= "WITH" module "=" replacement
module ::= name
replacement ::= name
name ::= identifier { "." identifier }
identifier ::= letter { letter | digit }
A WITH keyword is followed by the module to replace and the replacement to stand in for it after the =, over the indented body that follows.

Usage

A WITH keyword can only live inside a FUNCTION keyword.

Inside a FUNCTION

In a function body a WITH opens an indented block whose statements all run under the swapped module.

FUNCTION Ui.Element Ui.Content.Panel
  HOLE Ui.Element content
  WITH Logic = Ui.Logic
    content
A panel function that runs its hole's content with Logic swapped for Ui.Logic.

Everything inside runs with the override in place, and the swap is unwound as soon as that block closes — here the single indented line content invokes the HOLE, so the caller's block resolves every Logic name to Ui.Logic for the duration.

Why swap a module

Inside the user interface, the condition of Logic.If can be an asynchronous value that is not yet ready. The basic Logic simply renders nothing until it resolves — correct, but the user sees a blank where something is clearly loading. Ui.Logic is the same module with extra wiring into the interface: it tracks those not-ready conditions and shows a loading spinner while they settle. Wrapping a panel's content in WITH Logic = Ui.Logic means every Logic.If the caller writes inside it gains that spinner behaviour for free, without the caller ever naming Ui.Logic or knowing it exists.

Can Contain

The header names the module to replace and the implementation to put in its place, written WITH Module = Replacement. The replacement must satisfy the same shape as the module it stands in for, so callers inside the block see the same names with different behaviour. The indented lines below are the body that runs under the override.

Containing a LET

The body is ordinary statements run with the override in place — LET bindings, effect calls, or, as above, a single call into a HOLE's content. Every name they resolve as the swapped module is served by the replacement until the block ends.

WITH Logic = Ui.Logic
  LET Ui.Element panel = Ui.Content.Panel content
A binding in the body, run with the module override in place.

Containing a CALL

An effect call on its own line, run with the module override in place.

WITH Network = Network.Mock
  Network.Ping
A bare call in the body, run under the override.

Targets

The same example, rendered to each target; the renderer lowers WITH to a scoped override that installs the replacement module, runs the block, and restores the original binding.

JavaScript

// WITH installs Ui.Logic as Logic just for the block
function Panel(content) {
  return Module.With(Logic, Ui.Logic, function () {
    return content();   // the hole, run with Logic = Ui.Logic
  });
}

TypeScript

function Panel(content: () => Ui.Element): Ui.Element {
  return Module.With(Logic, Ui.Logic, () => content());
}

Dart

static Ui_Element Panel(Ui_Element Function() content) {
  return Module.With(Logic, Ui_Logic, () => content());
}

Swift

public static func Panel(_ content: () -> Ui.Element) -> Ui.Element {
  Module.With(Logic.self, Ui.Logic.self) { content() }
}

Go

func Panel(content func() Ui_Element) Ui_Element {
  return Module_With(Logic, Ui_Logic, func() Ui_Element {
    return content()
  })
}

Rust

pub fn Panel(content: Box<dyn Fn() -> ui::Element>) -> ui::Element {
  module::with(logic::MODULE, ui::logic::MODULE, Box::new(move || content()))
}

Zig

pub fn Panel(content: fn () ui.Element) ui.Element {
  return module.with(logic, ui.logic, struct { pub fn run() ui.Element {
    return content();
  } }.run);
}

JSON

["F", "Ui.Content.Panel", [], [
  ["content", [[], "Ui.Element"]]
], [
  ["W", "Logic", "Ui.Logic", [
    ["call", "content", [], []]
  ]]
]]

Related

WITH almost always wraps a HOLE's content inside a FUNCTION, and the module it swaps is an ordinary MODULE — here Logic standing in for Ui.Logic. Back to the language.