A programming language built from first principles.
Ostrin is an experimental general-purpose programming language focused on readability, physically meaningful types and safe-by-default concurrency. The project is currently a design-validation compiler and interpreter written in Rust.
GitHub currently reports Rust in its language bar because the compiler and
interpreter implementation live in compiler/src/*.rs. That is the
implementation of Ostrin, not a claim that Rust and Ostrin are the same
language. The actual Ostrin source files are the .ostrin programs in
examples/ and the validation cases in tests/.
| Path | Role |
|---|---|
examples/*.ostrin |
Programs written in Ostrin |
tests/**/*.ostrin |
Positive and negative Ostrin test programs |
compiler/src/*.rs |
Ostrin compiler, checker and interpreter implementation in Rust |
vscode-ostrin/ |
VS Code tooling for the Ostrin language |
GitHub Linguist does not yet know Ostrin as an official language, so the
language bar cannot display it as a stable category yet. The roadmap now includes
the upstream submission: representative .ostrin samples, a language definition,
local Linguist validation, and repository classification after acceptance. The
draft entry and upstream checklist live in docs/linguist.md,
with the machine-readable proposal in docs/linguist-language.yml
and the source-backed sample inventory in docs/linguist-samples.yml.
Run node scripts/linguist-check.mjs to validate the proposal, TextMate scope,
license and representative samples before opening an upstream request.
- Physical quantities as types.
5 m / 2 scarries its dimension through the type system, and incompatible arithmetic is rejected before execution. - Immutable by default. Mutable state is explicit and cannot be captured directly by a concurrent task.
- Readable control flow. Expressions, pattern matching, explicit
try,and/or/not, and significant newlines keep intent visible. - Extensible types. Records, enums, generics, nominal traits, defaults and applied implementations form the foundation for reusable libraries.
Ostrin is not yet a production compiler. The current implementation includes a lexer, parser, static checker, interpreter, modules, packages, collections, traits, pattern matching, quantities and two concurrency modes: deterministic cooperative scheduling by default, plus opt-in native threads for compiled programs.
The compiler suite currently passes 428 integration tests, 33 unit tests and 6 differential
interpreter↔native tests. Reproduction commands and evidence boundaries are documented in
README-reproduce.md. Function calls
support named/default arguments, scalar and String collection lookups preserve Option<T>
through the native IR path; concrete records and simple Option<Record> values
now use the same IR path with ownership markers, and record fields are checked
statically. String.to_int() and to_float() now also lower through the IR as
scalar Result values, including Ok/Err matching, core queries, try propagation and
inline try catch handlers and map/map_err/then combinators; scalar and String
Option.map/then use the same IR path.
The CLI also exposes JSON Lines
diagnostics with source locations for editor integrations, plus a compiler
index of type members, local bindings and inferred expression types for editor
tooling. A persistent language server (--lsp) resolves a document's real
import graph across unsaved buffers and serves hover, completion, references,
rename, signature help and semantic tokens over the protocol; a debug adapter
(--dap) gives real breakpoints, stepping, a call stack and variable
inspection on top of the same interpreter. A native backend (--emit-c/
--compile) transpiles a real subset of the language to C and compiles it to
a native executable: plain functions — including generic ones, monomorphized
per concrete instantiation the way C++/Rust templates are, with a fresh C
function generated the first time a given (function, concrete types) pair is
called and reused after that — plain records (heap-allocated, always by
reference, to match the interpreter's identity semantics) with their
non-generic impl methods (resolved statically at compile time), plain
non-generic enums with match (compiled to a tagged union and a sequence of
ifs), direct dyn Trait values (typed data + vtable HIR lowering with
retain/release hooks and runtime vtable dispatch; heterogeneous List<dyn Trait>
and indirect fold now use HIR, while generic record boxing and closure/task
captures still use explicit AST fallbacks), and
List<T> (heap-allocated, by reference, monomorphized per element type the
same way a generic function is — length/push/remove_at, indexing and
for x in list) — over Int/Float/Bool/String, recursion,
if/while/for <range>. Lambdas are supported as inline arguments of
List's map/filter/fold/any/all (expanded to loops, so captures
need no closure object); the project's own dyn_trait.ostrin compiles and
runs natively, as do Option<T> and Result<T, E> (Some/None/Ok/Err,
match, try, find). Dimensional Quantity compiles too (dimension
checked statically, unit carried at runtime exactly as in the interpreter).
Methods (including generic ones and trait defaults) work on records, enums and
quantities; generic records/enums, Map/Set, operators and derive, named
and default arguments, custom iterators, Option/Result combinators, the
built-in file/parse functions and synchronous spawn/channels all compile too.
The default native scheduler remains deterministic for differential testing;
--native-threads enables OS threads, blocking channels and deterministic-priority
select([channels]); yield() advances the cooperative scheduler, and
Task.cancel() cancels pending tasks immediately and requests cancellation for running
tasks at safe checkpoints; native-thread file I/O waits through a cancelable worker request,
while the cooperative/WASI runtime remains synchronous. yield() is the explicit native
checkpoint, and cancellation never forcibly aborts a libc call.
The standard library is still intentionally small, but now includes embedded Ostrin modules
for math, collections, strings, deterministic dates, portable JSON parsing/serialization,
program arguments, process/environment helpers, generic map queries and configurable float formatting.
The compiler itself also has a reproducible wasm32-wasip1 release workflow with a pinned
WASI C toolchain, checksums, and smoke tests for standalone and path-dependent programs,
program arguments/environment, file I/O and managed ownership. Emitted programs use cooperative
task cancellation through WebAssembly exception handling, so their WASI host must support that
proposal. The
native release workflow targets Linux x86_64, macOS arm64 and Windows x64; before upload it checks
the tag/version contract, runs ostrinc --version, executes examples/hello.ostrin, verifies the
archive checksum, and runs both the extracted example and the packaged path-dependency project.
Ostrin 0.2.0 is published as an experimental developer release for Linux x86_64, macOS ARM64,
Windows x64 and WASI Preview 1, with SHA-256 verified archives (release notes,
GitHub release). The installers resolve
this version by default and verify the archive checksum before installation. The public package registry
and additional distribution channels (Homebrew, winget, Scoop, Chocolatey, AUR) remain future
work.
The cooperative runtime avoids thread-only headers unless --native-threads is requested. The
same compiler is also deployed as ostrinc.wasm for the browser playground, where it runs the
interpreter locally through an in-memory WASI directory. Native C compilation remains a desktop/
WASI toolchain feature rather than a browser capability. Set OSTRIN_CFLAGS to pass additional
compiler or linker flags to generated native programs, for example when running sanitizer builds.
Requirements: Rust and Cargo.
cd compiler
cargo test
cargo run -- --run ..\examples\physics.ostrinThe compiler includes a deterministic formatter and a small test runner for functions named
test_*:
cargo run -- --fmt --check ..\examples\testing.ostrin
cargo run -- --test ..\examples\testing.ostrinUse --fmt --write to rewrite a file in place. The same commands are available in the browser
playground and in the VS Code extension; see the public workflow guide.
Release archives are built for Linux x86_64, macOS arm64 and Windows x64 by
.github/workflows/release.yml. The installers download the matching release archive and verify
its published SHA-256 before installing ostrinc.
Unix (Linux x86_64 or macOS arm64):
curl --fail --location https://raw.githubusercontent.com/sircalch/Ostrin/main/scripts/install.sh \
--output /tmp/ostrinc-install.sh
sh /tmp/ostrinc-install.sh --version 0.2.0Windows PowerShell:
$installer = Join-Path $env:TEMP 'ostrinc-install.ps1'
Invoke-WebRequest -UseBasicParsing https://raw.githubusercontent.com/sircalch/Ostrin/main/scripts/install.ps1 -OutFile $installer
powershell -ExecutionPolicy Bypass -File $installer -Version 0.2.0 -AddToPathUse --install-dir on Unix or -InstallDir on Windows to choose another destination. The
scripts are also usable with OSTRIN_REPOSITORY/-Repository for a compatible fork.
The compiler currently supports:
ostrinc file.ostrin # type-check
ostrinc --check file.ostrin # explicit type-check
ostrinc --json --check file.ostrin # diagnostics for tools and editors
ostrinc --symbols --json file.ostrin # symbols/signatures for editors
ostrinc --members --json file.ostrin # type members/bindings for editors
ostrinc --types --json file.ostrin # inferred expression types for editors
ostrinc --stdin --check --json --file file.ostrin # check unsaved editor text
ostrinc --lsp # language server over stdio
ostrinc --dap # debug adapter over stdio
ostrinc --run file.ostrin # type-check and run
ostrinc --ast file.ostrin # print the AST
ostrinc --tokens file.ostrin # print lexer tokens
ostrinc --emit-c file.ostrin # transpile a supported subset to C
ostrinc --compile file.ostrin # transpile and compile to a native executable
ostrinc --compile --native-threads file.ostrin # compile with OS threads and blocking channels
ostrinc --run --project path/to/project # use the entry declared by ostrin.toml
ostrinc --fetch --run --project path/to/project # explicitly fetch Git dependencies
ostrinc --locked --run --project path/to/project # require the existing lockfile/cache
ostrinc --effect-report file.ostrin # experimental typed effect inference
ostrinc --require-closed-effects file.ostrin # fail on unresolved/open effect boundaries
ostrinc --provenance-report --json file.ostrin # source hash, target and replay limits
--provenance-report emits the experimental ostrin.provenance/v0 artifact used by the
public provenance page. It records a normalized
source hash, compiler target and known effect sites. Inputs, output hashes, lockfiles and runtime
snapshots are still required before Ostrin can claim static purity or reproducibility levels R2/R3.
The first editor integration is in vscode-ostrin/. It
recognizes .ostrin files, provides syntax highlighting, uses the official
logo, exposes commands to check or run the current file with ostrinc, and
shows compiler diagnostics directly in the Problems panel. It also provides
syntax-aware completion, type-aware member completion, signature help, live
diagnostics, hover documentation, definition navigation, reference search,
scoped rename, precise inferred expression hover, document formatting, persistent semantic indexing and an outline for
top-level declarations. Enable
ostrin.checkOnSave to check automatically after saving.
The persistent stdio LSP backend resolves a document's real import graph
(including unsaved buffers and ostrin.toml dependencies) and serves hover,
completion, definition, signature help, references, rename and semantic
tokens natively; the extension's own compiler-backed providers only run as a
fallback when the server isn't available. A debug adapter (ostrin debug
type) launches ostrinc --dap for real breakpoints, stepping, a call stack
and variable inspection.
To install the current extension locally, build the compiler and package the extension:
cd compiler
cargo build
cd ..\vscode-ostrin
npx --yes @vscode/vsce package
code --install-extension .\ostrin-language-support-0.4.0.vsixOnce installed, VS Code detects .ostrin files automatically. The extension
will use compiler/target/debug/ostrinc.exe from this repository when it is
available, so a global compiler installation is not required during
development.
The design is documented in docs/design/, including:
- variables, types and quantities;
- functions, closures and generics;
- traits and operator design;
- errors,
OptionandResult; - enums and exhaustive matching;
- ranges and iterators;
- modules and visibility;
- concurrency;
- memory model;
- derive and dynamic traits;
- packages and the consolidated language reference;
- experimental
Measurement<T>uncertainty propagation, including bounded dense covariance for dimensionless scalar sources; dimensional or array covariance remains unsupported.
The project website is published at sircalch.github.io/Ostrin when GitHub Pages is enabled.
- Make typed HIR/IR the single native lowering path and retire the AST fallback.
- Complete ownership and last-use lowering for aggregates and escapes.
- Grow the scientific core: numeric hierarchy, linear algebra, units and dataframes.
- Grow the standard library; networking and a package registry come later.
- Publish the VS Code extension and additional distribution channels.
Completed milestones include the experimental v0.1.0 release, the LSP/DAP tooling, reproducible lockfiles, native threads with
structured cancellation, the WASI build and the browser playground.
See CONTEXTO_PROYECTO.md for the complete project
history and current implementation notes.
Ostrin is released under the MIT License.
