Zod

command module
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 6 Imported by: 0

README

Zod Programming Language

Zod Banner

Zod is a small (let's say it's a medium sized), interpreted, dynamically typed with a first-class functions, closures, arrays, hashes, and more.

Install

Prebuilt binaries for Linux, macOS, and Windows are attached to every GitHub Release.

Option 1: Download script
curl -fsSL https://raw.githubusercontent.com/theawakener0/Zod/main/install.sh | sh
Option 2: go install
go install github.com/theawakener0/Zod@latest

Requires Go 1.27 or newer and installs the Zod executable into your Go bin directory.

[!TIP] The standard library is embedded in the binary, so a plain go install works out of the box — no separate stdlib/ directory is needed.

Standard library lookup

import "std/..." resolves modules in this order:

  1. $ZOD_STDLIB environment variable (explicit override — wins).
  2. stdlib/ next to the zod executable (GitHub release tarballs ship this).
  3. stdlib/ in the current working directory.
  4. stdlib/ in up to 5 parent directories of the working directory/script.
  5. The standard library embedded in the binary.

Users who maintain their own copy of the stdlib should set $ZOD_STDLIB; it takes priority over every other source.

Demo

Conway's Game of Life

Conway's Game of Life

Features

  • First-class functions and closures
  • Data types: integers, floats, booleans, strings, arrays, hashes, matrices, and null
  • if / elseif / else control flow
  • C-style for loops, and infinite loop
  • break and continue
  • try(expr) for recoverable errors
  • Standard library in stdlib/ (std/fmt, std/str, std/array, …) via import "std/fmt" as fmt
  • The standard library is also embedded in the binary, so std/... imports resolve automatically without a stdlib/ directory
  • Legacy core built-ins for I/O (println(), printf(), input(), etc.), arrays, and hashes (kept for compat)
  • An interactive REPL

Getting Started

Prerequisites
  • Go 1.27 or newer
Build
# if you installed manually run this
go build -o zod .

[!NOTE] ZodLang now has a new engine, the VM, which is faster and more powerful. You can run the old engine with --eng=eval.

Run the REPL
# if you installed using the script
zod

# if you installed using go install
Zod

Inside the REPL, type /clear to clear the screen and /exit to quit.

Run a script
# if you installed using the script
zod file.zd

# if you installed using the script and want to run the eval engine
zod --eng=eval file.zd

# if you installed using go install
Zod file.zd

# if you installed using go install and want to run the eval engine
Zod --eng=eval file.zd

Examples

Hello, World!
println("Hello, World!")

More runnable examples live in examples/.

Language Reference

