Pyro Documentation
Welcome to the official documentation for the Pyro programming language. Pyro is a compiled language with 23 keywords, 76 built-in modules, and native C++ speed.
Installation
Install Pyro on your system in under a minute. Pre-built binaries — no compilers or build tools needed.
Linux / macOS
curl -fsSL https://aravindlabs.tech/pyro-lang/install.sh | bash
Windows (PowerShell)
irm https://aravindlabs.tech/pyro-lang/install.ps1 | iex
Downloads Pyro + MinGW C++ toolchain automatically. No Visual Studio, no restarts, no admin needed.
Build from Source (advanced)
Only needed if you want to modify Pyro itself
git clone https://github.com/krish9219/pyro.git
cd pyro
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
sudo make install
Verify the installation:
pyro --version
# Pyro Programming Language v1.0.0
Hello World
Create a file called hello.ro:
# No main() needed — just write code
print("Hello, World!")
Run it:
pyro run hello.ro
Or compile and run the binary:
pyro build hello.ro -o hello
./hello
Your First Program
Let's build a small program that reads a name and greets the user:
import io
print("What is your name?")
name = io.readline()
print("Hello, " + name + "! Welcome to Pyro.")
# Pipe operator example
squares = [1, 2, 3, 4, 5] |> map(|x| x * x)
big = squares |> filter(|x| x > 5)
big |> each(|x| print("Square: {x}"))
Using the REPL
Start the interactive REPL with:
pyro repl
Pyro 1.0.0 REPL — Type :help for commands, :quit to exit
>>> x = 42
>>> x * 2
84
>>> [1,2,3] |> map(|x| x + 10)
[11, 12, 13]
Variables & Types
Pyro is statically typed with type inference. Just assign values directly — no keyword needed. Use mut for mutable variables. The optional let keyword can enforce immutability explicitly.
# Simple assignment (no keyword needed)
name = "Pyro" # type inferred as str
age = 1 # int
pi = 3.14159 # float
active = true # bool
data = nil # nil value
# Mutable (use mut when you need to reassign)
mut counter = 0
counter = counter + 1
# Optional: use let for explicit immutability
# let locked = 42 # compiler enforces no reassignment
# Collections
list = [1, 2, 3] # List<int>
map = { "a": 1, "b": 2 } # Map<str, int>
tuple = (1, "hello", true) # (int, str, bool)
Built-in Types
| Type | Description | Example |
|---|---|---|
int | 64-bit signed integer | 42 |
float | 64-bit floating point | 3.14 |
bool | Boolean | true, false |
str | UTF-8 string | "hello" |
List<T> | Growable array | [1, 2, 3] |
Map<K,V> | Hash map | {"a": 1} |
nil | Absence of value | nil |
Functions
Functions are first-class citizens in Pyro. Declare them with fn.
# Basic function
fn greet(name)
return "Hello, " + name + "!"
# One-liner
fn add(a, b) = a + b
# Default parameters
fn power(base, exp = 2)
mut result = 1
for _ in 0..exp
result = result * base
return result
# Higher-order functions
fn apply_twice(f, val)
return f(f(val))
print(greet("World"))
print(power(3)) # 9 (default exp=2)
print(power(2, 10)) # 1024
print(apply_twice(|x| x * 2, 3)) # 12
Control Flow
# If / else
if score >= 90
status = "A"
else if score >= 80
status = "B"
else
status = "C"
# For loops
for i in 0..10
print(i)
for item in my_list
print(item)
# While loop
mut n = 10
while n > 0
print(n)
n = n - 1
# While true with break
while true
input = io.readline()
if input == "quit"
return
print("You said: " + input)
Structs
import math
# Structs hold data
struct Point
x = 0.0
y = 0.0
# Use functions to operate on structs
fn distance(a, b)
dx = a.x - b.x
dy = a.y - b.y
return math.sqrt(dx * dx + dy * dy)
mut a = Point()
a.x = 0.0
a.y = 0.0
mut b = Point()
b.x = 3.0
b.y = 4.0
print(distance(a, b)) # 5.0
print("Point: ({b.x}, {b.y})")
Enums
enum Color
Red
Green
Blue
fn describe(c)
if c == Color.Red
return "red"
if c == Color.Green
return "green"
return "blue"
print(describe(Color.Red)) # "red"
print(describe(Color.Green)) # "green"
Pattern Matching
fn classify(n)
if n == 0
return "zero"
if n < 10
return "small"
if n < 100
return "medium"
if n < 1000
return "large"
return "huge"
print(classify(0)) # "zero"
print(classify(5)) # "small"
print(classify(50)) # "medium"
print(classify(500)) # "large"
print(classify(5000)) # "huge"
Structs & Functions
# Structs are data containers; use functions to operate on them
import math
struct Circle
radius = 0.0
fn circle_area(c)
return math.PI * c.radius * c.radius
fn circle_info(c)
return "Circle(r={c.radius})"
mut c = Circle()
c.radius = 5.0
print(circle_area(c)) # 78.539...
print(circle_info(c)) # Circle(r=5.0)
Pipe Operator
The pipe operator |> passes the result of the left expression as the first argument to the right function. This makes data transformations read naturally from left to right.
# Without pipes (nested, hard to read)
print(join(sort(filter(map(data, square), is_even)), ", "))
# With pipes (clear, left to right)
result = data |> map(square) |> filter(is_even)
result = result |> sort |> join(", ")
print(result)
Closures
# Closures capture their environment
fn make_adder(n)
return |x| x + n # captures 'n'
add5 = make_adder(5)
print(add5(10)) # 15
# Lambdas with pipe operator
data = [-3, 1, -1, 4, 2]
result = data |> filter(|x| x > 0) |> map(|x| x * 2) |> sort
print(result) # [2, 4, 8]
Error Handling
import fs
# try/catch/finally — like Python but without colons
fn read_config(path)
try
content = fs.read(path)
return content
catch err
print("Error: {err}")
return nil
# throw to raise errors
fn divide(a, b)
if b == 0
throw "Division by zero!"
return a / b
try
result = divide(10, 0)
catch e
print("Caught: {e}")
finally
print("Cleanup done")
Async / Await
Pyro supports timing and scheduling with the time module. For concurrent tasks, use the thread module.
import time
# Measure execution time
start = time.now()
mut sum = 0
for i in 0..1000000
sum = sum + i
elapsed = time.now() - start
print("Sum: {sum}")
print("Computed in {elapsed} ms")
Modules
# Import a standard library module
import json
import http
import math
# Use dot notation to access module functions
print(math.PI)
print(math.sqrt(144))
data = json.parse("{\"key\": \"value\"}")
# Create a public module
# file: mylib.ro
pub fn hello()
return "hello from mylib"
# file: main.ro
import mylib
print(mylib.hello())
Core Modules (12)
| Module | Description |
|---|---|
std | Core utilities, print, assert, type conversions |
io | Input/output streams, stdin/stdout, file handles |
os | Operating system interfaces, environment variables |
fs | File system operations: read, write, mkdir, walk |
path | Path manipulation: join, dirname, basename, ext |
fmt | String formatting with templates and alignment |
math | Math constants and functions: PI, sqrt, sin, cos, log |
time | Time, date, duration, timers, sleep |
log | Structured logging: info, warn, error, debug |
errors | Error types and construction utilities |
types | Type checking and casting utilities |
reflect | Runtime reflection and introspection |
Data Modules (12)
| Module | Description |
|---|---|
json | JSON parsing and serialization |
csv | CSV reading/writing with headers and type inference |
xml | XML parsing and generation |
yaml | YAML parsing and serialization |
toml | TOML configuration file support |
base64 | Base64 encoding and decoding |
hex | Hexadecimal encoding and decoding |
sqlite | Embedded SQLite database with prepared statements |
collections | HashMap, HashSet, Deque, PriorityQueue, BTree |
iter | Iterator adapters: chain, zip, enumerate, take, skip |
serialize | Binary serialization and deserialization |
compress | Gzip, zlib, and deflate compression |
Web Modules (10)
| Module | Description |
|---|---|
http | HTTP client and server with routing |
url | URL parsing, encoding, query string handling |
websocket | WebSocket client and server |
html | HTML parsing and generation |
template | Template engine with logic and loops |
mime | MIME type detection and handling |
cookie | HTTP cookie parsing and creation |
router | URL routing with path parameters |
cors | Cross-Origin Resource Sharing middleware |
sse | Server-Sent Events support |
Security Modules (8)
| Module | Description |
|---|---|
crypto | High-level cryptography: encrypt, decrypt, hash |
hash | SHA-256, SHA-512, MD5, BLAKE2 |
hmac | HMAC message authentication |
aes | AES-128/256 CBC and GCM modes |
rsa | RSA key generation, encrypt, decrypt, sign, verify |
tls | TLS/SSL connections and certificate handling |
jwt | JSON Web Token creation and verification |
pbkdf2 | PBKDF2 key derivation with configurable rounds |
Algorithm Modules (8)
| Module | Description |
|---|---|
sort | Sorting algorithms: quicksort, mergesort, timsort |
search | Binary search, linear search, pattern search |
graph | Graph algorithms: BFS, DFS, Dijkstra, topological sort |
matrix | Matrix operations: multiply, transpose, determinant |
stats | Statistics: mean, median, stdev, linreg, correlation |
random | Random number generation, distributions, shuffle |
bigint | Arbitrary precision integer arithmetic |
bitops | Bitwise operations and bit manipulation |
Networking Modules (10)
| Module | Description |
|---|---|
net | Low-level networking: sockets, addresses |
tcp | TCP client and server |
udp | UDP sockets and datagrams |
dns | DNS resolution and lookup |
smtp | SMTP email sending |
ftp | FTP client for file transfers |
ssh | SSH client and remote execution |
grpc | gRPC client and server with protobuf |
mqtt | MQTT messaging protocol client |
redis | Redis client with pub/sub support |
System Modules (8)
| Module | Description |
|---|---|
process | Process spawning, pipes, signals |
thread | OS threads with shared memory |
async | Async runtime, tasks, channels, join |
signal | OS signal handling |
env | Environment variable access |
sys | System information: arch, OS, CPU count |
mem | Memory allocation and management |
ffi | Foreign Function Interface for C libraries |
Text Modules (8)
| Module | Description |
|---|---|
string | String utilities: split, trim, replace, pad |
regex | Regular expressions with capture groups |
unicode | Unicode normalization and properties |
glob | Glob pattern matching for paths |
diff | Text diffing and patching |
color | Terminal color and styling (ANSI codes) |
table | ASCII table formatting for terminal output |
plot | Terminal-based charts and graphs |
CLI Commands
All commands available in the Pyro CLI:
| Command | Description |
|---|---|
pyro run <file.ro> | Run a Pyro program |
pyro build <file.ro> | Compile to native binary |
pyro watch <file.ro> | Watch and auto-restart on changes |
pyro new <type> <name> | Create new project (webapp, api, cli) |
pyro install <package> | Install package from GitHub |
pyro deploy <platform> <file> | Deploy (docker, binary) |
pyro check <file.ro> | Type check without running |
pyro fmt <file.ro> | Format source code |
pyro update | Update Pyro to latest version |
pyro emit <file.ro> | Show generated C++ code |
pyro bench <file.ro> | Run benchmarks |
pyro doc <file.ro> | Generate documentation |
pyro debug <file.ro> | Run with debugger |
pyro profile <file.ro> | CPU profiling |
pyro tokens <file.ro> | Show lexer tokens |
pyro init | Initialize a new project |
pyro repl | Start interactive REPL |
pyro version | Show version |
pyro help | Show help |
Keywords (23)
Pyro has exactly 23 reserved keywords:
| Keyword | Purpose |
|---|---|
let | Declare an immutable variable (optional — bare assignment works too) |
mut | Make a variable mutable |
fn | Declare a function |
return | Return a value from a function |
if | Conditional branch |
else | Alternative branch |
for | Loop over a range or iterator |
in | Iterator binding in for loops |
while | Loop with condition |
match | Pattern matching expression |
struct | Define a data structure |
enum | Define an enumeration |
import | Import a module |
pub | Mark item as public |
async | Declare an async function |
await | Await an async value |
true | Boolean true literal |
false | Boolean false literal |
nil | Null/absence of value |
try | Begin error handling block |
catch | Handle errors from try block |
throw | Throw an error |
finally | Always-execute block after try/catch |
Operators
| Operator | Description | Example |
|---|---|---|
+ - * / % | Arithmetic | a + b |
== != < > <= >= | Comparison | a == b |
&& || ! | Logical | a && b |
|> | Pipe | x |> f |
.. | Range | 0..10 |
? | Error propagation | val? |
. | Member access | module.func |
=> | Match arm | 1 => "one" |
Type System
Pyro uses a static type system with full type inference. The compiler infers types at compile time, but you can always annotate explicitly for clarity.
# Type inference — just assign, no annotations needed
x = 42 # int
y = 3.14 # float
z = "hello" # str
nums = [1, 2, 3] # list
# mut for mutable variables
mut counter = 0
counter = counter + 1
# Functions work on any type
fn first(items)
if items.len() == 0
return nil
return items[0]
print(first([10, 20, 30])) # 10
print(first([])) # nil
Grammar Summary
Pyro's grammar is intentionally small. The complete formal grammar fits on a single page:
program = declaration*
declaration = fn_decl | struct_decl | enum_decl | import_decl | statement
fn_decl = ["pub"] ["async"] "fn" IDENT "(" params? ")" block
struct_decl = ["pub"] "struct" IDENT NEWLINE INDENT fields
enum_decl = ["pub"] "enum" IDENT NEWLINE INDENT variants
import_decl = "import" path
statement = let_stmt | expr_stmt | return_stmt | for_stmt | while_stmt
expression = assignment | pipe | logical | comparison | arithmetic | unary | call | primary
pipe = expression "|>" expression