Skip to content
You are reading v0.1, which is not the current release. Go to v0.4.

std::env

What a program was told: its arguments and its environment.

The smallest thing that separates a program from a demo. Until this existed, nothing a Khora program did could depend on anything outside its own source — every path, every port, every setting was compiled in.

Clock used to live here and now does not. The two were together because both answer “what did the outside world hand this process”, and that grouping cost something: this file is native-only for getenv and argv, so the clock was native-only too, for a reason that had nothing to do with clocks. std::clock has it, and says why.

The C side is almost all ISO C: getenv, strlen, memcpy. The one exception is the argument vector, which no C function returns — it arrives through main and is gone, so the generated main hands it to the runtime and khora_arg gives it back.

Types: EnvError

Effects: Env

Methods: Env

Functions: variable_or

derive(Show, Eq)
pub type EnvError = | Denied(name: String);

Why reading the environment did not work.

One case, because there is one way for it to fail that is not “no such variable”: the manifest did not grant it. Not being set is None, which is an answer rather than a failure.

pub effect Env {
variable: (String) -> Option<String> raises EnvError,
arguments: () -> List<String>,
}

What the process was started with.

A capability rather than plain functions, for the reason every other one is: a function that reads DATABASE_URL says so in its signature, and a test can hand it something else. Reading the environment is exactly the kind of hidden input that makes a program hard to test, and this is the seam.

variable: (String) -> Option raises EnvError

The value of a variable, or None when it is not set.

raises because a denial is not None. A variable the manifest does not grant is a different thing from one nobody set, and the fix is a line in khora.toml rather than a line in a deployment script. Answering None for both would send a reader to look at their environment for a decision their own manifest made – the same reasoning IoError::Denied records.

arguments: () -> List

Everything the process was invoked with, the program’s own name first — the same convention C, Rust and Go all follow.

impl Env
pub fn real() -> Env

The real environment.

pub fn variable_or(name: String, fallback: String) -> String with { env: Env } raises EnvError

A variable, or a default when it is not set.

The shape almost every caller wants, written once here rather than as a match at each of them.

The fallback is for “not set”, not for “not allowed”. A denial passes through rather than quietly becoming the default: a program told it may not read DATABASE_URL and silently given localhost is a program that starts and does the wrong thing, which is worse than one that stops and says why.

Khora 0.1.0built frombd964738afb6on 2026-10-17 20:41ZVersioningSecurityContributingReleasesSource