Kalandra

Contributing

Contributing and source setup

A functional language for parallel and distributed programming. The next chapter of Clio.

Prerequisites

Use Bun 1.3.12, matching the repository's pinned development version.

Install and verify

From the repository root:

bash
bun install --frozen-lockfile
bun run check

Create a project

From the Kalandra development repository:

bun run cli new ../my-kalandra-app bun run cli run ../my-kalandra-app/src/main.kalandra --strict bun run cli build ../my-kalandra-app/src/main.kalandra -o ../my-kalandra-app/build --strict

The starter returns [2, 4, 6] using a typed parallel function imported from a second module. It includes a manifest, Bun version pin, README and ignore rules. Creation is offline and does not install packages or initialize Git. Choose a new directory with an existing parent; existing paths are never overwritten.

The development CLI is not yet a published npm installation. From the new project directory, use `bun /absolute/path/to/kalandra.dev/packages/cli/src/index.ts` as the CLI prefix, or the built `dist/cli/index.js` with its sibling packages. The generated README includes run, build, watch and inspection commands. The workspace script `bun run cli` belongs to the toolchain repository, not the generated project.

Preview the website

bash
bun run dev

Inspect the syntax tree

bash
bun run cli --help
bun run cli parse /path/to/source.kalandra

The parse command prints the syntax tree as JSON or reports syntax errors. Use check for single-file type analysis. The compile command emits the supported subset as JavaScript ESM.

Check a source file

bash
bun run cli check /path/to/source.kalandra
bun run cli check /path/to/source.kalandra --strict

The checker reports known type errors. Unresolved names are warnings by default and errors with --strict. External imports without signatures remain unchecked warnings; this command does not analyze dependencies or run your program.

Compile and run the example

bash
bun run cli compile examples/fibonacci.kalandra -o dist/examples/fibonacci.mjs
bun dist/examples/fibonacci.mjs

The generated module prints 89. The compiler warns that console is a host global. It does not execute your source during compilation. Single-file compile emits explicit esm:/cjs: package imports and rejects unresolved local Kalandra imports. Use project build or run for parallel execution; single-file compile does not prepare managed workers. Unsupported forms produce explicit diagnostics and no output.

Build a local project

bash
bun run cli build examples/modules/main.kalandra -o dist/examples/modules
bun dist/examples/modules/main.kalandra.mjs

Build uses the nearest enclosing kalandra.toml and its build.source when present, or the entry file’s directory otherwise. It checks exported types across files and writes JavaScript modules and source maps. It does not run the program. Local modules share range and decorator helpers. Installed JavaScript packages can be imported with esm: or cjs: prefixes. Builds resolve them without executing package code. Installed Kalandra packages under .kalandra/modules are supported, including bare package imports. Module cycles remain unsupported. Remote imports using remote:./contract.json read local generated client contracts; execution needs endpoint bindings through the Bun remote API or run --bindings endpoints.json. Output uses machine-local package paths and is not yet a deployment bundle.

Execute exported functions in parallel

bash
bun run cli build examples/worker-tasks.kalandra -o dist/examples/workers
bun examples/workers.ts dist/examples/workers/worker-tasks.kalandra.mjs

The example runs four Fibonacci tasks through two Bun subprocess workers and closes the pool. The runtime API supports bounded queues, cancellation, deadlines, and failure propagation. Browser workers are available in the playground. Single-instance, typed startup closures are also supported within the documented scope. Experimental authenticated Bun services support remote task calls; arbitrary dynamic function-local targets remain unsupported.

Run a parallel Kalandra program

bun run cli run examples/parallel.kalandra --strict The run command builds temporarily, calls exported main with an argument array, prints its result, and closes the workers. Project builds support |fn| and fn.parallel for module-level functions, including named imports, aliases, re-exports, and immutable namespace members from local Kalandra modules. Explicitly typed data captures are snapshotted for each task. Unannotated captures and external JavaScript dependencies in tasks produce diagnostics. Module-level tasks can schedule children through the same bounded pool. Imported Kalandra helper functions are supported. Array maps preserve callback arguments; direct range maps need conversion to arrays first.

Import a parallel task

