Optionals
Represent absence without turning it into failure
VibeLang's built-in Optional<T> is the success-or-absence counterpart to Result<T, E>. It uses an ordinary generic type and method calls, so the source remains valid TypeScript-shaped syntax.
Return an Optional
function findCached(id: string): Optional<User> {
const user = cache.get(id)
if (user === undefined) return undefined
return user
}Inside an Optional<T>-returning function, the compiler lifts return value to present and return null or return undefined to absent. Returning an existing compatible Optional does not nest it. Optional.some and Optional.none are therefore not part of the authoring API.
Absence is part of the normal value; it does not add an Error to a Result.
Inspect and Transform
const label = findCached(id).match({
some: user => user.displayName,
none: () => "Guest",
})
const email = findCached(id)
.map(user => user.email)
.filter(email => email.includes("@"))The built-in methods are:
isSome(),isNone(),match(...)map(...),andThen(...),filter(...),tap(...)unwrap(),unwrapOr(...)toResult(...),toNullable()Optional.fromNullable(...)andOptional.all(...)
Propagate Absence
Optional.unwrap() is a compiler propagation point inside an Optional-returning function:
function primaryEmail(id: string): Optional<string> {
const user = findCached(id).unwrap()
return user.emails.at(0)
}If either Optional is absent, the enclosing function returns absent. In uncompiled JavaScript, unwrap() throws MissingOptionalValue so missed lowering is visible.
Use unwrapOr when a fallback is enough:
const user = findCached(id).unwrapOr(() => guestUser)Convert Absence to an Error
Use toResult when the caller needs structured recovery information:
function requireUser(id: string): Result<User, NotFound> {
return findCached(id).toResult(() => new NotFound(id))
}An operation can independently be fallible and return an optional value:
declare function findUser(
id: string,
): Result<Optional<User>, DatabaseError>The two layers remain explicit: database failure is in Result; a successful lookup with no row is in Optional.
In a Result<Optional<T>, E> body, the compiler lifts from the outside in: a plain value is success/present, a nullish return is success/absent, and a thrown Error is the Result error.
TypeScript Interoperability
Use Optional.fromNullable(value) to adapt T | null | undefined, and optional.toNullable() when passing a value back to a nullable API. Optional properties and parameters keep their normal TypeScript meaning; VibeLang does not reinterpret property?: T as Optional<T>.
The language adds no ?T, orelse, .?, or payload-capture grammar.