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 }
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
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
Containing a CALL
An effect call on its own line, run with the module override in place.
WITH Network = Network.Mock
Network.Ping
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.