Keywords · HOLE

HOLE

A HOLE is a callback parameter — a gap the caller fills with a block of their own.

Format

The grammar of a single HOLE line:

HOLE ::= "HOLE" [ type ] identifier
type ::= name [ "(" type { " " type } ")" ]
name ::= identifier { "." identifier }
identifier ::= letter { letter | digit }
A HOLE keyword is followed by an optional return type and then the hole's name.

Usage

A HOLE keyword can live inside FUNCTION and HOLE keywords.

Inside a FUNCTION

In a function, a hole is a gap the caller fills with a block of their own, declared after the function's inputs.

FUNCTION Collection.Array(ElementType) FromJsonArray(ElementType)
  INPUT Optional Code.Language.Json.Value jsonArray
  HOLE ElementType fromJson
    INPUT Optional Code.Language.Json.Value jsonElement
A function that takes a per-element callback as a hole.

A hole appears in a function after all of that function's INPUT parameters. A function may declare several holes; each is one block the caller supplies.

Inside a HOLE

Inside another hole, a nested hole makes the caller's block take a callback block of its own.

FUNCTION Collection.Array(ElementType) FromJsonArray(ElementType)
  HOLE ElementType fromJson
    INPUT Optional Code.Language.Json.Value jsonElement
    HOLE Text describe
A hole whose own block takes a further hole, nested one level deeper.

A hole may also sit inside another hole, after that hole's inputs: the block the caller passes in takes a callback block of its own.

Can Contain

A hole declares only its own parameters — the same parts a function's signature carries — because the body it runs is whatever the caller passes in. They appear in the same order: inputs first, then any nested holes.

Containing an INPUT

The hole's indented INPUT lines, in order, are the arguments the callback block is given each time the function invokes it. These are plain forward inputs.

FUNCTION Ui.Element List
  HOLE Ui.Element row
    INPUT Text item
The hole’s own input — an argument the callback block is given.

Containing a HOLE

A hole may itself declare further HOLEs, after its inputs. The block the caller supplies then takes callback blocks of its own — a hole whose argument is itself a block.

FUNCTION Ui.Element Wrapper
  HOLE Ui.Element outer
    HOLE Ui.Element inner
A hole nested in a hole — the caller’s block takes a block of its own.

Targets

The same example, rendered to each target.

JavaScript

// the hole becomes a callback parameter with its own arg
function FromJsonArray(jsonArray, fromJson) {
  // calls fromJson(jsonElement) for each element
}

TypeScript

function FromJsonArray<ElementType>(
  jsonArray: Code.Language.Json.Value | null,
  fromJson: (jsonElement: Code.Language.Json.Value | null) => ElementType,
): ReactiveValue<ReactiveArray<ElementType>> { /* ... */ }

Dart

static ReactiveValue<ReactiveArray<ElementType>> FromJsonArray<ElementType>(
  Code_Language_Json_Value? jsonArray,
  ElementType Function(Code_Language_Json_Value? jsonElement) fromJson,
) { /* ... */ }

Swift

public static func FromJsonArray<ElementType>(
  _ jsonArray: Code.Language.Json.Value?,
  _ fromJson: (Code.Language.Json.Value?) -> ElementType
) -> ReactiveValue<ReactiveArray<ElementType>> { /* ... */ }

Go

func FromJsonArray[ElementType any](
  jsonArray *Code_Language_Json_Value,
  fromJson func(jsonElement *Code_Language_Json_Value) ElementType,
) ReactiveValue[ReactiveArray[ElementType]] { /* ... */ }

Rust

pub fn FromJsonArray<ElementType>(
  jsonArray: Option<code::language::json::Value>,
  fromJson: Box<dyn Fn(Option<code::language::json::Value>) -> ElementType>,
) -> ReactiveValue<ReactiveArray<ElementType>> { /* ... */ }

Zig

pub fn FromJsonArray(
  comptime ElementType: type,
  jsonArray: ?code.language.json.Value,
  fromJson: fn (jsonElement: ?code.language.json.Value) ElementType,
) ReactiveValue(ReactiveArray(ElementType)) { /* ... */ }

JSON

["F", "FromJsonArray", ["ElementType"], [
  ["jsonArray", "Optional Code.Language.Json.Value"],
  ["fromJson", [[["jsonElement", "Optional Code.Language.Json.Value"]], "ElementType"]]
], [ /* body */ ]]

Related

An ordinary value parameter is an INPUT; holes belong to a FUNCTION and are how UI components nest their content. See Ui. Back to the language.