Why this fires¶
Parameters after * must be supplied with their public labels. The marker is
a separator; it does not add a parameter. Parameters before it retain their
existing positional and label rules.
fn transfer(prefix: int, *, from source: int, to target: int = 10) -> int =
prefix + target - source
transfer(1, from: 3) // valid; to uses its default
transfer(1, to: 8, from: 3) // valid; labels may be reordered
transfer(1, 3) // TE188; write from: 3Use the public label (from), even when the function binds a different
local name (source). Named puns keep their normal caller binding:
let from = 3; transfer(1, from:). Defaults and nullable parameters may still
be omitted. An explicitly supplied value, including nil, requires its label.
The rule travels with methods and typed function values, including values returned from a function, imported from a module or stored in a collection.
type Sender = fn(*, from: int, to: int) -> int
fn apply(sender: Sender) -> int = sender(from: 2, to: 7)A required-name callable cannot be assigned to a function type that promises unlabelled positional calls. Keep the required names in the annotation or provide a wrapper that supplies them explicitly. A pipe, operator or tagged literal also cannot provide a required slot positionally. Omitted named slots with defaults retain their normal omission rules.
Duplicate, unknown and out-of-order argument errors retain their existing diagnostics. Invalid separator placement or a parameter without a usable public label is rejected by the parser.
TE188 describes the required label: spelling. It deliberately provides no
automatic source edit; a label must be added at the actual authored call site.