Function Channels
Reference for values, errors, and requirements
Every VibeLang function is analyzed across three conceptual channels, but all runtime values use ordinary types:
| Parameter | Meaning | Runtime representation |
|---|---|---|
A | success value | the success variant of Result<A, E> |
E | expected errors | the error variant of Result<A, E> |
R | required capabilities | compiler-tracked context, provided by Layers |
For an infallible function, the return type remains A. For a fallible function it is Result<A, E>; for a fallible async function it is Promise<Result<A, E>>.
Example
function getUser(
id: string,
): Result<User, DatabaseError | NotFound> {
const db = Database.context()
const log = Logger.context()
const row = db.find(id).unwrap()
if (row === null) throw new NotFound(id)
log.info(`user:${id}`)
return User.from(row)
}The compiler sees:
A = User
E = DatabaseError | NotFound
R = Database | LoggerComposition
| Operation | Effect on E | Effect on R |
|---|---|---|
| return a Result | union returned errors | union called requirements |
.unwrap() | propagate the Result error | unchanged |
Result.match / recover | remove or transform handled errors | unchanged |
throw ErrorSubclass | add that Error type | unchanged |
Layer.provide | include layer initialization errors | remove provided capabilities; add layer requirements |
await | unwrap Promise only; leave Result | unchanged |
Duplicate Error members collapse in unions.
Public Signatures
export declare function boundary(): Result<A, E>
export declare function asyncBoundary(): Promise<Result<A, E>>These are ordinary generic return types, not failure annotations. Context requirements are inferred from Capability.context() and retained in VibeLang analysis metadata. The declaration-file representation for R remains compiler-owned.
Inference and Lifting
An unannotated implementation may infer both A and E from its body. Once a function is fallible, plain returns and throws are lowered into Result variants. Returning an existing compatible Result does not produce Result<Result<A, E>, E>.
No marker opts a function into inference. Public API authors should spell Result<A, E> explicitly for stability.
TypeScript Boundaries
An imported TypeScript function that might throw is adapted to a Result at its declared VibeLang boundary. Unknown exceptions become UnhandledException until an adapter maps them to a domain Error. Runtime TypeScript use also adds the built-in TypeScript requirement; type-only imports do not.
Async Boundary
VibeLang does not add an error generic to Promise. It wraps an ordinary Result:
Promise<Result<A, E>>Authored VibeLang uses only await for Promise consumption. The compiler rejects .then, .catch, and .finally calls.