A modern, function-first programming language built on Pascal's readable syntax. Compiles .fpas source files to bytecode and runs them on a managed virtual machine.
⚠️ Disclaimer: This is a small hobby project, entirely vibe-coded. It started as an experiment in learning how to effectively communicate and collaborate with LLMs. The future is uncertain — no idea where this will end up, or if it will.
- Function-first — Functions are the primary building block. No classical classes.
- Immutable by default — All bindings are immutable unless declared with
mutable var. - Pattern matching — Exhaustive
casestatements with enum,Result, andOptiondestructuring. - First-class functions — Pass named functions as values, store them in variables, and use them with higher-order APIs.
- Error handling — Built-in
Result of T, EandOption of Ttypes with atryoperator for propagation. - Concurrency —
gotasks, typed bounded channels, cooperative cancellation, mixed-sourceSelect, task groups, and supervised retries. Std.Task includes timed group close; timeout retains unfinished work rather than forcibly terminating it. - Standard library — Built-in
Std.*units for console I/O, TUI, strings, math, arrays, tasks, and more. - Server lifetime — Std.Server owns worker groups and listeners, handles stop signals, and supports explicitly authorized process escalation after a common grace period.
- Editor support — A repository-owned VS Code-compatible extension provides diagnostics, formatting, navigation, completion, project workflows, integrated tests, and source debugging.
- Safe by design — The VM manages memory. No pointers, no manual allocation, no unsafe operations.
- Case-insensitive — Keywords and identifiers are case-insensitive, following Pascal tradition.
- Explicit types — Every variable and parameter declares its type.
git clone https://github.com/tobiasbick/functional-pascal.git
cd functional-pascal
cargo build --releaseThe compiler is at target/release/fpas (or fpas.exe on Windows). Keep the
adjacent target/release/lib/ source standard library and
target/release/fpas-runner (or fpas-runner.exe) with it. The runner is used
by fpas build --executable; generated applications themselves are standalone.
Run the compiler directly or add the whole target/release directory to your
PATH.
To prepare the distributable layout under bin/, run ./dist.sh on Linux or
./dist.ps1 on Windows. Both scripts copy fpas, fpas-runner, fpas-lsp,
and lib/ together.
Both scripts resolve paths from their own directory and stop on build,
standard-library staging, or copy failures. They report success only after all
steps finish.
Alternatively, run without installing:
cargo run -p fpas-cli -- run examples/hello.fpasCreate hello.fpas:
program Hello;
uses Std.Console;
begin
WriteLn('Hello, World!')
end.Run it:
fpas run hello.fpas.fpas sources under examples/, tests/, and apps/ follow the official formatter style (docs/pascal/tools/fmt-style.md). Format in place:
scripts/format-fpas-sources.sh # Unix
scripts/format-fpas-sources.ps1 # Windows
# or: cargo run -p fpas-cli -- fmt examples tests appsCheck without writing:
cargo run -p fpas-cli -- fmt --check examples tests appsRun fpas fmt manually for command-line workflows. The repository's
VS Code-compatible editor integration
also provides diagnostics, Format Document, document symbols, hover,
definition, references, rename, and basic completion. Its bounded project catalog follows
manifest dependencies and refreshes navigation after watched source or manifest changes. It
works with the editor's standard format-on-save setting; no FPAS watch mode is required.
With Node.js 22 or newer and a stable Rust toolchain installed, build the local toolchain-independent VSIX from the repository root:
npm ci --prefix editors/vscode
npm run package --prefix editors/vscodeThe result is editors/vscode/dist/functional-pascal-<version>.vsix. Install
it in VS Code, Cursor, VSCodium, or another compatible desktop editor through
Extensions: Install from VSIX. Install the FPAS toolchain separately and
put fpas on PATH, or select it through the extension's
functionalPascal.executablePath setting. The same selected toolchain supplies
the compiler, language server, debugger, and standard library.
Local Chat is a small Std.Tui client for the
fixed local OpenAI-compatible llama.cpp endpoint.
fpas run apps/local-chat/local-chat.fpasprjNotes is a complete modern Std.Tui note-taking
application with local human-readable .note files, responsive layouts,
keyboard and mouse control, a command palette, and headless workflow tests.
fpas run apps/notes/notes.fpasprj -- ./my-notesSee apps/ for complete applications. Focused language and
standard-library demonstrations remain under examples/.
program Fibonacci;
uses Std.Console;
function Fib(N: integer): integer;
begin
if N <= 1 then
return N
else
return Fib(N - 1) + Fib(N - 2)
end;
begin
WriteLn('Fibonacci sequence:');
for I: integer := 0 to 9 do
WriteLn(Fib(I))
end.program PatternMatching;
uses Std.Console;
type
Light = enum
Red;
Yellow;
Green;
end;
function TrafficAdvice(L: Light): string;
begin
case L of
Light.Red: return 'Stop';
Light.Yellow: return 'Caution';
Light.Green: return 'Go'
end
end;
begin
WriteLn(TrafficAdvice(Light.Red))
end.program HigherOrderFunctions;
uses Std.Console;
function Double(X: integer): integer;
begin
return X * 2
end;
function Apply(F: function(X: integer): integer; Value: integer): integer;
begin
return F(Value)
end;
begin
var Op: function(X: integer): integer := Double;
WriteLn(Apply(Op, 10)) // 20
end.program OptionExample;
uses Std.Console, Std.Arrays;
function FindFirst(Items: array of integer; Min: integer): Option of integer;
begin
for I: integer := 0 to Length(Items) - 1 do
if Items[I] >= Min then
return Some(Items[I]);
return None
end;
begin
case FindFirst([3, 7, 15, 42], 10) of
Some(V): WriteLn('Found: ', V);
None: WriteLn('Not found')
end
end.More examples in the examples/ directory.
The canonical interactive Std.Tui example renders complete Mandelbrot images
from a cancellable subscription using the VM worker pool. Navigation replaces the active
generation without blocking terminal input, and only the serialized TUI host
updates the model and paints frames.
fpas run examples/math/mandelbrot/mandelbrot.fpasprjSee the Mandelbrot example for controls and its background-work structure.
Author-facing tests are *_test.fpas programs under tests/ (stdlib/, including stdlib/tui/, concurrency/, runner/, console/, and apps/). Run the full suite with fpas test tests/ or fpas test tests/suite.fpasprj. See docs/pascal/std/testing/test.md and examples/README.md.
The reproducible Functional Pascal fine-tuning dataset lives under
training/fpas/. It is generated from implemented docs,
examples, applications, and regression tests and uses Hugging Face's
conversational JSONL format. Build and validate it locally with:
python training/fpas/generate_dataset.py
python training/fpas/validate_dataset.pyThe generated files can be selected in Unsloth Studio for local LoRA/QLoRA training. Keep the held-out test split out of training and validate generated FPAS with the compiler and test runner afterward.
Larger programs use a .fpasprj project file. Each imported unit is built independently into a source-adjacent .fpascu sidecar and linked into the final program automatically. Sources and manifests remain authoritative; sidecars are derived, Git-ignored build outputs. Reference library projects from [dependencies].projects (paths) or [dependencies].workspace (member project.name inside a .fpasworkspace). Libraries may hide internal units from dependents with [exports].units in the library .fpasprj. See Projects, library-deps, and monorepo.
fpas init project my-app
fpas init library my-lib --unit MyLib
fpas init workspace my-suite
fpas run my-app/my-app.fpasprj
fpas check my-lib/my-lib.fpasprj
fpas check my-suite/my-suite.fpasworkspace # check every workspace member
cd my-suite && fpas check # discover .fpasworkspace in cwd
cd my-suite && fpas run # run the sole program memberThe full language specification lives in docs/pascal/. Start with the documentation hub for area navigation and the learning path.
| Area | Hub |
|---|---|
| Getting started | getting-started/ |
| Language | language/ |
| Program structure | program-structure/ |
| Standard library | std/ — themed subdirs (host/, text/str/, console/, tui/, network/, …) |
| Tools | tools/ — formatter and editor integration |
| Formal grammar | grammar.ebnf |
Ordered learning path:
- Overview
- Basics
- Control Flow
- Functions
- Types
- Pattern Matching
- Error Handling
- Concurrency
- Units
- Projects
- CLI
- Standard Library
- Formatter style
- Editor integration
Roadmaps, implementation progress, and deferred work: docs/future/.
See CONTRIBUTING.md. Short pointers:
- Language spec:
docs/pascal/(hub) — source of truth for implemented behavior - Agents:
AGENTS.mdand skills under.agents/skills/ - Examples:
examples/README.md - FPAS tests:
tests/anddocs/pascal/std/testing/test.md - Verify locally:
cargo fmt,cargo build,cargo test --workspace, andfpas fmt --checkon touched.fpaspaths when relevant
| Component | Purpose |
|---|---|
fpas-cli |
Command-line interface (fpas binary) |
fpas-lexer |
Tokenizer / lexical analysis |
fpas-parser |
Parser producing the AST |
fpas-project |
Project/workspace loading and unit-graph resolution |
fpas-build |
Incremental compiled-unit build engine |
fpas-sema |
Semantic analysis and type checking |
fpas-ir |
Typed control-flow intermediate representation |
fpas-compiler |
AST lowering through typed IR to register bytecode |
fpas-bytecode |
Register-bytecode definitions and executable verification |
fpas-unit |
Compiled-unit identities, format, and sidecar lifecycle |
fpas-linker |
Deterministic linker from unit objects to verified executables |
fpas-program |
Persistent executable .fpascp program images |
fpas-bundle |
Host-native runner bundle format and publication |
fpas-vm |
Virtual machine / bytecode interpreter |
fpas-std |
Standard library intrinsics |
fpas-fmt |
Canonical FPAS source formatter |
fpas-diagnostics |
Error codes and diagnostic utilities |
fpas-language-service |
Compiler-backed editor analysis and language features |
fpas-lsp |
Language Server Protocol transport |
fpas-debug |
Source debug engine with JSONL and DAP adapters |
fpas-bench |
Bounded performance harness, baselines, and comparisons |
editors/vscode |
VS Code-compatible extension, packaging, and Extension Host tests |
v0.0.1 — Experimental. The language specification and compiler are under active development. Expect breaking changes.
BSD-3-Clause © 2026 Tobias Bick
0 comments
log in to comment.