Callable presets¶
This page is the reference for callable presets created with partial.
A callable preset is a callable derived from a target callable by presetting named arguments. Each preset parameter becomes a defaulted parameter whose default is the preset value, and the preset has the target's return type.
For the mental model and examples, see Callable presets explained.
Forms¶
| Form | Written as | Where |
|---|---|---|
| Top-level declaration | [pub] name = partial target(keyword=value, ...) |
At module level |
| Method partial | name = partial method(keyword=value, ...) |
In the body of a model, class, trait or newtype |
| Local partial expression | partial callable_expression(keyword=value, ...) |
Anywhere an expression is allowed |
pub def route(method: str, path: str) -> str:
return f"{method} {path}"
pub get = partial route(method="GET") # accepted
model Cell:
alive: bool
def set_state(mut self, state: bool) -> None:
self.alive = state
set_alive = partial set_state(state=true) # accepted
def status_line(method: str) -> str:
fetch = partial route(method=method) # accepted
return fetch("/health")
Every preset is a named argument; a positional preset is a syntax error, INCAN-P0001. A partial presets at least one argument.
Targets¶
| Form | Target |
|---|---|
| Top-level declaration | A function, declared or imported (partial math.sqrt(x=4.0)), a model, class or newtype constructor, or a symbol alias or top-level partial that resolves to one of these. A newtype constructor's parameter is named value. |
| Method partial | A method of the same type, named by its unqualified name or through a same-type method alias (display = label). |
| Local partial expression | A callable named by its name or path: a function, a generic function, a model, class or newtype constructor, a symbol alias, a top-level partial, or a method of a value (partial user.label(prefix="x")). |
A top-level target that is a const, a static, a module, an enum variant, a call expression, a local variable, a closure, a field or an unbound method is error INCAN-T0001. A local partial expression whose target is not callable, or is a variable or parameter holding a callable, is error INCAN-T0001.
A method of a value as a local partial's target is a method that takes self, of a local, of self, or of a field of one. The partial holds the receiver as it is when the partial is built, and calls the method on it. A method that takes mut self, an overloaded method and a generic method are error INCAN-T0001.
model User:
name: str
def label(self, prefix: str, suffix: str) -> str:
return prefix + self.name + suffix
class Counter:
pub count: int
def add(mut self, by: int) -> None:
self.count += by
def main() -> None:
user = User(name="ann")
tag = partial user.label(prefix="x") # accepted
mut counter = Counter(count=0)
step = partial counter.add(by=1) # refused: add takes mut self (INCAN-T0001)
Signature¶
A partial has the target's signature with these changes:
- unfilled required parameters remain required;
- unfilled defaulted parameters remain defaulted and take the default the target declares; a call through the partial may leave one unbound exactly when a direct call to the target may (see Ordinary call binding);
- preset parameters become defaulted parameters whose defaults are the preset values, and a call may override a preset by naming it;
- the return type is the target's return type;
- the partial is async exactly when the target is;
- a method partial has the target method's receiver;
- a top-level partial of a generic callable stays generic over the type parameters its presets leave free.
A local partial expression's value is a callable with the target's parameters and return type, each preset parameter defaulted to its preset value. It holds its presets, so a function-typed slot holds it where it holds a closure that captures local values (see Closures that capture local values).
A local partial expression of a generic callable instantiates it: each type parameter takes the type argument the partial writes (partial pair[int](a=1)) or, when it writes none, the one its preset values fix. A type parameter neither fixes is error INCAN-T0001, and a type argument that does not meet its parameter's bounds is refused as it is in a call.
model TableReader:
layer: str
format: str
path: str
model Box[T]:
value: T
label: str
def pair[T](a: T, b: T) -> list[T]:
return [a, b]
def read_orders(layer: str) -> TableReader:
reader = partial TableReader(layer=layer, format="delta") # accepted
return reader("orders")
def instantiate() -> None:
first = partial pair(a=1) # accepted: T is int
labeled = partial Box[str](label="x") # accepted: T is str
unfixed = partial Box(label="x") # refused: INCAN-T0001, T is not fixed
Positional arguments bind as follows:
| Form | Positional arguments bind |
|---|---|
| Top-level declaration and method partial | The target's parameters in declaration order, preset parameters included. |
| Local partial expression | The parameters that are not preset, in declaration order. A preset is overridden only by name. |
def submit() -> str:
a = get(path="/submit") # accepted
b = get(method="POST", path="/submit") # accepted
c = get("POST", "/submit") # accepted
return get("/submit") # refused: INCAN-T0001, path is unbound
def local_call() -> str:
fetch = partial route(method="GET")
a = fetch("/health") # accepted
return fetch("POST", "/health") # refused: INCAN-T0001, one positional parameter
Preset values¶
| Form | Preset values |
|---|---|
| Top-level declaration | The values listed below. The declaration does not call its target when its module initializes. |
| Method partial | Any expression of the parameter's type, evaluated like a parameter default in the module that declares the type: each time a call leaves the preset unbound. |
| Local partial expression | Any expression of the parameter's type, evaluated once, left to right, when the partial expression is evaluated. |
Each preset value of a top-level declaration is one of:
- a scalar literal, including a negative number literal such as
-2, a string or bytes literal, orNone; - a const, named by its identifier or by a qualified path, whose value is itself such a value;
- an enum variant path whose variant takes no payload, such as
Mode.Fast; - a list, set, tuple or dict literal whose elements, keys and values are such values;
- a model literal of a known model whose field values are such values.
Any other preset value of a top-level declaration, such as a function or constructor call, a closure, a comprehension or a spread entry, is error INCAN-T0001:
from std.hash import DEFAULT_CHUNK_SIZE
def scale(k: int, n: int) -> int:
return k * n
twice = partial scale(k=2) # accepted
negative = partial scale(k=-2) # accepted
chunked = partial scale(k=DEFAULT_CHUNK_SIZE) # accepted
computed = partial scale(k=len("ab")) # refused: INCAN-T0001, a call
A pub top-level partial targets a public callable, and its preset values name only public items.
Method and trait partials¶
A method partial is a method of the type that declares it. It calls the target method with the preset values applied:
model User:
name: str
def label(self, prefix: str) -> str:
return prefix
display = label
short = partial display(prefix="name")
def main() -> None:
println(User(name="Ada").short()) # accepted
println(User(name="Ada").short(prefix="other")) # accepted
A method partial declared in a trait is a default method of the trait: every type that adopts the trait has it.
Imports¶
A pub top-level partial is exported from its module and imported like a function. A call of an imported partial binds its arguments against the partial's signature, preset parameters included. In a package other than the partial's, a leftover defaulted parameter follows the target's cross-package default rule, and every preset of a method partial is a required argument (see Ordinary call binding, rule 8).
Refusals¶
A positional preset is syntax error INCAN-P0001. Each of the following is error INCAN-T0001:
- a partial that presets no argument;
- a preset name used twice, or one the target does not declare;
- a preset value whose type does not match the parameter;
- a target that is unknown or not one the form allows (see Targets);
- a partial whose name is already declared in its module or on its type;
- a target with a rest parameter;
- a local partial expression of a generic callable that leaves one of its type parameters unfixed;
- a partial whose target resolves back to itself, directly or through symbol aliases;
- a
pubpartial whose target is private, or whose preset value names a private item; - a top-level preset value that is not one of the values listed under Preset values.