Tiny Language: A Concurrent Bytecode VM with Inline Go Extensions
Tiny is a high-performance, concurrent programming language and runtime system built with Go. It provides a hybrid execution model that combines the development speed of a dynamic language with the performance of a multi-threaded runtime, allowing developers to embed native Go functions directly into their source code via WebAssembly.
Multi-Tiered Execution and JIT Compilation
Tiny utilizes a multi-tiered execution model to balance flexibility and performance. Source files are compiled into compact, stack-based bytecode instructions (.tbc) that run on a virtual machine using slot-based local storage.
Just-In-Time (JIT) Engine
The runtime includes a JIT compiler that translates "hot" bytecode paths into native WebAssembly for increased execution speed. Key optimizations include:
- Region Outlining: The compiler automatically identifies hot loops in top-level code and function bodies, outlining them into specialized JIT regions to ensure scripts run at native speed without requiring manual function encapsulation.
- Packed Object Arrays: For arrays containing objects of uniform shape, the JIT uses host-memory mirroring and field-column pointer tables. This allows the VM to access object properties directly in linear memory, bypassing the overhead of VM-to-Native interop. These arrays support dynamic growth and Wasm-side optimization.
- JIT-Safe Patterns: To maximize performance, the JIT favors synchronous functions without closures that capture mutable outer variables. Explicit type hints (e.g.,
: number) are recommended to help the JIT generate specialized machine code.
Language Specifications and Syntax
Tiny is dynamically typed by default but supports optional static type hints for variables, parameters, and return types, including support for unions and generics.
Structural Typing and Composition
Tiny employs structural typing (shape-based validation), where objects are validated against interfaces at runtime. The JIT engine optimizes these checks by tracking object shapes and using linear memory field offsets.
Instead of deep inheritance, Tiny emphasizes class composition using the embed keyword. This allows a class to delegate behavior to another class instance; if a method or field is missing on the parent, the runtime automatically resolves it from the embedded instance.
Advanced Control Flow
- Pattern Matching: The
matchblock supports literal values, variables, enums, union patterns, and guards, serving as the primary mechanism for extracting data from enum variants. - Destructuring: Tiny supports object and array destructuring for
letandconstdeclarations, including nested patterns, default values, and property renaming. - Scoped Cleanups: The
deferstatement schedules a function call to execute immediately before the current scope exits, regardless of whether the function returned early or threw an error.
Concurrency and Threading
Tiny implements parallel execution using OS-level multi-threading rather than an event-loop model. The spawn keyword initiates a new execution routine on an isolated VM state space, allowing tasks to run concurrently across all available CPU cores.
To ensure thread safety, Tiny provides native lock blocks and mutexes via the sync standard library. The compiler guarantees that mutexes are automatically released when execution leaves the lock block to prevent deadlocks.
Inline Go Extensions
One of Tiny's standout features is the native fn block. This allows developers to write Go code directly within a Tiny source file. These blocks are compiled to WebAssembly via TinyGo and loaded at runtime, enabling the use of specific Go packages for performance-critical or system-level logic.
Standard Library and Tooling
Tiny provides a comprehensive standard library for various use cases:
validate: A chainable API for schema validation of objects, arrays, and unions.http: A concurrent web server and client with route-based multiplexing.ui: A WebView-based desktop container using HTML/CSS/JS with direct bindings to Tiny functions.desktop: OS automation tools for keyboard, mouse, and clipboard interaction.array: Native operations includingmap,filter,reduce, andsort.
Tooling and Distribution
The Tiny CLI provides several key commands:
tiny run: Compiles and runs scripts using a bytecode cache to avoid unnecessary recompilation.tiny pack: Bundles bytecode and the VM runtime into a single native executable (approximately 13MB).tiny dist: Packages applications with compiled plugins and assets.tiny lsp: Launches a Language Server providing type narrowing, semantic recovery, and refactoring safety in editors like VS Code.
Community Discussion
While the project has been praised for its rapid development, community members on Hacker News have questioned the specific use case for Tiny compared to using Go or Python directly. One user suggested its potential as a high-level scripting language for ad-hoc configuration management systems.
"i'm wondering if it can beat just installing go though. I think it'd be interesting to build a adhoc config mgmt system w/ this and use it as a high level scripting language."
Other users suggested that the author provide more detailed benchmarks against similar runtimes like LuaJIT to further validate the performance claims regarding binary size and memory requirements.