Changelog¶
v1.0.0 — Initial Release¶
First stable release of Zen.
- Compiler core stabilized (LLVM backend)
- Language design finalized
- Standard library introduced
- Basic tooling and documentation added
Notes¶
This marks the first public version of Zen. Future updates will be incremental improvements and new features.
v1.0.1¶
- Disabled map dynamic key access (compile-time safety)
- Disabled
loop inmutation during iteration (undefined behavior prevention) - Added
sys.performance()to stdlib - Added
sys.argvto stdlib - Various bug fixes
v1.1.1¶
Language¶
- Added support for
List<Struct> - Added limited struct literal support
- Struct variables can now be initialized using literals:
Person p = { name: "Jishith", age: 21 } - Functions can now return structs
- Structs can now be exported and imported across modules
- Empty initialized global struct instances can be exported and imported
- Added
bytegeneric support throughList<byte> - Added limited empty List type inference when type context is available
- Disabled automatic function type inference for structs
- Disabled dynamic map access and dynamic map assignment
- Disabled maps as function parameters
Standard Library¶
- Added
matchRegex()with POSIX ERE regex support - Added
ffi.fn - Added
List.join() - Added
List.indexOf() - Added
Map.keys()returningList<string> - Added
fs.readFileBytes() - Added
fs.writeFileBytes() - Added binary file support through
List<byte>
Compiler & Runtime¶
- Added function name mangling
- Migrated compiler and runtime to LLVM opaque pointers (
ptr) - Added 32-bit and 64-bit aware size and alignment calculations
- Standardized internal LLVM helper functions with
_-prefixed names - Improved global string handling after opaque pointer migration
- Improved struct passing and struct return behavior
Tooling¶
- Added
zen init <project-name>for project scaffolding
Creates a new project directory containing:
<project-name>/
├── main.zen
└── zen.json
Generated zen.json:
{
"name": "<project-name>",
"version": "1.0.0",
"main": "main.zen"
}
- Added official Zen Package Registry for package management
- Added
zen signupandzen loginfor authentication - Added
zen logoutandzen whoamifor account management - Added
zen install <package>to install packages from registry - Added
zen publishto publish packages to registry - Added
zen unpublishto remove packages from registry - Added
zen listwith pagination to browse all packages (50 per page) - Registry supports both runnable applications (
main) and library packages (bin) - Library packages install to
~/.zen/packages/ - Runnable applications install to current directory
- Secure JWT-based authentication
- GitHub-hosted package source code
Fixes¶
contains()no longer performs struct literal comparisons- Various compiler, runtime, and standard library bug fixes
v1.2.1¶
Language¶
- Introduced
enumwith constant integer values - Added support for importing and exporting within the same module
- Added circular import detection and resolution
- Added installed package imports (
import(...) from "package") - Exported modules can now import other modules and packages
- Added built-in
HttpServer,HttpRequest, andHttpResponsestructs
Standard Library¶
- Added
httpServernamespace - Added
httpServer.create(port) - Added
HttpServer.listen() - Added
HttpServer.next() - Added
HttpServer.close() - Added
HttpRequest.method - Added
HttpRequest.path - Added
HttpRequest.json() - Added
HttpRequest.html() - Added
HttpRequest.css() - Added
HttpRequest.send() - Added
HttpRequest.setHeader() - Added
HttpRequest.redirect() - Added
HttpRequest.status() - Added
sys.setEnv() - Added
sys.hasEnv() - Added
sys.timestamp() - Added
sys.execOutput() - Added
os.exit() - Added
os.pid() - Added
os.parentPid() - Added
os.platform() - Added
os.isWindows() - Added
os.isLinux() - Added
os.isMac() - Added
os.isAndroid() - Added
os.homeDir()
Tooling¶
- Added
zen recoveryfor account recovery - Added
zen uninstall <package> - Added
zen search <package> - Added
zen kind <package> - Added
zen mine zen installnow automatically detects the repository's default Git branch- Increased package description limit from 50 to 400 characters
- Migrated the package registry backend from JSON storage to PostgreSQL
Compiler & Runtime¶
- Improved module dependency resolution
- Improved import/export compilation
- Improved HTTP runtime support
Fixes¶
- Various compiler, runtime, CLI, package registry, and standard library bug fixes
v1.3.0¶
Language¶
- Added built-in
Json,JsonObject, andJsonArraystructs - Added JSON parsing and traversal API
- Added
HttpRequest.body - Added bitwise XOR (
^) operator for integer operands - Added
time.now() - Added
time.format() - Added
sys.clipboard.get() - Added
sys.clipboard.set() - Added
sys.clipboard.clear() - Added
sys.clipboard.hasText()
Standard Library¶
- Added
Json.parse() - Added
Json.free() - Added
Json.getRootObject() - Added
Json.getRootArray() - Added
JsonObject.getString() - Added
JsonObject.getInt() - Added
JsonObject.getDouble() - Added
JsonObject.getBool() - Added
JsonObject.getObject() - Added
JsonObject.getArray() - Added
JsonArray.getString() - Added
JsonArray.getInt() - Added
JsonArray.getDouble() - Added
JsonArray.getBool() - Added
JsonArray.getObject() - Added
JsonArray.getArray() - Added
HttpRequest.sendFile(path, contentType)
Compiler & Runtime¶
- Added compile-time distinction between built-in struct properties and methods
- Added compile-time validation for built-in struct property access
- Added runtime
JsonError - Added use-after-free detection for JSON objects
- Improved HTTP server runtime
- Improved JSON runtime
- Improved bitwise operator validation
Documentation¶
- Expanded language specification
- Added JSON API documentation
- Added HTTP server documentation
- Added semantics documentation
- Added runtime error reference
Removed¶
sys.timestamp()has been removed.
Usetime.now()instead.
Fixes¶
- Various compiler, runtime, CLI, package registry, and standard library bug fixes
v2.0.0 — Major Release¶
⚠️ Breaking Release
ZEN v2 introduces the largest language update since the initial release. Several language constructs have been refined for improved consistency, readability, and long-term stability.
From v2 onwards, the language syntax is considered frozen for backward compatibility. Future releases will focus on new features and APIs while preserving existing syntax whenever possible.
Language¶
Syntax Changes¶
⚠️ Breaking Change
Struct field declarations now use
type nameorder.Old
name string age intNew
string name int age⚠️ Breaking Change
constnow appears before the type.Old
int const age = 10New
const int age = 10
- Added
.free()method forstringvalues - Introduced
.free()methods for heap-owned values - Heap-owned values in Zen now provide an explicit
.free()method for manual memory management - Improved ownership and memory management semantics for heap-allocated values
⚠️ Breaking Change
bytehas been replaced by the built-inBytestruct.Binary APIs now use
List<Byte>, and byte values are created usingtoByte().
- Added callback function parameters (
fn cb(...)) - Added
thread fnfor lightweight concurrent execution - Added
extern fnfor foreign function declarations without name mangling - Added generic function call syntax (
function<Type>()) for type-safe generic returns - Added built-in
Ptrstruct for native pointer manipulation - Added built-in
Bytestruct for binary data - Added global
toByte()conversion function Mapis now implemented as a built-in struct instead of a language data type- Added struct-style
Mapliterals - Introduced ownership semantics for runtime-managed objects
- Improved compile-time type safety for generic APIs
Standard Library¶
HTTP¶
- Added
http.urlEncode() - Added
http.urlDecode() - Added
http.setHeader() - Added
http.clearHeaders() - Added
http.lastStatus() - Added configurable request timeout support
Threads¶
- Added
threadsnamespace - Added
threads.waitAll()
Debug¶
- Added
debugnamespace - Added
debug.pretty()for formatted printing of Lists, Maps, and structs
Package Registry¶
- Added package version history and version-specific publishing
- Added support for installing specific package versions:
zen install <package>@<version> - Added automatic dependency detection with
zen deps - Added recursive dependency detection through imported
.zenfiles - Added automatic dependency installation during package installation
- Package dependencies are stored in
zen.json - Added support for recursive package dependencies
- Package versions are backed by Git tags
- Registry now preserves previously published package versions
- Added version-specific package metadata and repository resolution
- Library packages are installed to
~/.zen/packages/<package> - Installing a package automatically installs its dependencies
- Added Semantic Versioning validation for package versions
Compiler & Runtime¶
- Added runtime support for thread execution
- Added callback code generation support
- Added external function declarations
- Added native pointer runtime (
Ptr) - Migrated
Mapto an opaque built-in runtime struct - Migrated binary APIs to
List<Byte> - Added compile-time ownership validation where possible
- Added runtime detection for invalid ownership operations
- Added runtime detection for use-after-free errors
- Improved generic type resolution for nested
Listtypes - Improved built-in struct handling
- Improved
Byteruntime integration - Improved HTTP runtime
- Improved parser consistency
- Improved formatter support
Tooling¶
- Added official source formatter (
zen fmt) - Added built-in linter (
zen lint) - Added Language Server Protocol (LSP) implementation
- Added editor auto-completion support
- Added hover information support
- Added signature help support
- Improved diagnostics
- Improved code formatting workflow
- Improved developer tooling integration
Documentation¶
- Completely rewritten language specification
- Updated all syntax examples to v2
- Added thread documentation
- Added callback documentation
- Added
externdocumentation - Added
Ptrdocumentation - Added
Bytedocumentation - Added
toByte()documentation - Added ownership semantics documentation
- Added
Mapruntime documentation - Expanded built-in struct documentation
- Updated binary API documentation to
List<Byte> - Improved API reference
- Improved appendix and language reference
Fixes¶
- Fixed numerous parser bugs
- Fixed formatter inconsistencies
- Fixed built-in struct handling
- Fixed HTTP runtime issues
- Fixed generic type resolution
- Fixed module and compiler edge cases
- Fixed known compiler, runtime, tooling, and standard library bugs
Notes¶
This release marks the beginning of the ZEN v2 series. The language syntax is now considered stable, with future releases focusing on new capabilities, performance improvements, tooling, and standard library expansion while maintaining backward compatibility.
v2.1.0¶
Language¶
- Added new primitive type
byte(i8) - Added new primitive type
long(i64) - Added
Lsuffix forlongliterals - Added
Bsuffix forbyteliterals - Added hexadecimal
byteliterals using an explicit trailingBsuffix - Changed
toByte()toByte() - Added
Long()global cast - Added concatenation coercion support for
byte - Added
setT()/getT()support forlongandbyte
Standard Library¶
Crypto¶
Added the new crypto namespace:
crypto.sha256(data)crypto.sha512(data)crypto.hmacSha256(key, data)crypto.hmacSha512(key, data)crypto.randomBytes(length)crypto.randomInt(min, max)crypto.base64Encode(data)crypto.base64Decode(data)crypto.base64UrlEncode(data)crypto.base64UrlDecode(data)
Map & JSON¶
- Added
Map.json() - Added
Json.map()
Compiler & Runtime¶
- Changed several built-in APIs from
inttolongfor 64-bit values.
OS¶
os.totalMemory:int→longos.freeMemory:int→longos.usedMemory:int→longos.processMemory:int→longos.pid:int→longos.parentPid:int→long
Time¶
time.millis:int→longtime.now:int→longtime.formatargument:int→longtime.sleepargument:int→long
v2.1.1¶
Standard Library¶
HTTP¶
- Added
HttpRequest.getHeader()for retrieving a request header by name.
JSON & Map¶
⚠️ Important
- JSON integer numbers become
Longvalues when converted using.map(). - After
.map(), usegetLong()to retrieve JSON integer values. - Normal
Mapinteger/long behavior remains unchanged.
Language¶
Automatic List Field Initialization¶
- List fields are automatically initialized when a new struct instance is declared without an initializer.
- Struct literals only initialize or assign the fields explicitly specified in the literal.
Path¶
extName()returns the file extension without the leading..path.extname()returns the file extension with the leading..
Fixes¶
- Various compiler, runtime, standard library, and type-resolution bug fixes.
v3.0.0 — Major Release¶
⚠️ Breaking Release
toString()/toInt()renamed tointToAscii()/asciiToInt()privateis now a reserved keyword (functions, methods, fields)- Keyword
inremoved- Classic loops must always use
loop (init, cond, update)+with a string operand converts the other operand to a string and concatenatesfs.writeFileBytes()now returnsint(success code) instead ofvoidsqrt()now takes and returnsdoublezen testsrenamed tozen testzen -vchanged tozen --v- JSON integers after
.map()are no longer alwaysLong(see Standard Library)- Windows support is temporarily paused
Language¶
- Formalized numeric widening:
byte→int→long→double boolcan now be used in arithmetic (true= 1,false= 0) and bitwise operations- Added bitwise operators
&,|,>>,<<,~ - Added unary
+ autoinference now supportsint,bool,double,string,long,byte- Added compile-time constants (
int N = 10; int arr[N]) sizeOf()now supports bare types and expressions (bare struct names are not supported)- Struct fields can have default initializers
- Uninitialized structs get zero-value fields (
0,"",false, empty list) - Struct literals only set the fields explicitly given
- Added anonymous inline functions as callback arguments (no closures: they cannot capture outer variables)
- Named functions passed as callbacks can use closures
- Thread functions now accept parameters and report capture errors at compile time
- Thread methods in structs are supported
- Added multiple exports and imports per file
- Added import aliasing for functions and variables (
import (worker as w)); structs cannot be aliased - Struct dependencies are tracked: importing a struct also registers its dependent structs as hidden (usable through the struct, not nameable)
- Exported functions can take or return structs that are not exported
- Chained calls on returned structs are supported (
make().show()) - Added
privatefor fields and methods - Added scientific notation for
doubleliterals (1e300,1.5e-10,2E+5) byteis signed (-128 to 127); suffixed values outside the range wrap (two's complement)- Hex literals without a suffix are always
int(0xFBis 251) - Hex literals with a type suffix need an underscore:
0xFB_Bisbyte,0xFF_Lislong - Added
\eand\xHHstring escapes (for example"\e[31m"for ANSI colors) - Added constants
SQRT1_2,SQRT3,LOG2E,LOG10E,BYTE_MAX,BYTE_MIN,I64_MAX,I64_MIN
Standard Library¶
General¶
- Added
lastIndexOf() - Added
stringToBytes()andbytesToString() length()now accepts a List directly, alongsidelist.length
List and Map¶
- Added
List.remove(),List.reverse(),List.sort(),List.sum(),List.avg() - Added
List.flat()(flattens any depth to depth 1) - Added
Map.keys()andMap.entries()
JSON¶
⚠️ Important
JSON numbers converted with
.map()can be read withgetInt(),getByte()orgetLong(). Overflow is checked at runtime for the getter used. This replaces the v2.1.1 behavior where integers were alwaysLong.
File System and System¶
- Added
fs.listDir(),fs.isFile(),fs.isDir() - Added
sys.spawn(),sys.kill(),sys.isRunning(),sys.wait() - Added
threads.count()andthreads.currentId()
Networking¶
- Added TCP support:
TcpandTcpServerstructs - Added
net.online(),net.connect(host, port),net.listen(port) - Added
Tcp.send(),Tcp.receive(),Tcp.close(),Tcp.isOpen() - Added
TcpServer.accept(),TcpServer.close(),TcpServer.isOpen()
HTTP¶
- Added
http.getProgress(url, callback)for downloads with progress reporting. The callback receivesdownloadedandtotalbytes (long), and the call returns the data asList<byte> - Connect timeout is 10 seconds for every request
- Requests without a progress callback have a 30 second total limit
- Requests with a progress callback have no total limit; they abort only if speed stays below 1 KB/s for 30 seconds
- Network failures and timeouts print a
NetworkErrorand exit
Tooling¶
zen installandzen uninstallaccept multiple package names- renamed zen -h to zen --h
- Added
zen installed - Added
zen upgrade <package> - Added
zen install <package>@<semver> - Added
zen read <package> [--raw]to render a package README in the terminal - Added
zen update --devto install the development version - Added
zen test <package>to run a package'stest.zen - Added
zen --v <package>,zen --version <package>andzen version <package>for installed package versions - Added
zen infofor namespaces and globals (with--methodName) zen depsnow detects and recordsnative/*.o; native objects link automatically.cfiles are supported as native dependencieszen.jsonsupportsflags: []at module and standalone level (for example-lmariadb)- Added
--link a.o b.o - Added interactive REPL (
zenwith no arguments); prints "Bye!" onexit() - Enhanced LSP server (
zen lsp) - Enhanced formatter and fixed bugs
- Fixed linter bugs
- Better compile-time diagnostics with hints and source text
zen fmt¶
Formats .zen files. Output goes next to the source as name.formatted.zen
(the original is never touched).
Usage¶
zen fmt <path...> [-r | --recursive] [--no-comments]
| Command | What it formats |
|---|---|
zen fmt a.zen |
one file |
zen fmt a.zen b.zen |
several files |
zen fmt src |
.zen files directly inside src |
zen fmt src -r |
everything under src, all subfolders |
zen fmt . -r |
the whole project |
zen fmt *.zen |
shell glob, works as normal multiple paths |
Flags¶
-r,--recursivedescend into subdirectories (flag position doesn't matter)--no-commentsdrop comments from the output
Rules¶
- Skipped always:
*.formatted.*files (so re-running never formats its own output) - Skipped when recursing:
node_modules,build,.git,.zen - Duplicate paths are formatted once
- Errors:
Path not found: <path>if an input doesn't exist,No .zen files foundif nothing matched
Breaking change¶
The old dir/* and dir/** syntax is removed. The shell expanded them
before zen saw them. Use dir and dir -r instead.
Installer¶
- Added
--tagand--branchinstall modes - Branch installs skip the
VERSIONcheck and version from the short commit hash - Verified on Termux (Android) and reviewed for apt, pacman, dnf and zypper
- Windows is not supported for now (documented, not auto-installed)
Compiler & Runtime¶
- Thread methods spawn through the same path as thread functions
- Thread context is freed inside the thread; string arguments are duplicated and freed per thread
- Struct dependency tracking with clear errors for naming or clashing with hidden structs
- Redefinition errors now show line information
- Unified unknown-struct error in member chains
- Parser supports chained access after a statement-level call
Documentation¶
- Added architecture documentation
- Updated error reference
Known Limitations¶
- Structs cannot be imported with an alias
debug.pretty()does not support struct fields of typeList<Map>- HTTP timeouts are not configurable; no retry or resume
- Windows support is paused
Fixes¶
- Fixed linter, formatter and LSP bugs
- Various compiler, runtime, CLI, and standard library bug fixes
v3.1.0 — Language and Standard Library Improvements¶
Language¶
- Added automatic initialization of
Mapfields in structs when no initializer is provided - Added optional labeled function arguments using
label: valuesyntax; labels are for readability and do not affect argument ordering or evaluation
Standard Library¶
Path¶
- Updated
path.join()to accept two or more path components in a single call
Output¶
- Added variadic
print()built-in for printing multiple values separated by a single space, followed by a newline - Preserved the existing
screen(value, format)API for formatted output
Map¶
- Added
Map.type(key)to return the canonical type of a stored value as a string, including nested list types such asList<List<int>>
Compiler & Runtime¶
- Restricted explicit type arguments to generic-capable calls; currently,
getList()supports explicit type arguments - Added runtime validation of requested list depth and leaf type in
Map.getList() - Added validation of declared list types against
getList()generic arguments - Added validation of supported list element types in
Map.setList()andMap.getList() - Improved nested list inference for Map values,
setList()arguments, and function return values - Improved list depth and leaf-type validation during indexing
- Added runtime bounds checking for string indexing
- Fixed undefined behavior when iterating over a List of Maps
Diagnostics & Compiler Improvements¶
- Improved parser diagnostics for missing closing braces at EOF
- Improved source locations for unresolved struct field types
- Improved type errors for void expressions used where values are expected
- Improved built-in type handling and error messages
- Improved return-path analysis for
switchstatements with adefaultcase - Added typo suggestions for unknown functions, variables, and namespaces
- Improved handling of generic type arguments in method and function calls
CLI & Runtime¶
- Fixed program argument forwarding in
zen run - Fixed propagation of nonzero exit codes from compiled programs
Fixes¶
- Fixed Map initialization and pointer handling in struct fields
- Fixed incorrect list element sizes and metadata for nested lists
- Fixed generic handling and type validation in Map list operations
- Fixed invalid LLVM generation when indexing beyond the declared list depth
- Various compiler, parser, runtime, CLI, and standard library bug fixes