Single-callable wrapper schemas with stored callable context and one declared call signature.
Use
"Function" use exposes the module's public names. Name-specific imports such as "Function.Function" use, "Function.Function2" use, or "Function.makeFunction" use expose only selected names.
Dispatch keys
Construction forms
Function2constructs an emptyFunctionobject with explicit callable-context storage size and one declared call signature.Functionconstructs the same kind of emptyFunctionobject with 32 bytes of callable-context storage.makeFunctionconstructs oneFunctionobject and stores one callable in it in a single step.
Function2
Function2
(signature dataSize -- function) Constructs an empty Function object with dataSize bytes of embedded callable storage.signatureis the three-part descriptor (inputs output options) used to form acodeRefsignature, not aCodereference. The input and option descriptors followcodeRef's rules.dataSizeis a knownInt32of at least 8; smaller sizes fail compilation withThe [Function] data size is less than 8 bytes.- The result is an initialized, managed, non-Meta object.
DATA_SIZEcounts embedded callable bytes, not the vtable or whole-object padding. Callable storage starts at 8-byte alignment.
Fields
SCHEMA_NAME: StaticTextvalue"Function".DATA_SIZE: StaticInt32byte capacity of the embedded callable storage.Signature: Static descriptor of the public call signature.data:Nat64providing the first eight bytes of callable storage.pad: EmbeddedNat8storage of lengthDATA_SIZE - 8.vtable:Codereference taking anInt32operation key and returningNatx. Keys 0–3 return operation addresses; key 4 returns 0 for empty dispatch and 1 for installed dispatch.ASSIGN_CODE: Static Code-reference signature for copying context:(otherAddress thisAddress --).CALL_CODE: Static Code-reference signature matchingSignaturewith aNatxcontext address added on top of the inputs.DIE_CODE: Static Code-reference signature(thisAddress --)for context destruction.INIT_CODE: Static Code-reference signature(thisAddress --)for context initialization.- Both addresses in
ASSIGN_CODEandthisAddressinDIE_CODEandINIT_CODEareNatx. These signature fields areNILCode-reference descriptors, not callable operation addresses.
Methods
assign
(callable --) Stores one callable in the wrapper.- A callable matching
Signatureis required. A sized runtime callable is stored in the wrapper: an immutable source is copied, and a mutable source is moved. - A sized callable context must fit
DATA_SIZE; an oversized context fails compilation withThe object is too large to be encapsulated in a [Function]. The callable must also matchSignature's input and output schemas. - Reference fields remain borrowed. A
Codereference is retained independently of later rebinding of the sourceCodevariable. - For runtime storage, use a callable
Dictwith explicit fields; stored reference fields remain borrowed. - A Function of the same wrapper schema uses the assignment rules above; a different Function schema is encapsulated as a callable context and must fit
DATA_SIZE. - A callable that cannot be copied may still be moved into the wrapper. Copying such an installed context reports
Non-assignable callableand terminates the process.
- The input and output stacks are specified by
Signature. Push the first declared input last, so it is on top. A void output produces no item; a reference output returns the declared reference. - Calling an empty wrapper reports
Invalid function calledand terminates the process. The hidden context address is not a caller argument. - Output values and references follow
Signature. A reference into stored callable state remains valid only while that state stays alive at the same address; replacement, release, movement, or destruction can invalidate it. - References to external objects retain those objects' lifetime requirements; storing a reference does not keep its target alive.
- Calling through an immutable Function view can still mutate the stored callable and return mutable references. An installed
Codereference must be non-NILand valid;hasContextdoes not validate it.
hasContext
(-- cond) Returns Cond indicating whether the wrapper has an installed callable dispatch.release
(--) Destroys the stored callable and resets the wrapper.Example: explicit context size
"Function.Function2" use
"control" use
{} () {} [
({value: Int32;} () {}) 48 Function2 .DATA_SIZE printStack _:;
] "main" exportFunction
Expected Output During Compilation
48
Runtime example: call through one explicit-size wrapper
"Function.Function2" use
"String" use
"control" use
{} Int32 {} [
code: {value1: Int64; value0: Int32;} Real32 {} codeRef;
[swap drop Int32 cast 5 + Real32 cast] !code
function: ({value1: Int64; value0: Int32;} Real32 {}) 48 Function2;
@code @function.assign
("has=" @function.hasContext LF
"call=" 7 11i64 function 16.0r32 = LF) printList
0
] "main" exportFunction
Expected Output
has=TRUE
call=TRUE
Stored state and call validity
- Initialization creates an empty wrapper. Automatic destruction destroys its stored callable; referenced external objects remain the caller's responsibility.
releasedestroys the stored callable and restores the empty state without ending the wrapper's lifetime.INIT,DIE, andASSIGNare reserved lifecycle hooks, not ordinary public operations.- Direct
DIEis notrelease: it does not changehasContext; directINITrestores the empty state. - Ordinary assignment requires the same Function schema, including
SignatureandDATA_SIZE. An immutable source is copied; a mutable source is moved and becomes empty. These rules also apply toassignwhen its source has that same schema.ASSIGNis the reserved copy hook, not the move operation. CALLis invalid while the wrapper has no stored callable context.
Known issue: Lifetime hooks on Meta callable objects can run extra times during assignment, invocation, and release with the current compiler. Avoid side-effecting lifetime hooks on Meta callables here; use a callable with runtime storage instead.
For a Meta callable, diagnostic-only INIT and DIE fields are enough to expose the extra calls when the callable is assigned to a Function, invoked, and released.
c: {
CALL: [7];
INIT: ["meta-init\n" print];
DIE: ["meta-die\n" print];
};
f: ({} Int32 {}) Function;
@c @f.assign
f
@f.release
Function
Function
(signature -- function) Constructs an empty Function object with 32 bytes of embedded callable storage.- Function has the same fields and operations as Function2, with that default size.
- The result is an initialized, managed, non-Meta object.
Lifecycle and call result
"Function.Function" use
"Function.makeFunction" use
"String" use
"control" use
{} Int32 {} [
code: {value1: Int64; value0: Int32;} Real32 {} codeRef;
[swap drop Int32 cast 11 + Real32 cast] !code
function: ({value1: Int64; value0: Int32;} Real32 {}) Function;
("has0=" @function.hasContext LF) printList
@code @function.assign
("has1=" @function.hasContext LF
"call1=" 17 19i64 function 30.0r32 = LF) printList
@function.release
("has2=" @function.hasContext LF) printList
function2: @code ({value1: Int64; value0: Int32;} Real32 {}) makeFunction;
("has3=" @function2.hasContext LF
"call2=" 23 29i64 function2 40.0r32 = LF) printList
0
] "main" exportFunction
Expected Output
has0=FALSE
has1=TRUE
call1=TRUE
has2=FALSE
has3=TRUE
call2=TRUE
Copy from another wrapper
"Function.Function" use
"String" use
"control" use
{} Int32 {} [
function0: ({value1: Int64; value0: Int32;} Real32 {}) Function;
function1: ({value1: Int64; value0: Int32;} Real32 {}) Function;
code0: {value1: Int64; value0: Int32;} Real32 {} codeRef;
[swap drop Int32 cast 11 + Real32 cast] !code0
@code0 @function0.assign
code1: {value1: Int64; value0: Int32;} Real32 {} codeRef;
[swap drop Int32 cast 13 + Real32 cast] !code1
@code1 @function1.assign
@function0 const @function1 set
("call0=" 17 19i64 function0 30.0r32 = LF
"call1=" 23 29i64 function1 40.0r32 = LF
"has0=" @function0.hasContext LF
"has1=" @function1.hasContext LF) printList
0
] "main" exportFunction
Expected Output
call0=TRUE
call1=TRUE
has0=TRUE
has1=TRUE
makeFunction
makeFunction
(callable signature -- function) Constructs and initializes one Function object.- Uses Function's 32-byte capacity and the same input, storage, and copy/move rules as assign.
See also
- interface: Interface-wrapper construction and implementation helpers.