bun run cli run examples/parallel-modules/main.kalandra --strict The example imports Fibonacci under an alias and maps it over four inputs. The compiler generates the task companion next to its defining module without replaying that module's initialization in workers. The task function calls a helper imported from another Kalandra module; workers load its extracted definitions without replaying application initialization.

Parallel calls require concrete static parameter, argument, and result types. Use `@params Number` for numeric parameters; the compiler can infer results. Unknown or unsupported serialized types fail at the call with `KAL4202`, even without `--strict`. Arbitrary decorators cannot establish a parallel signature. Compiled workers exchange versioned Sia byte frames using compiler-generated schemas. Number uses eight-byte float64, strings preserve UTF-16, and schema mismatches fail explicitly.

Send typed records to workers

bun run cli run examples/parallel-records/main.kalandra --strict The example sends a declared Point to a worker, doubles its coordinates, and validates the returned Point in the parent. Record fields must have concrete supported types. Nested records, arrays of records, inherited fields, and imported record types retain their identity across the boundary. Plain JavaScript objects and arbitrary classes are rejected.

Typed parallel captures

A module-level parallel function can capture explicitly typed data such as `Number offset = 2`. Captures are snapshotted at each call, checked against their Sia schemas, and reconstructed in a fresh task scope. Private captures in imported helpers work too. `Any`, dynamic initializers, unannotated captures, and directly imported data are rejected.

Run the typed record capture example:

bun run cli run examples/parallel-captures/main.kalandra --strict

The result is `[4, 6, 8]`. Task mutations do not change parent data or later calls.

Nested parallel work

bun run cli run examples/nested-parallel.kalandra --strict The example maps batches to workers, then each batch schedules item tasks. It returns [[2, 4], [6, 8]]. A central scheduler admits every child; when the pool is full, children can execute cooperatively on their submitting worker. Nested work therefore completes with one worker too. Children retain strict Sia schemas and capture snapshots from the calling task. Root deadlines, cancellation, and child failures apply to the entire task tree.

The runtime defaults to a maximum child depth of 32 and 256 outstanding descendants. Large eager nested maps may exceed these limits. Arbitrary function-local parallel targets remain unsupported.

Update array elements

bun run cli run examples/indexed-assignment.kalandra --strict Use items[index] = value to update an element, including nested targets such as matrix[0][1]. This example returns [2, 42]: the worker modifies its snapshot while the parent's original array stays unchanged. Typed element mismatches fail compilation. Brackets retain Clio's property-lookup behavior; a range index does not perform a bulk update.

Try the browser playground

Open the playground

Run a single-file program, inspect compiler diagnostics, and stop long-running work. Parallel calls use the same typed Sia protocol as the Bun runtime. Each run starts in a fresh execution sandbox; imports and network access are unavailable in this preview.

Browse function documentation

bun run cli docs examples/modules/math.kalandra bun run cli docs examples/modules/math.kalandra --json

The docs command lists top-level function declarations, parameter names, source decorators and literal builtin `@describe` text. Add a function name after the file to inspect one declaration. Imports are not loaded and user code is not executed. Computed descriptions are marked unavailable statically. This is source inspection, not type validation; use check or build to validate a program. Nested functions and imported functions are not included.

Highlight source in the terminal

bun run cli highlight examples/modules/math.kalandra bun run cli highlight examples/modules/math.kalandra --color always

Highlight uses the language lexer and leaves whitespace, comments, Unicode and line endings intact. It colors terminal output automatically and uses plain source when piped. Use `--color always` to force ANSI colors or `--color never` to disable them. Auto mode respects a nonempty `NO_COLOR` and `TERM=dumb`. The command expects UTF-8 and reports lexer errors without partial output; it does not execute or type-check the program.

Editor support

The Kalandra language server provides diagnostics, completion, type hover, go-to-definition, references and rename. Configure your editor's LSP client with the absolute path to Bun as its command and the absolute path to packages/language-server/src/stdio.ts in the toolchain checkout as its argument. Associate the kalandra filetype with .kalandra files. The source server requires installed workspace dependencies.

After building packages, use dist/language-server/stdio.js instead. Editor configuration is manual; there is no published editor extension in this preview. Analysis reads source without running your program or imported packages.