Pyro by Example
Learn Pyro step by step with 50 runnable programs. Every example uses correct Pyro syntax and can be copied straight into the playground.
1. Hello World
The simplest Pyro program. No main function, no imports, no semicolons. Just write code and it runs.
print("Hello, World!")
2. Variables
Bare assignment creates an immutable variable. Use mut for mutable, let for explicit immutable. No type annotations needed.
# Bare assignment — immutable by default
name = "Pyro"
version = 1.0
active = true
# mut — mutable variable
mut counter = 0
counter = counter + 1
print("counter = {counter}")
# let — explicit immutable
let pi = 3.14159
print("name={name}, version={version}, pi={pi}")
3. String Interpolation
Embed variables and expressions inside strings with {var}. No f-prefix like Python — it just works.
name = "Aravind"
lang = "Pyro"
age = 20
# Variable interpolation
print("Hello, {name}!")
print("{name} created {lang}")
# Expression interpolation
print("2 + 2 = {2 + 2}")
print("Next year: {age + 1}")
print("{lang} is {79}x faster!")
4. Functions
Define functions with fn (not def). No colons, no type hints. Indentation-based blocks.
# Simple function
fn add(a, b)
return a + b
print("3 + 5 = {add(3, 5)}")
# Function with default value
fn greet(name, greeting = "Hello")
return "{greeting}, {name}!"
print(greet("World"))
print(greet("Pyro", "Welcome"))
# Functions can call other functions
fn square(x)
return x * x
fn sum_of_squares(a, b)
return square(a) + square(b)
print("3^2 + 4^2 = {sum_of_squares(3, 4)}")
5. If / Else
Conditional blocks use if, elif, else with no colons. Indentation defines the block.
age = 18
if age >= 18
print("You can vote!")
else
print("Too young to vote.")
# elif chains
score = 85
if score >= 90
grade = "A"
elif score >= 80
grade = "B"
elif score >= 70
grade = "C"
else
grade = "F"
print("Score {score} = Grade {grade}")
# Nested conditions
x = 15
if x > 10
if x % 2 == 0
print("{x} is big and even")
else
print("{x} is big and odd")
6. For Loops
Use 0..10 ranges (not range(10)). Iterate over lists directly. No colons needed.
# Range loop: 0..5 gives [0, 1, 2, 3, 4]
for i in 0..5
print("i = {i}")
# Iterate over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits
print("I like {fruit}")
# Accumulator pattern
mut total = 0
for n in 1..11
total = total + n
print("Sum 1..10 = {total}")
7. While Loops
Loop while a condition is true. Use mut for the counter since it changes each iteration.
# Countdown
mut counter = 5
while counter > 0
print("T-minus {counter}")
counter = counter - 1
print("Liftoff!")
# Find first power of 2 above 1000
mut val = 1
while val <= 1000
val = val * 2
print("First power of 2 > 1000: {val}")
8. Lists
Lists are dynamic arrays with built-in methods: push, len, sum, min, max. Zero-indexed.
# Create and access
nums = [10, 20, 30, 40, 50]
print("First: {nums[0]}")
print("Last: {nums[4]}")
# Modify with mut
mut colors = ["red", "green"]
colors.push("blue")
print("Colors: {colors}")
# Built-in aggregations
scores = [95, 87, 92, 78, 100]
print("Length: {scores.len()}")
print("Sum: {scores.sum()}")
print("Min: {scores.min()}")
print("Max: {scores.max()}")
9. Maps / Dicts
Key-value dictionaries with {"key": "value"} syntax. Access with dot or bracket notation.
# Create a map
person = {"name": "Aravind", "age": 20, "lang": "Pyro"}
# Access values
print("Name: {person[\"name\"]}")
print("Age: {person[\"age\"]}")
# Get keys and values
print("Keys: {person.keys()}")
print("Values: {person.values()}")
# Iterate over map
scores = {"math": 95, "science": 88, "english": 92}
for key in scores.keys()
print("{key}: {scores[key]}")
10. Pipes & Lambdas
The pipe operator |> chains data left-to-right. Lambdas use |x| expr syntax — shorter than Python's lambda x:.
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Pipe to filter
evens = nums |> filter(|x| x % 2 == 0)
print("Evens: {evens}")
# Pipe to map
doubled = nums |> map(|x| x * 2)
print("Doubled: {doubled}")
# Chain pipes — reads like English
result = nums |> filter(|x| x > 5)
|> map(|x| x * x)
print("Filter >5, square: {result}")
# Lambda as variable
triple = |x| x * 3
print("7 tripled = {triple(7)}")
11. String Methods
Built-in string methods for transformation, splitting, trimming, replacing, and repeating.
msg = " Hello, Pyro! "
print("upper: {msg.upper()}")
print("lower: {msg.lower()}")
print("trim: [{msg.trim()}]")
print("replace: {msg.trim().replace(\"Pyro\", \"World\")}")
# Split and join
csv = "a,b,c,d,e"
parts = csv.split(",")
print("Split: {parts}")
# Repeat
star = "*".repeat(20)
print(star)
# Contains, starts_with, ends_with
path = "src/main.pyro"
print("Contains main: {path.contains(\"main\")}")
print("Ends with .pyro: {path.ends_with(\".pyro\")}")
12. List Operations
Use map and filter with lambdas to transform and select list elements functionally.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Map: transform every element
squares = numbers |> map(|x| x * x)
print("Squares: {squares}")
# Filter: keep elements matching condition
odds = numbers |> filter(|x| x % 2 != 0)
print("Odds: {odds}")
# Chain: filter then map
result = numbers |> filter(|x| x >= 5)
|> map(|x| x * 10)
print(">=5 then *10: {result}")
# Sorting
names = ["Charlie", "Alice", "Bob"]
print("Sorted: {names.sort()}")
13. Multiline Strings
Triple-quoted strings """...""" preserve newlines and indentation. Great for templates, SQL, and HTML.
# Multiline string
poem = """Roses are red,
Violets are blue,
Pyro is fast,
And elegant too."""
print(poem)
# Interpolation works inside triple-quotes
name = "Pyro"
version = 1.0
info = """
Language: {name}
Version: {version}
Speed: 79x faster than Python
"""
print(info)
14. Error Handling
Use try/catch for error handling and throw to raise errors. No colons.
fn divide(a, b)
if b == 0
throw "Division by zero!"
return a / b
# Safe division
try
result = divide(10, 3)
print("10 / 3 = {result}")
catch e
print("Error: {e}")
# This will throw
try
result = divide(10, 0)
print("Result: {result}")
catch e
print("Caught: {e}")
print("Program continues after error!")
15. Importing Modules
Pyro has 76 built-in modules. Import with import module — no pip install, no package managers.
import math
import time
# Use module functions with dot notation
print("Pi = {math.PI}")
print("sqrt(64) = {math.sqrt(64)}")
# Time module
now = time.now()
print("Timestamp: {now}")
# Benchmark something
start = time.now()
mut sum = 0
for i in 0..100000
sum = sum + i
elapsed = time.now() - start
print("Sum of 0..100k = {sum} in {elapsed} ms")
16. Math Module
Constants, square roots, powers, trig, and random numbers — all built in.
import math
# Constants
print("PI = {math.PI}")
print("E = {math.E}")
print("TAU = {math.TAU}")
# Functions
print("sqrt(144) = {math.sqrt(144)}")
print("pow(2,10) = {math.pow(2, 10)}")
print("abs(-42) = {math.abs(-42)}")
# Trigonometry
print("sin(PI/2) = {math.sin(math.PI / 2)}")
print("cos(0) = {math.cos(0)}")
# Random numbers
print("Random: {math.random()}")
print("Rand 1-100: {math.randint(1, 100)}")
17. JSON Parsing
Parse, stringify, and pretty-print JSON with the built-in json module.
import json
# Parse JSON string to object
raw = "{\"name\": \"Pyro\", \"speed\": 79, \"compiled\": true}"
data = json.parse(raw)
print("Name: {data[\"name\"]}")
print("Speed: {data[\"speed\"]}x")
# Stringify object to JSON
obj = {"lang": "Pyro", "version": 1.0}
print("JSON: {json.stringify(obj)}")
# Pretty print
print("Pretty:")
print(json.pretty(obj))
# Parse array
arr = json.parse("[1, 2, 3, 4, 5]")
print("Array: {arr}")
18. File I/O
Read and write files with the io module. Simple one-liners for common operations.
import io
# Write a file
io.write("hello.txt", "Hello from Pyro!\nLine 2\nLine 3")
print("File written!")
# Read entire file
content = io.read("hello.txt")
print("Content: {content}")
# Read as lines
lines = io.readlines("hello.txt")
print("Lines: {lines}")
print("Line count: {lines.len()}")
# Append to file
io.append("hello.txt", "\nLine 4 appended!")
print(io.read("hello.txt"))
19. Regular Expressions
Pattern matching with the re module — find, match, and replace text.
import re
text = "Call 555-1234 or 555-5678 today!"
# Find all matches
phones = re.find_all("\\d{3}-\\d{4}", text)
print("Phones: {phones}")
# Test if pattern matches
print("Has phone: {re.match(\"\\d{3}-\\d{4}\", text)}")
print("Has email: {re.match(\"@\", text)}")
# Replace with regex
cleaned = re.replace("\\d", text, "#")
print("Cleaned: {cleaned}")
# Extract emails
msg = "Contact us at hello@pyro.dev or support@pyro.dev"
emails = re.find_all("[\\w.]+@[\\w.]+", msg)
print("Emails: {emails}")
20. Testing
Built-in test framework with test.run, test.eq, and test.summary. No pytest needed.
import test
# Define what we're testing
fn add(a, b)
return a + b
fn factorial(n)
if n <= 1
return 1
return n * factorial(n - 1)
# Run tests
test.run("addition", fn()
test.eq(add(2, 3), 5)
test.eq(add(-1, 1), 0)
test.eq(add(0, 0), 0)
)
test.run("factorial", fn()
test.eq(factorial(0), 1)
test.eq(factorial(1), 1)
test.eq(factorial(5), 120)
test.eq(factorial(10), 3628800)
)
test.summary()
21. Web Server
Build a web server with routes and static files using the built-in web module. No Express, no Flask.
import web
# Create a web app
app = web.App()
# Define routes
app.get("/", fn(req, res)
res.send("Hello from Pyro Web!")
)
app.get("/api/status", fn(req, res)
res.json({"status": "ok", "lang": "Pyro"})
)
app.get("/greet/{name}", fn(req, res)
res.send("Hello, {req.params.name}!")
)
# Serve static files
app.static("/public", "./static")
# Start server
app.listen(8080)
print("Server running on http://localhost:8080")
22. Database
SQLite CRUD operations with the built-in db module. No ORM setup, no drivers.
import db
# Connect to SQLite (creates file if needed)
conn = db.connect("app.db")
# Create table
conn.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")
# Insert rows
conn.exec("INSERT INTO users (name, age) VALUES ('Alice', 25)")
conn.exec("INSERT INTO users (name, age) VALUES ('Bob', 30)")
conn.exec("INSERT INTO users (name, age) VALUES ('Charlie', 22)")
print("Inserted 3 users")
# Query
rows = conn.query("SELECT * FROM users")
for row in rows
print("{row}")
# Update
conn.exec("UPDATE users SET age = 26 WHERE name = 'Alice'")
# Count
count = conn.query("SELECT COUNT(*) as total FROM users")
print("Total users: {count}")
conn.close()
23. HTTP Client
Make HTTP requests with the built-in http module. GET, POST, headers, JSON — all included.
import http
# Simple GET request
res = http.get("https://jsonplaceholder.typicode.com/posts/1")
print("Status: {res.status}")
print("Title: {res.json()[\"title\"]}")
# POST request with JSON body
res = http.post("https://jsonplaceholder.typicode.com/posts", {
"title": "Pyro is awesome",
"body": "Built-in HTTP client!",
"userId": 1
})
print("Created post ID: {res.json()[\"id\"]}")
# GET with headers
res = http.get("https://api.github.com", {
"User-Agent": "Pyro/1.0"
})
print("GitHub API status: {res.status}")
24. AI Chat
Built-in AI module for chat, translation, and summarization. Configure a provider first with ai.provider().
import ai
# Configure your AI provider (required)
ai.provider("openai", "sk-your-key")
# Or: ai.provider("ollama", "") # local, no key needed
# Or: ai.provider("gemini", "your-key")
# Chat with AI
response = ai.chat("Explain Pyro in one sentence")
print("AI says: {response}")
# Translate text
spanish = ai.translate("Hello, how are you?", "Spanish")
print("Spanish: {spanish}")
# Summarize text
text = "Pyro is a compiled programming language created by Aravind Pilla. It compiles to native C++ and runs 79x faster than Python."
summary = ai.summarize(text)
print("Summary: {summary}")
25. Machine Learning
Train models with the built-in ml module. Linear regression, prediction, evaluation — no scikit-learn.
import ml
# Dataset: [hours_studied, sleep] -> exam_score
mut ds = ml.Dataset()
ds.X = [[1.0, 8.0], [2.0, 7.0], [3.0, 6.0], [5.0, 6.0], [7.0, 4.0], [8.0, 3.0]]
ds.y = [30.0, 40.0, 50.0, 65.0, 80.0, 85.0]
# Train linear regression
model = ml.linear_regression(ds, 0.01, 2000)
print(model)
# Predict new data
mut new_data = ml.Dataset()
new_data.X = [[4.0, 7.0], [9.0, 2.0]]
preds = model.predict(new_data)
print("Predictions: {preds}")
# Evaluate
print("MSE: {ml.mse(preds, [55.0, 90.0])}")
26. NLP
Natural Language Processing built in. Sentiment analysis, tokenization, keyword extraction — no NLTK or spaCy.
import nlp
text = "Pyro is an amazing programming language. It compiles to C++ and runs incredibly fast."
# Sentiment analysis
print("Sentiment: {nlp.sentiment(text)}")
print("Negative: {nlp.sentiment(\"This is terrible\")}")
# Tokenize
tokens = nlp.tokenize(text)
print("Tokens: {tokens}")
# Keywords (TF-IDF)
kw = nlp.keywords(text, 5)
print("Keywords: {kw}")
# Word count and sentence count
print("Words: {nlp.count_words(text)}")
print("Sentences: {nlp.count_sentences(text)}")
# Similarity
score = nlp.similarity("Pyro is fast", "Pyro has great speed")
print("Similarity: {score}")
27. Visualization
Create charts with the viz module. Bar charts, pie charts, line graphs — rendered natively.
import viz
# Bar chart
viz.bar(
"Programming Languages",
["Pyro", "Python", "Go", "Rust"],
[95, 85, 78, 92]
)
# Pie chart
viz.pie(
"Market Share",
["Chrome", "Firefox", "Safari", "Edge"],
[65, 12, 18, 5]
)
# Line chart
viz.line(
"Growth Over Time",
[1, 2, 3, 4, 5],
[10, 25, 45, 80, 150]
)
print("Charts rendered!")
28. Benchmarking
Measure performance with test.bench. Compare different implementations side by side.
import test
import time
# Iterative fibonacci
fn fib_iter(n)
mut a = 0
mut b = 1
for i in 0..n
mut temp = b
b = a + b
a = temp
return a
# Recursive fibonacci
fn fib_rec(n)
if n <= 1
return n
return fib_rec(n - 1) + fib_rec(n - 2)
# Benchmark both
test.bench("fib_iter(30)", fn()
fib_iter(30)
)
test.bench("fib_rec(30)", fn()
fib_rec(30)
)
# Verify they give same result
print("Iterative: {fib_iter(30)}")
print("Recursive: {fib_rec(30)}")
29. Environment Variables
Access env vars and load .env files with the built-in env module.
import env
# Get environment variable
home = env.get("HOME")
print("Home: {home}")
path = env.get("PATH")
print("Path: {path}")
# Get with default value
port = env.get("PORT", "3000")
print("Port: {port}")
# Load .env file
env.load(".env")
print("Loaded .env file")
# Set environment variable
env.set("APP_NAME", "PyroApp")
print("APP_NAME = {env.get(\"APP_NAME\")}")
# List all env vars
all_vars = env.keys()
print("Total env vars: {all_vars.len()}")
30. Form Validation
Validate user input with the validate module. Email, phone, URL, and custom rules.
import validate
# Email validation
print("Email valid: {validate.email(\"user@pyro.dev\")}")
print("Email valid: {validate.email(\"not-an-email\")}")
# Phone validation
print("Phone valid: {validate.phone(\"+1-555-123-4567\")}")
print("Phone valid: {validate.phone(\"abc\")}")
# URL validation
print("URL valid: {validate.url(\"https://pyro.dev\")}")
print("URL valid: {validate.url(\"not a url\")}")
# Validate a form
form = {
"name": "Aravind",
"email": "aravind@pyro.dev",
"age": 20
}
result = validate.check(form, {
"name": "required|min:2",
"email": "required|email",
"age": "required|min:18"
})
print("Form valid: {result.valid}")
print("Errors: {result.errors}")
31. Structs
Define custom data structures with struct. No type annotations needed. Access fields with dot notation.
# Define a struct
struct User
name
age
active = true
# Create instances
user1 = User("Aravind", 20)
user2 = User("Pyro", 1, false)
print("Name: {user1.name}, Age: {user1.age}")
print("Active: {user1.active}")
print("User2: {user2.name}, active={user2.active}")
# Struct with methods
struct Point
x
y
fn distance(p1, p2)
dx = p1.x - p2.x
dy = p1.y - p2.y
return math.sqrt(dx * dx + dy * dy)
import math
a = Point(0, 0)
b = Point(3, 4)
print("Distance: {distance(a, b)}")
32. Enums
Type-safe enumerations with enum. Use match for exhaustive pattern matching on enum values.
# Define an enum
enum Color
Red
Green
Blue
# Use enum values
favorite = Color.Blue
print("Favorite: {favorite}")
# Pattern matching with match
fn describe(c)
match c
Color.Red -> return "warm"
Color.Green -> return "natural"
Color.Blue -> return "cool"
print("Red is {describe(Color.Red)}")
print("Blue is {describe(Color.Blue)}")
# Enum for state machines
enum Status
Pending
Active
Done
task = Status.Pending
print("Task: {task}")
33. Timing & Performance
Measure execution time with the time module. Pyro compiles to native C++ for maximum speed.
import time
fn compute()
mut sum = 0
for i in 0..1000000
sum = sum + i
return sum
start = time.now()
result = compute()
elapsed = time.now() - start
print("Result: {result}")
print("Time: {elapsed} ms")
print("Native speed!")
34. Message Passing
Use lists as message queues to pass data between functions.
# Simple message queue pattern
mut queue = []
fn produce(q)
for i in 0..5
q.push("msg-{i}")
fn consume(q)
for msg in q
print("Received: {msg}")
produce(queue)
consume(queue)
print("All messages processed")
35. Template Rendering
Render dynamic HTML templates with web.render(). Use {var} placeholders inside templates for server-side rendering.
import web
# HTML template with placeholders
template = """
<html>
<body>
<h1>Welcome, {name}!</h1>
<p>You have {count} notifications.</p>
</body>
</html>
"""
# Render with data
html = web.render(template, {
"name": "Aravind",
"count": 5
})
print(html)
# Use in a web route
mut app = web.app()
app.get("/", fn(req) = web.html(web.render(template, {
"name": req.query("name") ?? "Guest",
"count": 0
})))
print("Template rendered!")
36. REST API
Build a full CRUD API with database persistence. Pyro's web and db modules handle everything.
import web
import db
import json
# Setup database
conn = db.connect(":memory:")
conn.exec("CREATE TABLE todos (id INTEGER PRIMARY KEY, title TEXT, done INTEGER)")
conn.exec("INSERT INTO todos (title, done) VALUES ('Learn Pyro', 0)")
conn.exec("INSERT INTO todos (title, done) VALUES ('Build API', 0)")
# REST routes
mut app = web.app()
# GET all todos
app.get("/api/todos", fn(req)
rows = conn.query("SELECT * FROM todos")
return web.json(json.stringify(rows))
)
# POST create todo
app.post("/api/todos", fn(req)
data = json.parse(req.body)
conn.exec("INSERT INTO todos (title, done) VALUES (?, 0)", [data["title"]])
return web.json("{\"status\": \"created\"}")
)
print("REST API with CRUD operations")
print("GET /api/todos — list all")
print("POST /api/todos — create")
rows = conn.query("SELECT * FROM todos")
for row in rows
print(row)
37. CSV Processing
Read, filter, and transform CSV data with the built-in csv module. No pandas needed.
import csv
# Parse CSV from string
raw = "name,age,city\nAravind,20,Hyderabad\nPyro,1,Cloud\nAlice,30,NYC"
data = csv.parse(raw)
print("Headers: {data[0]}")
print("Rows: {data.len() - 1}")
# Print all rows
for i in 1..data.len()
row = data[i]
print("{row[0]} is {row[1]} from {row[2]}")
# Convert back to CSV string
output = csv.stringify(data)
print("CSV output:")
print(output)
38. Password Hashing
Securely hash and verify passwords with the crypto module. Uses PBKDF2 under the hood via OpenSSL.
import crypto
# Hash a password
password = "super-secret-123"
hashed = crypto.hash_password(password, 10000)
print("Hash: {hashed}")
# Verify password
valid = crypto.verify_password(password, hashed)
print("Valid password: {valid}")
wrong = crypto.verify_password("wrong-password", hashed)
print("Wrong password: {wrong}")
# Other crypto utilities
token = crypto.random_token(32)
print("Token: {token}")
hash256 = crypto.hash_sha256("Pyro")
print("SHA256: {hash256}")
39. JWT Tokens
Create and verify JSON Web Tokens with the auth module. Perfect for API authentication.
import auth
# Create a JWT token
secret = "my-secret-key"
payload = {
"user_id": 42,
"name": "Aravind",
"role": "admin"
}
token = auth.jwt_sign(payload, secret)
print("Token: {token}")
# Verify and decode
decoded = auth.jwt_verify(token, secret)
print("Decoded: {decoded}")
print("User: {decoded[\"name\"]}")
print("Role: {decoded[\"role\"]}")
# Invalid token check
try
auth.jwt_verify("bad-token", secret)
catch e
print("Invalid token: {e}")
40. Rate Limiting
Add rate limiting middleware to your web server. Protect APIs from abuse with built-in rate module.
import web
import rate
mut app = web.app()
# Rate limit: 100 requests per minute per IP
limiter = rate.limiter(100, 60000)
app.use(limiter)
# Protected API routes
app.get("/api/data", fn(req)
return web.json("{\"data\": \"protected\"}")
)
# Stricter limit for auth endpoints
auth_limiter = rate.limiter(5, 60000)
app.post("/api/login", fn(req)
return web.json("{\"status\": \"ok\"}")
)
print("Rate limiting configured:")
print(" /api/data — 100 req/min")
print(" /api/login — 5 req/min")
print("Excess requests get 429 Too Many Requests")
41. File Upload
Handle file I/O with the io and fs modules. Read, write, copy, and manage files easily.
import io
import fs
# Write a file
io.write("/tmp/hello.txt", "Hello from Pyro!\nLine two.")
print("File written!")
# Read it back
content = io.read("/tmp/hello.txt")
print("Content: {content}")
# Read as lines
lines = io.readlines("/tmp/hello.txt")
print("Lines: {lines.len()}")
for line in lines
print(" > {line}")
# Append to file
io.append("/tmp/hello.txt", "\nLine three!")
# File info
print("Exists: {fs.exists(\"/tmp/hello.txt\")}")
print("Size: {fs.size(\"/tmp/hello.txt\")} bytes")
42. Image Processing
Process images with the cv module. Create, transform, and analyze images — no OpenCV install needed.
import cv
# Create a 100x100 red image
img = cv.create(100, 100, 255, 0, 0)
print("Created 100x100 image")
# Draw shapes
cv.fill_rect(img, 10, 10, 30, 30, 0, 255, 0)
cv.draw_rect(img, 50, 50, 40, 40, 0, 0, 255)
print("Drew green filled rect and blue outline")
# Image operations
gray = cv.grayscale(img)
print("Converted to grayscale")
flipped = cv.flip(img, "horizontal")
print("Flipped horizontally")
resized = cv.resize(img, 50, 50)
print("Resized to 50x50")
edges = cv.edges(gray)
print("Edge detection applied")
# Save to file
# cv.save(img, "output.ppm")
print("Image processing complete!")
43. Data Pipeline
Chain data transformations with the |> pipe operator. Build ETL pipelines that read like English.
# Raw sales data
sales = [
{"product": "Widget", "price": 25.0, "qty": 10},
{"product": "Gadget", "price": 50.0, "qty": 3},
{"product": "Gizmo", "price": 15.0, "qty": 20},
{"product": "Widget", "price": 25.0, "qty": 5}
]
# Pipeline: calculate totals with pipes + lambdas
totals = sales |> map(|s| s["price"] * s["qty"])
print("Order totals: {totals}")
# Filter big orders and sum
big_orders = totals |> filter(|t| t > 100)
print("Big orders (>$100): {big_orders}")
# Full pipeline in one chain
revenue = sales
|> map(|s| s["price"] * s["qty"])
|> filter(|t| t > 0)
print("All revenue: {revenue}")
print("Total: ${revenue.sum()}")
44. Websocket Chat
Build real-time messaging with the websocket module. No Socket.IO or external libraries needed.
import web
import websocket
mut app = web.app()
# Create a WebSocket hub for chat
hub = websocket.hub()
# WebSocket endpoint
app.get("/ws", fn(req)
ws = websocket.upgrade(req)
hub.add(ws)
ws.on("message", fn(msg)
# Broadcast to all connected clients
hub.broadcast("User says: {msg}")
)
ws.on("close", fn()
hub.remove(ws)
)
)
# Serve the chat page
app.get("/", fn(req) = web.html("<h1>Pyro Chat</h1>"))
print("WebSocket chat server")
print("Connect to ws://localhost:3000/ws")
print("Messages broadcast to all clients")
45. Cron Jobs
Schedule recurring tasks with time.every() and delayed execution with time.after(). No crontab needed.
import time
# Run a function every 2 seconds, 3 times
mut count = 0
time.every(2000, fn()
count = count + 1
print("Tick {count} at {time.timestamp()}")
, 3)
# Run once after a delay
time.after(1000, fn()
print("Delayed task ran after 1 second")
)
# Timer for measuring performance
timer = time.timer()
mut sum = 0
for i in 0..100000
sum = sum + i
print("Sum: {sum}")
print("Elapsed: {timer.elapsed()} ms")
print("Today: {time.today()}")
print("Now: {time.timestamp()}")
46. CLI Arguments
Build command-line tools with os.args(). Parse flags, options, and positional arguments.
import os
# Get command-line arguments
# Usage: pyro run cli.ro --name Aravind --verbose
args = os.args()
print("Arguments: {args}")
print("Count: {args.len()}")
# Simple flag parser
fn has_flag(args, flag)
for arg in args
if arg == flag
return true
return false
fn get_option(args, key)
for i in 0..args.len()
if args[i] == key
if i + 1 < args.len()
return args[i + 1]
return nil
# Parse flags
verbose = has_flag(args, "--verbose")
name = get_option(args, "--name") ?? "World"
print("Hello, {name}!")
print("Verbose: {verbose}")
print("Platform: {os.platform()}")
print("CPUs: {os.cpus()}")
47. Unit Testing
Write comprehensive tests with test.run(). Assert equality, comparisons, truthiness, and expected failures.
import test
# Test a function
fn factorial(n)
if n <= 1
return 1
return n * factorial(n - 1)
test.run("factorial base cases", fn()
test.eq(factorial(0), 1)
test.eq(factorial(1), 1)
)
test.run("factorial recursive", fn()
test.eq(factorial(5), 120)
test.eq(factorial(10), 3628800)
test.gt(factorial(10), 1000)
)
# Test string operations
test.run("string basics", fn()
name = "Pyro"
test.eq(name.len(), 4)
test.neq(name, "Python")
test.ok(name.len() > 0)
)
# Test list operations
test.run("list operations", fn()
nums = [1, 2, 3, 4, 5]
test.eq(nums.len(), 5)
test.eq(nums.sum(), 15)
test.eq(nums.min(), 1)
test.eq(nums.max(), 5)
)
test.summary()
48. Benchmarking
Measure performance with test.bench(). Compare algorithms and find bottlenecks with nanosecond precision.
import test
import time
# Iterative vs recursive fibonacci
fn fib_recursive(n)
if n <= 1
return n
return fib_recursive(n - 1) + fib_recursive(n - 2)
fn fib_iterative(n)
mut a = 0
mut b = 1
for i in 0..n
temp = a + b
a = b
b = temp
return a
# Verify correctness first
test.run("fib correctness", fn()
test.eq(fib_recursive(10), 55)
test.eq(fib_iterative(10), 55)
)
# Benchmark both approaches
test.bench("fib_recursive(20)", 100, fn() = fib_recursive(20))
test.bench("fib_iterative(20)", 100, fn() = fib_iterative(20))
# Benchmark string operations
test.bench("string concat x1000", 10, fn()
mut s = ""
for i in 0..1000
s = s + "x"
)
test.summary()
49. Error Types
Handle different error types with try/catch. Use throw for custom errors and ?? for nil coalescing.
# Custom error types
fn parse_int(s)
if s == ""
throw "EmptyInput: string is empty"
for c in s
if c < "0" || c > "9"
throw "InvalidChar: '{c}' is not a digit"
return s
# Catch specific errors
try
result = parse_int("42")
print("Parsed: {result}")
catch e
print("Error: {e}")
try
result = parse_int("12x")
catch e
print("Caught: {e}")
try
result = parse_int("")
catch e
print("Caught: {e}")
# Nil coalescing with ??
config = nil
port = config ?? 3000
print("Port: {port}")
# try/catch/finally
try
print("Opening resource...")
throw "ConnectionFailed"
catch e
print("Handling: {e}")
finally
print("Cleanup done")
50. Project Setup
Scaffold a new Pyro project with pyro init. Standard folder structure with config, tests, and entry point.
# Create a new project
# $ pyro init my-app
#
# Creates:
# my-app/
# main.ro # entry point
# pyro.toml # project config
# src/
# lib.ro # library code
# tests/
# test_main.ro # test file
# .gitignore
# main.ro — entry point
print("Welcome to my-app!")
# src/lib.ro — shared functions
fn add(a, b)
return a + b
fn greet(name)
return "Hello, {name}!"
# tests/test_main.ro
import test
test.run("add function", fn()
test.eq(add(2, 3), 5)
test.eq(add(0, 0), 0)
test.eq(add(-1, 1), 0)
)
test.run("greet function", fn()
test.eq(greet("World"), "Hello, World!")
test.eq(greet("Pyro"), "Hello, Pyro!")
)
test.summary()
# Build and run:
# $ pyro run main.ro
# $ pyro build main.ro # creates native binary
# $ pyro test # runs all tests