📚 AetherShell Tutorial
Learn AetherShell from basics to advanced features
Lesson 1: Basics
1.1 Variables and Values
AetherShell uses immutable bindings by default. Use = for immutable,
:= for mutable.
// Immutable binding (cannot be reassigned)
x = 10
print(x) // 10
// Mutable binding (can be reassigned)
y := 20
y = 30
print(y) // 30
// String values
name = "Alice"
greeting = "Hello, ${name}!"
print(greeting) // "Hello, Alice!"
1.2 Basic Types
// Numbers
integer = 42 // Int
floating = 3.14 // Float
// Strings
text = "Hello" // Str
// Booleans
flag = true // Bool
condition = false // Bool
// Arrays
numbers = [1, 2, 3] // Array
mixed = [1, "two", 3] // Arrays can be heterogeneous
// Null
nothing = null // Null
1.3 Operators
// Arithmetic
10 + 5 // 15
10 - 5 // 5
10 * 5 // 50
10 / 5 // 2
10 % 3 // 1
// Comparison
10 == 10 // true
10 != 5 // true
10 > 5 // true
10 < 20 // true
10 >= 10 // true
10 <= 10 // true
// Logical
true && false // false
true || false // true
!true // false
// String concatenation
"Hello" + " " + "World" // "Hello World"
Exercise: Try calculating the area of a circle with radius 5 using
pi = 3.14.
Lesson 2: Pipelines - The Heart of AetherShell
2.1 What are Pipelines?
Pipelines let you chain operations together, passing data from left to right using the |
operator.
// Simple pipeline
[1, 2, 3] | print
// Multi-step pipeline
[1, 2, 3, 4, 5]
| map(fn(x) => x * 2) // [2, 4, 6, 8, 10]
| where(fn(x) => x > 5) // [6, 8, 10]
| reduce(fn(a,b) => a+b, 0) // 24
| print
2.2 Pipeline with map
// Double all numbers
[1, 2, 3] | map(fn(x) => x * 2)
// Result: [2, 4, 6]
// Square all numbers
range(1, 6) | map(fn(n) => n * n)
// Result: [1, 4, 9, 16, 25]
// Convert to uppercase
["hello", "world"] | map(fn(s) => upper(s))
// Result: ["HELLO", "WORLD"]
2.3 Pipeline with where (filter)
// Filter even numbers
[1, 2, 3, 4, 5, 6] | where(fn(x) => x % 2 == 0)
// Result: [2, 4, 6]
// Filter long strings
["a", "bb", "ccc"] | where(fn(s) => len(s) > 1)
// Result: ["bb", "ccc"]
2.4 Pipeline with reduce
// Sum of array
[1, 2, 3, 4, 5] | reduce(fn(a, b) => a + b, 0)
// Result: 15
// Product of array
[1, 2, 3, 4] | reduce(fn(a, b) => a * b, 1)
// Result: 24
// Find maximum
[3, 7, 2, 9, 1] | reduce(fn(a, b) => max(a, b), 0)
// Result: 9
2.5 Complex Pipeline Example
// Calculate sum of squares of even numbers from 1-10
range(1, 11)
| where(fn(x) => x % 2 == 0) // [2, 4, 6, 8, 10]
| map(fn(x) => x * x) // [4, 16, 36, 64, 100]
| reduce(fn(acc, val) => acc + val, 0) // 220
| print
Exercise: Create a pipeline that finds all odd numbers from 1-20, triples them, and
sums the result.
Lesson 3: Functions
3.1 Lambda Syntax
// Single parameter
double = fn(x) => x * 2
print(double(5)) // 10
// Multiple parameters
add = fn(a, b) => a + b
multiply = fn(a, b) => a * b
print(add(3, 4)) // 7
print(multiply(3, 4)) // 12
// No parameters
get_pi = fn() => 3.14159
print(get_pi()) // 3.14159
3.2 Functions in Pipelines
// Inline functions
[1, 2, 3] | map(fn(x) => x * x)
// Named functions
square = fn(x) => x * x
[1, 2, 3] | map(square)
// Both work the same!
3.3 Higher-Order Functions
// Function that returns a function
make_adder = fn(n) => fn(x) => x + n
add5 = make_adder(5)
add10 = make_adder(10)
print(add5(3)) // 8
print(add10(3)) // 13
// Function composition
compose = fn(f, g) => fn(x) => f(g(x))
times2 = fn(x) => x * 2
plus3 = fn(x) => x + 3
times2_then_plus3 = compose(plus3, times2)
print(times2_then_plus3(5)) // 13 (5*2=10, 10+3=13)
Pro Tip: AetherShell supports closures - functions can capture variables from their
enclosing scope!
Lesson 4: Type System
4.1 Type Inference
AetherShell uses Hindley-Milner type inference. Types are automatically inferred!
// Types are inferred, not declared
x = 42 // Inferred as Int
y = 3.14 // Inferred as Float
s = "hello" // Inferred as Str
arr = [1, 2, 3] // Inferred as Array
// Check types at runtime
print(type_of(x)) // "Int"
print(type_of(y)) // "Float"
print(type_of(s)) // "Str"
print(type_of(arr)) // "Array"
4.2 Structured Types
// Records (like objects/structs)
person = {
name: "Alice",
age: 30,
active: true
}
print(person.name) // "Alice"
print(person.age) // 30
// Arrays of records
users = [
{name: "Alice", age: 30},
{name: "Bob", age: 25},
{name: "Charlie", age: 35}
]
// Filter and transform
adults = users | where(fn(u) => u.age >= 30)
names = adults | map(fn(u) => u.name)
4.3 Type Safety
// Operations must be type-compatible
x = 10
// x + "hello" // Error: cannot add Int and Str
// But you can convert types
num_str = "42"
// num = parse_int(num_str) // Convert string to int
Lesson 5: Records & Tables
5.1 Working with Records
// Create a record
user = {
id: 1,
name: "Alice",
email: "alice@example.com",
roles: ["admin", "user"]
}
// Access fields
print(user.name) // "Alice"
print(user.roles) // ["admin", "user"]
// Get all keys
keys(user) // ["id", "name", "email", "roles"]
5.2 Tables (Arrays of Records)
// File listings are tables!
files = ls(".")
// Filter large files
large_files = files | where(fn(f) => f.size > 10000)
// Get just names
file_names = large_files | map(fn(f) => f.name)
// Count files
total = files | len
print("Total files: ${total}")
5.3 Table Transformations
// Create a table
products = [
{name: "Laptop", price: 999, stock: 5},
{name: "Mouse", price: 25, stock: 50},
{name: "Keyboard", price: 75, stock: 20}
]
// Find expensive items
expensive = products | where(fn(p) => p.price > 50)
// Calculate total value
total_value = products
| map(fn(p) => p.price * p.stock)
| reduce(fn(a, b) => a + b, 0)
print("Total inventory value: $${total_value}")
Lesson 6: File Operations
6.1 Listing Files
// List current directory
files = ls(".")
print(files)
// Filter by type
dirs = files | where(fn(f) => f.type == "directory")
regular = files | where(fn(f) => f.type == "file")
6.2 Reading Files
// Read entire file
content = cat("README.md")
print(content)
// Read first 10 lines
preview = head("README.md", 10)
// Read last 10 lines
tail_lines = tail("logfile.txt", 10)
6.3 Searching Files
// Find all Rust files
rust_files = find(".", "*.rs")
print(rust_files)
// Search file content
matches = grep("README.md", "AetherShell")
print(matches)
6.4 Processing Text Files
// Read file and process lines
cat("data.csv")
| split("\n") // Split into lines
| where(fn(line) => len(line) > 0) // Remove empty lines
| map(fn(line) => split(line, ",")) // Split each line by comma
| print
Lesson 7: AI Basics
7.1 Simple AI Agent
// Deploy an agent with a goal
result = agent("Count all .rs files in src/", "ls,find", 5)
print(result)
7.2 AgenticBinary Protocol
// Encode a message
ping_msg = ab_encode("command", "ping", "hello")
print(ping_msg) // [0, 5, 104, 101, 108, 108, 111]
// Decode the message
decoded = ab_decode(ping_msg)
print(decoded.msg_type) // "Command"
print(decoded.opcode) // "PING"
print(decoded.payload) // "hello"
7.3 All Message Types
// Command messages
cmd = ab_encode("command", "exec", "run_task")
// Query messages
query = ab_encode("query", "query", "get_status")
// Response messages
resp = ab_encode("response", "ack", "received")
// Event messages
event = ab_encode("event", "sync", "state_update")
Note: AI features require setting up environment variables like
OPENAI_API_KEY or running local models with Ollama.
Lesson 8: Multi-Agent Systems
8.1 Agent Communication
// Worker registers with coordinator
worker_ready = ab_encode("response", "ack", "worker1:ready")
// Coordinator delegates task
task = ab_encode("command", "delegate", "analyze_logs")
// Worker executes
exec = ab_encode("command", "exec", "started:analysis")
// Worker reports result
result = ab_encode("response", "data", "analysis_complete")
8.2 Agent Collaboration
// Agent requests help
collab_req = ab_encode("command", "collaborate", "agent2:need_data")
// Agent shares knowledge
learn_msg = ab_encode("command", "learn", "protocol:new_syntax")
// Agent acknowledges learning
ack = ab_encode("response", "ack", "learned:new_syntax")
8.3 Error Handling
// Agent encounters error
error = ab_encode("response", "error", "task_failed:timeout")
// Coordinator reassigns
retry = ab_encode("command", "delegate", "retry_task")
Lesson 9: Syntax Knowledge Base
9.1 Discovering Protocols
// List all available protocols
protocols = syntax_list("protocol")
print(protocols) // ["ab", "jsonrpc", "http"]
// Get protocol details
ab_spec = syntax_get("ab")
print(ab_spec.name) // "AgenticBinary Protocol"
print(ab_spec.specification) // Full spec...
9.2 Searching Syntax
// Search for binary-related syntax
results = syntax_search("binary")
print(results) // ["ab"]
// Search for all protocols
all_protos = syntax_search("protocol")
print(all_protos)
9.3 Adding Custom Syntax
// Define custom protocol
my_protocol = {
id: "myproto",
name: "My Custom Protocol",
category: "protocol",
specification: "Custom communication protocol...",
examples: ["example 1", "example 2"]
}
// Add to knowledge base
syntax_add(my_protocol)
// Retrieve it later
retrieved = syntax_get("myproto")
print(retrieved.name) // "My Custom Protocol"
Lesson 10: Advanced Patterns
10.1 Factorial with Reduce
// Calculate 5! = 120
factorial = fn(n) =>
range(1, n + 1)
| reduce(fn(a, b) => a * b, 1)
print(factorial(5)) // 120
print(factorial(10)) // 3628800
10.2 Fibonacci Sequence
// Generate first N fibonacci numbers
fib = fn(n) => {
a := 0
b := 1
result := [0, 1]
i := 2
while (i < n) {
next = a + b
result = push(result, next)
a = b
b = next
i = i + 1
}
result
}
print(fib(10)) // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
10.3 Data Processing Pipeline
// Process CSV data
cat("data.csv")
| split("\n") // Lines
| where(fn(line) => len(line) > 0) // Non-empty
| map(fn(line) => split(line, ",")) // Parse CSV
| where(fn(row) => len(row) > 2) // Valid rows
| map(fn(row) => { // Extract fields
name: row[0],
age: row[1],
city: row[2]
})
| where(fn(person) => person.age > "30") // Filter
| map(fn(p) => p.name) // Get names
| print
10.4 Multi-Agent Task Distribution
// Complete workflow example
// See examples/13_agent_coordination.ae for full implementation
// 1. Workers learn protocol
spec = syntax_get("ab")
// 2. Workers signal ready
worker1_ready = ab_encode("response", "ack", "worker1:ready")
// 3. Coordinator delegates tasks
task1 = ab_encode("command", "delegate", "analyze_data")
task2 = ab_encode("command", "delegate", "process_logs")
// 4. Workers execute and report
exec1 = ab_encode("command", "exec", "started:analyze")
result1 = ab_encode("response", "data", "complete:results.json")
// 5. Coordinator reflects
reflection = ab_encode("command", "reflect", "efficiency:95%")
🎓 Congratulations!
You've completed the AetherShell tutorial! You now know:
- ✅ Basic syntax and types
- ✅ Powerful pipeline operations
- ✅ Functional programming with lambdas
- ✅ Type system and type inference
- ✅ Records and table processing
- ✅ File operations
- ✅ AI agent integration
- ✅ Multi-agent coordination
- ✅ Syntax Knowledge Base
- ✅ Advanced patterns