///
The Zen programming language introduces a fresh paradigm with its "zero keywords" philosophy, leveraging pattern matching, Uniform Function Call (UFC), and powerful metaprogramming for expressive and
104 views
~104 views from guests
Guest views are estimated from total page views. These include anonymous visitors and users who weren't logged in when they viewed the page.
The Zen programming language introduces a fresh paradigm with its "zero keywords" philosophy, leveraging pattern matching, Uniform Function Call (UFC), and powerful metaprogramming for expressive and concise code. The LANGUAGE_SPEC.zen serves as the definitive source of truth for the language's design.
This page provides an overview of Zen's core features through illustrative code examples, directly sourced from the project's README.
Zen offers six distinct ways to declare variables, emphasizing immutability by default and providing clear syntax for mutability, all without relying on traditional keywords.
x: i32: Declares x as an i32 but doesn't initialize it immediately; x is immutable by default.x = 10: Assigns a value to a previously declared variable or implicitly declares an immutable variable if not already existing.y = 10: Infers the type of y as i32 and makes it immutable.z: i32 = 20: Explicitly declares z as an i32 and initializes it immutably.w:: i32: Declares w as a mutable i32 without immediate initialization.w = 20: Assigns a value to the mutable variable w.v ::= 30: Infers the type of v as i32 and makes it mutable.u:: i32 = 40: Explicitly declares u as a mutable i32 and initializes it.Zen replaces all traditional conditional keywords like if/else, while, for, and match with a powerful pattern matching operator: ?.
condition ? { ... } executes the block if condition is true. For if/else logic, multiple arms can be used: condition ? | true { ... } | false { ... }.? operator is used with enum variants to execute different code blocks based on the variant of the entity variable. This provides a type-safe way to handle different data states.Zen provides structs for composite data types and enums for sum types, without requiring explicit keywords for their definition, using : for type definition.
Point: { ... } defines a struct named Point. Fields can be mutable (x:: f64) or have default values (y:: f64 = 0).Shape: Circle, Rectangle defines an enum where Circle and Rectangle are unit variants. Enums can also serve as type discriminators for UFC, as seen with GameEntity.Traits in Zen define shared behavior across different types, similar to interfaces or type classes in other languages. They are defined using a declarative syntax and implemented using .implements().
Geometric: { ... } defines a trait with method signatures (area and perimeter).Circle.implements(Geometric, { ... }) provides concrete implementations of the Geometric trait for the Circle type.Shape.requires(Geometric) states that all variants of the Shape enum must implement the Geometric trait, enforcing behavioral contracts.UFC allows any function to be called as a method, facilitating a flexible and extensible object-oriented style. It also enables function overloading based on enum variants.
get_health function is overloaded to provide different implementations based on the specific GameEntity variant it receives.player.get_health()) or a traditional function call style (get_health(player)), promoting flexibility.Zen eliminates null or nil by providing Option<T> for potentially absent values and Result<T, E> for fallible operations, encouraging explicit error handling.
Option<T> is an enum with Some(T) (value present) and None (value absent). Result<T, E> is an enum with Ok(T) (success with value) and Err(E) (failure with error).? operator is used to elegantly destructure Option<T> values, executing different branches based on whether a value is Some or None.Error handling is explicit in Zen, primarily through the Result<T, E> type and a .raise() method for concise error propagation, avoiding exceptions.
.raise() method, when called on a Result<T, E>, will either extract the T value if it's Ok, or immediately return the E value if it's Err, propagating the error up the call stack. This eliminates boilerplate if let checks for every fallible operation.Zen offers flexible looping constructs, including infinite loops, and range expressions for iteration, all integrated with the UFC style.
(0..10).loop((i) { ... }) iterates over a numerical range, with i taking each value. (0..100).step(10) allows iterating with a custom step size..loop() method, enabling concise processing of elements (shapes.loop((shape) { ... })).loop(() { ... }) creates an infinite loop, with break and continue statements controlling its flow. The ? operator handles conditional breaking.Zen distinguishes between synchronous and asynchronous operations not by function coloring, but by the allocator used, providing a unified function signature.
fetch_game_data can behave synchronously or asynchronously depending on the Allocator passed to it. This avoids function coloring, where functions must explicitly mark themselves as async or await.GPA.init() provides a synchronous allocator, while AsyncPool.init() provides an asynchronous one, driving the concurrency model.Zen features explicit pointer types instead of relying on * or & symbols, making pointer usage clearer and type-safe.
Ptr<T>, MutPtr<T>, and RawPtr<T> explicitly denote immutable, mutable, and raw (unsafe) pointers..ref() creates an immutable pointer, .mut_ref() creates a mutable one. Dereferencing is done via .val, and the memory address can be accessed via .addr.Zen provides powerful compile-time metaprogramming with full AST access, allowing code generation and transformation, along with runtime reflection capabilities.
reflect.ast(T) function allows runtime inspection of a type's Abstract Syntax Tree (AST), enabling dynamic type introspection and manipulation.@meta.comptime block executes code at compile-time, allowing programmatic access to and modification of the AST. This example prepends a println call to a function's body.Zen provides first-class support for concurrency via actors, channels, mutexes, and atomics, designed for robust and efficient parallel programming.
Actor((receiver) { ... }) defines an actor that can send messages to a receiver, useful for streaming data and lazy evaluation.Channel<string>(10) creates a buffered channel for message passing between concurrent tasks.Mutex<u32>(0) provides mutual exclusion for shared data, preventing race conditions. The ? operator is used for handling lock acquisition results.AtomicU32(0) offers atomic operations for lock-free concurrency on primitive types.Zen's DynVec allows storing elements of different types (variants of an enum) within a single vector, enabling flexible data structures.
DynVec<GameEntity.Player, GameEntity.Enemy> demonstrates a dynamic vector capable of holding multiple enum variants, offering a flexible way to manage heterogeneous collections.DynVec allows using pattern matching to process each element according to its specific type variant.Zen's module system supports importing and exporting symbols, enabling code organization and reuse.
{ io, maths } = @std) is used to import specific symbols from modules within the standard library (@std).module.exports = { ... } explicitly declares which symbols (types, functions, etc.) a module makes available to other modules.module.import("shapes2d").Circle shows how to import specific symbols from user-defined modules, demonstrating a clean and explicit module dependency management.