Data types
Type Example
Integer 42, -7, 0
Float 3.14, -0.5, 20.0
Boolean true, false
String "Hello, World!"
Array [1, 2, 3], []
Hash {"name": "Zod"}, {}
Matrix matrix(2, 2, [1, 2, 3, 4])
Bytes __bytes("hi") (private intrinsic; use std/*)
Error error("boom")
Null null
Operators
Category Operators
Arithmetic + - * / %
Comparison == != < > <= >=
Logical && || !
Increment ++ -- (prefix and postfix)
Assignment
Operator Meaning
let Declare a new variable: let x = 5
:= Assign (declares if needed): x := 5
+= -= *= /= %= Compound assignment: x %= 2

Index assignment works on arrays and hashes too: nums[0] = 10, user["age"] += 1.

Modules

Bindings are private by default. Prefix a top-level let or := with pub to export it.

// pub_lib.zd
pub let version = 1
let secret = "hidden"
pub greet := fn(name) { "hello, " + name }
from "examples/pub_lib.zd" import *      // all public bindings
from "examples/pub_lib.zd" import greet  // listed public bindings only
import "examples/pub_lib.zd" as m        // property access: m.version, m.greet("hi")

Importing or accessing a private binding is an error (e.g. secret is private). See docs/introduction.md (Modules & pub) and examples/modules_pub.zd for details.

Standard Library (preferred)

New code should use the standard library in stdlib/ (25 modules) instead of the legacy core built-ins below. Each module is imported by path with an alias:

import "std/fmt" as fmt
fmt.println("Hello, World!")
Module Import example Key exports
fmt import "std/fmt" as fmt print, println, eprint, printf, sprintf
str import "std/str" as str split, join, slice, trim, upper, lower, replace, index_of, starts_with, ends_with, repeat, pad_left, pad_right, contains, to_int, to_float, is_empty, has_prefix, has_suffix
array import "std/array" as array first, last, push, pop, pop_last, map, filter, find, any, all, reverse, flatten, join, sort, slice, range, make, zip, contains
hash import "std/hash" as hash get, set, contains, has, del, keys, vals, merge, remove, from_pairs
math import "std/math" as math pi, e, tau, abs, min, max, clamp, floor, ceil, round, exp, log, sqrt, pow, sin, cos, tan
matrix import "std/matrix" as matrix new, eye, zeros, ones, rows, row, get, transpose, mul, det2, det3, det, inv2, inv
rand import "std/rand" as rand seed, float, int, range, choice, shuffle
time import "std/time" as time sleep, now_ms, now_s, elapsed_note
os import "std/os" as os args, env_get, env_set, env_list, exit, cwd
  • The __* names (about 50 intrinsics such as __print, __str_split, __read_file) are private implementation details backing std/*. Do not call them directly.
  • New types: Bytes (type(x) returns "BYTES") and Error values (type(error("x")) returns "ERROR"). New globals are error(msg) (creates an error value) and is_error(x) (tests for one); string() also formats Array, Hash, Matrix, Bytes, null, and Error (string(error("x")) returns "Error: x").
  • Capture errors with try(): let r = try(error("x")) returns [false, "x"]. A bare let e = error("x") halts evaluation by design, so always wrap error-producing expressions in try() (or nest them, e.g. string(error("x")), which works on both engines).
  • An imported name shadows a same-named core built-in (e.g. array.push vs push) on both engines. Several modules export the same name (join in str/array/path, contains in str/array/hash), so always import with an alias and call through it.
  • std/ lookup order and runnable examples are documented in docs.
Legacy core (kept for compat)

The original 24 built-ins below still work, but new code should use std/* instead.

Function Description
len(x) Length of a string, array, hash, or matrix
println(...) Print each argument on its own line
printf(fmt, ...) Formatted output (Go-style verbs)
input(prompt) Read a line of input from the user
int(x) Convert x to integer
float(x) Convert x to float
string(x) Convert x to string (also Array, Hash, Matrix, Bytes, null, Error → "Error: msg")
type(x) Return the type name of x
first(arr) First element of an array
last(arr) Last element of an array
push(arr, x) New array with x appended
pop(arr) New array without its last element
insert(hash, k, v) New hash with k: v added
remove(hash, k) New hash without key k
keys(hash) Array of keys in insertion order
vals(hash) Array of values in insertion order
contains(hash, k) Whether hash contains key k
random(...) Random float in [0, 1); with one arg, in [0, x)
matrix(r, c, data) Matrix with r rows and c cols from data
make(size) / make(size, value) Create a new array with size elements, and value
color(color, text) Change the color of text to color
sleep(ms) Pause execution for ms milliseconds
exp(x) e^x
pi() π

[!NOTE] The color function is still under development so it doesn't have many colors.

for more details. Go to the docs.

Acknowledgments

Inspired by Thorsten Ball's Writing an Interpreter in Go and Writing a Compiler in Go.

License

MIT License. See LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package stdlib exposes the Zod standard library as an embedded filesystem so the interpreter can resolve "std/..." imports even when no stdlib directory exists next to the executable (e.g.
Package stdlib exposes the Zod standard library as an embedded filesystem so the interpreter can resolve "std/..." imports even when no stdlib directory exists next to the executable (e.g.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL