"The language where code becomes poetry" - Topaz syntax pursues maximum expressiveness with minimal code. Master Topaz's beautiful syntax in this comprehensive guide. 🌟
🎯 Core Philosophy
"Write Less, Express More"
Even complex logic can be expressed concisely and readably.
Global Syntax, Local Expression
- Keywords: Unified in English (
function,let,match,case) - Identifiers: Free use of any language, English, Unicode, and even emojis
Everything is an Expression
All constructs like if, match, for, try return values.
📝 Basic Syntax
Variable Declaration
// Immutable variables (default)
let name = "Alice"
let age = 25
let isActive = true
// Mutable variables
mut let score = 85
score = 90 // Can be changed
// Type annotation (optional)
let distance: float = 3.14
let users: Array<string> = ["John", "Jane"]
Null‑Coalescing Assignment (??=)
Statement‑only operator that initializes when the target is None/null.
let mut name: Option<string> = None
name ??= Some("guest") // now Some("guest")
Function Definition
// Basic function
function greet(name: string) -> string {
"Hello, {name}!"
}
// Default parameters
function calculate(x: int, y: int = 10) -> int {
x + y
}
// Multiple return values
function getCoordinates() -> (int, int) {
(100, 200)
}
// Higher-order functions
function transform(data: Array<int>, fn: (int) -> int) -> Array<int> {
data.map(fn)
}
Conditionals
// if expression (returns a value)
let message = if age >= 20 {
"You are an adult"
} else if age >= 13 {
"You are a teenager"
} else {
"You are a child"
}
// Ternary-style
let status = if online { "Connected" } else { "Offline" }
Pattern Matching
// Basic matching
let result = match value {
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
case _ => "Other"
}
// Range matching
let grade = match score {
case 90..100 => "A"
case 80..<90 => "B"
case 70..<80 => "C"
case _ => "F"
}
// Structural matching
let discount = match customer {
case { tier: "VIP", amount } if amount > 1000000 => 0.3
case { tier: "VIP" } => 0.2
case { joinDate } if today - joinDate > 365.days => 0.1
case _ => 0.0
}
#### List Patterns
```rust
match xs {
case [head, ..tail] => useHead(head, tail)
case [..init, last] => useLast(init, last)
case [a, .., z] => useEnds(a, z)
case [x, y, ..rest] if rest.length > 0 => handle(x, y, rest)
}
End‑to‑end example (guard + nested list pattern):
let desc = match numbers {
case [] => "empty"
case [single] => "single"
case [first, .., last] if first < last => "ascending edge"
case [first, ..mid, last] => "edges {first}..{last}, mid={mid.length}"
}
## 🌊 Pipeline Operations
### Basic Pipeline
```rust
// Data flows like poetry
let result = rawData
|> normalize()
|> filter(x => x > 0)
|> map(x => x * 2)
|> sort()
Mixed with Method Chaining
let processedString = "hello world"
.split(" ")
|> each(word => word.capitalize())
.join(" ")
|> append("!", _)
// Result: "Hello World!"
Pipe Sugar
v4Use concise sugar on the right side of a pipe:
value
|> .length // property sugar: (x => x.length)
|> replace("foo", _, "bar") // method sugar: (x => replace("foo", x, "bar"))
// Multiple placeholders bind left-to-right within the nearest call
value |> format("id=", _, ":", _)
🧠 Type System
Type Inference
// Types are automatically inferred
let number = 42 // int
let text = "hello" // string
let array = [1, 2, 3, 4] // Array<int>
let object = { // { name: string, age: int }
name: "Alice",
age: 25
}
Literal Types
// Restrict types to exact values
type TrafficLight = "red" | "yellow" | "green"
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6
type StatusCode = 200 | 404 | 500
function handleSignal(color: TrafficLight) {
match color {
case "red" => stop()
case "yellow" => caution()
case "green" => go()
// Compiler ensures all cases are handled!
}
}
Union Types
type UserInput = string | int | null
function process(input: UserInput) -> string {
match input {
case s: string => "String: {s}"
case n: int => "Number: {n}"
case null => "No input"
}
}
🔁 Loops
for Loops (Expressions)
// Range iteration
for i in 1..10 {
print("Number: {i}")
}
// Array iteration
for item in ["apple", "banana", "cherry"] {
print("Fruit: {item}")
}
// With index
for (index, value) in data.enumerate() {
print("{index}: {value}")
}
// for returns values too!
let squares = for x in 1..5 { x * x } // [1, 4, 9, 16]
Range step with by
v4
// Step forward
for i in 0..10 by 2 { print(i) } // 0,2,4,6,8,10
// Step backward with negative stride
for i in 10..0 by -3 { print(i) } // 10,7,4,1
// Date/Time step (library-defined durations)
for day in startDate..endDate by 1.day { schedule.add(day) }
while Loops
mut let counter = 0
while counter < 10 {
print("Counter: {counter}")
counter = counter + 1
}
📚 Collections
Arrays
// Basic arrays
let numbers = [1, 2, 3, 4, 5]
let fruits = ["apple", "banana", "cherry"]
// Array methods
let large = numbers.filter(x => x > 2) // [3, 4, 5]
let squares = numbers.map(x => x * x) // [1, 4, 9, 16, 25]
let sum = numbers.reduce(0, +) // 15
Membership (in)
// Arrays/Lists/Sets
let ok1 = 3 in [1, 2, 3]
let ok2 = "a" in Set.of("a", "b")
// Map keys
let hasId = "id" in userMap.keys
// Ranges
let inside = 5 in 1..10
let outside = 10 in 1..<10
Objects/Structs
// Object literal
let user = {
name: "Alice",
age: 25,
email: "alice@example.com"
}
// Struct definition
struct User {
name: string,
age: int,
email: string
}
// Struct instance
let newUser = User {
name: "Bob",
age: 30,
email: "bob@example.com"
}
Record Update Literal
v4Shallow‑copy a record and update selected fields immutably.
let user = { name: "Alice", age: 20, city: "Seoul" }
let updated = user{ age: user.age + 1, city: "Busan" }
// { name: "Alice", age: 21, city: "Busan" }
🎭 String Templates
Basic Interpolation
let name = "Alice"
let age = 25
let greeting = "Hello, {name}! You are {age} years old."
Tagged Templates
v4Standardized tags with safety and meta preservation:
let path = p"/home/{user}/docs/{fileName}" // path normalization
let pattern = r"^[a-z0-9_]+$" // regex with light escapes
let cmd = sh"grep {pattern} {file}" // safe shell template (execution policy‑controlled)
// SQL: parameters are always bound (no raw string insertion)
let query = sql"SELECT * FROM users WHERE age > {age} AND city = {city}"
⚡ Async Processing
Automatic Async
// I/O is automatically async but written like sync!
function getUserInfo(id: int) -> User {
let basicInfo = API.fetchUser(id) // implicit async handling
let profile = API.fetchProfile(id) // implicit async handling
User {
basicInfo: basicInfo,
profile: profile
}
}
Parallel Execution
// Run multiple tasks in parallel
let results = concurrent {
weather: WeatherAPI.current("NYC"),
rate: CurrencyAPI.usdRate(),
news: NewsAPI.headlines(5)
}
🛡️ Error Handling
Result Type
function safeDivide(a: int, b: int) -> Result<int, string> {
if b == 0 {
Err("Cannot divide by zero")
} else {
Ok(a / b)
}
}
// Simple with ? operator
function complexCalculation(x: int) -> Result<int, string> {
let result1 = safeDivide(x, 2)?
let result2 = safeDivide(result1, 3)?
Ok(result2 * 10)
}
try Expression
let config = try {
readFile("config.json")?
} else {
// Return default value
{ theme: "dark", language: "english" }
}
🎨 Advanced Features
Partial Application
let add10 = add(10, _)
let result = [1, 2, 3].map(add10) // [11, 12, 13]
Option‑Safe Optional Chaining (?.)
v4Use ?. only when the left side is Option<T> or a nullable union (e.g., T | null). It desugars to Option.map/flatMap and short‑circuits left‑to‑right.
let user: Option<{ name: string, profile: Option<{ city: string }> }> =
Some({ name: "Ann", profile: Some({ city: "Seoul" }) })
// Each hop returns Option<...>
let nameOpt = user?.name
let cityOpt = user?.profile?.city
// Combine with ?? for defaults
let city = user?.profile?.city ?? "Unknown"
// Not generic object chaining; use `.` for non‑Option values
let plain = { name: "Jo" }
let ok = plain.name // use .
Equivalence with map/flatMap:
// user?.profile?.city
let viaFns = user
|> Option.flatMap(_, u => u.profile)
|> Option.map(_, p => p.city)
Macros
// Repeat execution macro
macro repeatExecution(times: int) {
for i in 1..times {
print("Execution {i}/{times}")
yield // Execute user code
}
}
repeatExecution(3) {
importantTask()
}
�� Practical Examples
Web API Call
let userData = fetch("https://api.example.com/users/1")
|> json()
|> (data => {
name: data.name,
email: data.email,
joinDate: Date.parse(data.created_at)
})
Data Processing Pipeline
let analysisResult = CSV.read("sales.csv")
|> filter(row => row.revenue > 1000000)
|> groupBy(row => row.region)
|> aggregate(group => {
region: group.key,
totalRevenue: group.values.sum(row => row.revenue),
avgRevenue: group.values.average(row => row.revenue)
})
|> sortBy(descending: row => row.totalRevenue)
🎯 Next Steps
You've now mastered Topaz's basic syntax! What to learn next:
- Data Types - Deep dive into the type system
- Functions & Closures - Master functional programming
- Error Handling - Write safe, robust code
Continue your journey where coding becomes poetry with Topaz! ✨