YaoXiang Quick Start
This guide helps you get started with YaoXiang programming language.
Note: Code examples in this document are written based on YaoXiang language specification. If you encounter syntax differences in actual execution, please refer to Language Specification.
Installation
Build from Source (Recommended)
# Clone repository
git clone https://github.com/ChenXu233/YaoXiang.git
cd yaoxiang
# Build (debug version, for development testing)
cargo build
# Build (release version, recommended for production)
cargo build --release
# Run tests
cargo test
# Check version
./target/debug/yaoxiang --version
# or
./target/release/yaoxiang --versionVerify successful installation:
./target/debug/yaoxiang --version
# Should output something like: yaoxiang x.y.zYour First Program
Create file hello.yx:
// hello.yx
use std.io
// Function definition: name: (param: Type, ...) -> return_type = { return ... } # code block must explicitly return
// Expression form: name: (param: Type, ...) -> return_type = expr # expression returns value directly
main: () -> Void = {
print("Hello, YaoXiang!")
}Run:
./target/debug/yaoxiang hello.yx
# or use release version
./target/release/yaoxiang hello.yxOutput:
Hello, YaoXiang!Basic Concepts
Variables and Types
// Automatic type inference
x = 42 // inferred as Int
name = "YaoXiang" // inferred as String
pi = 3.14159 // inferred as Float
is_valid = true // inferred as Bool
// Explicit type annotation (recommended to use type-centric convention)
count: Int = 100
// Immutable by default (safety feature)
x = 10
x = 20 // ❌ Compile error! Immutable
// Mutable variable (requires explicit declaration)
mut counter = 0
counter = counter + 1 // ✅ OKFunctions
// Function definition syntax
// Expression form: return value directly, no return needed
add: (a: Int, b: Int) -> Int = a + b
// Code block form: must use return to return value
// add: (a: Int, b: Int) -> Int = { return a + b }
// Call
result = add(1, 2) // result = 3
// Single parameter function (expression form)
inc: (x: Int) -> Int = x + 1Type Definitions
YaoXiang uses unified name: type = value syntax model:
// Variable declaration
x: Int = 42
name: String = "YaoXiang"
// Function definition
add: (a: Int, b: Int) -> Int = a + b
// Type definition (using braces)
Point: Type = { x: Float, y: Float }
// Use type
p: Point = Point(x=1.0, y=2.0)
p.x // 1.0
p.y // 2.0Record Types
// Struct type
Point: Type = { x: Float, y: Float }
Rect: Type = { x: Float, y: Float, width: Float, height: Float }
// Usage
p = Point(x=3.0, y=4.0)
r = Rect(x=0.0, y=0.0, width=10.0, height=20.0)Interface Definitions
Interfaces are record types with all function fields:
// Define interface
Drawable: Type = {
draw: (Surface) -> Void,
bounding_box: () -> Rect
}
Serializable: Type = {
serialize: () -> String
}
// Empty interface
EmptyInterface: Type = {}Type Methods
Use Type.method: (Type, ...) -> Return = ... syntax to define type methods:
// Type definition
Point: Type = { x: Float, y: Float }
// Type method definition
Point.draw: (self: Point, surface: Surface) -> Void = {
surface.plot(self.x, self.y)
}
Point.serialize: (self: Point) -> String = {
"Point({self.x}, {self.y})"
}
// Use methods (syntactic sugar)
p = Point(x=1.0, y=2.0)
p.draw(screen) // → Point.draw(p, screen)
str = p.serialize() // → Point.serialize(p)Automatic Binding
Functions declared with pub keyword automatically bind to types defined in the same file:
Point: Type = { x: Float, y: Float }
// pub declaration automatically binds to Point
pub distance: (p1: Point, p2: Point) -> Float = {
dx = p1.x - p2.x
dy = p1.y - p2.y
(dx * dx + dy * dy).sqrt()
}
// Usage
p1 = Point(x=3.0, y=4.0)
p2 = Point(x=1.0, y=2.0)
// Functional call
d = distance(p1, p2) // 3.606...
// OOP syntactic sugar (auto-binds to Point.distance)
d2 = p1.distance(p2) // → distance(p1, p2)Enum Types
// Simple enum
Color: Type = { red: () -> Color, green: () -> Color, blue: () -> Color }
// Enum with data
Result: (T: Type, E: Type) -> Type = { ok: (T) -> Result(T, E), err: (E) -> Result(T, E) }
// Using generics
success: Result(Int, String) = ok(42)
failure: Result(Int, String) = err("not found")Generic Types
// Generic type definition
List: (T: Type) -> Type = {
data: Array(T),
length: Int,
push: (List(T), T) -> Void
}
// Concrete instantiation
IntList: Type = List(Int)
StringList: Type = List(String)Control Flow
// Conditional expression
if x > 0 {
"positive"
} else if x == 0 {
"zero"
} else {
"negative"
}
// Loop
for i in 0..5 {
print(i)
}
// while loop
mut n = 0
while n < 5 {
print(n)
n = n + 1
}Lists and Dictionaries
// Lists
numbers = [1, 2, 3, 4, 5]
first = numbers[0] // 1
// Dictionaries
scores = {"Alice": 90, "Bob": 85}
alice_score = scores["Alice"] // 90
// Add elements
mut list = [1, 2, 3]
list.append(4)Pattern Matching
// match expression
result: Result(Int, String) = ok(42)
message = match result {
ok(value) => "Success: " + value.to_string()
err(error) => "Error: " + error
}Spawn Programming (Concurrency)
YaoXiang's concurrency model builds around the spawn <expr> primitive — the sole entry point for parallelism.
// spawn can decorate any expression, executed in parallel automatically
main: () -> Void = {
user = spawn fetch_user(1) // executes in background
posts = spawn fetch_posts() // another parallel step
// automatically blocks waiting for result when needed
print(user.name)
print(posts.length)
}Core rule: Expressions decorated with spawn execute in background, and the outer scope synchronously blocks waiting for results. Independent tasks automatically run in parallel, scheduled by the runtime's GMP model.
Module System
// Import standard library
use std.io
use std.math
// Use imported functions
result = math.sqrt(16) // 4.0
print("Hello!")FAQ
Q: Variables are immutable by default, how do I modify a variable?
// Use mut keyword to declare mutable variable
mut x = 10
x = 20 // ✅ OKQ: How do I define a function?
// Full form (recommended)
add: (a: Int, b: Int) -> Int = a + b
// Short form (type inference)
add = (a, b) => a + bQ: How do I handle errors?
// Use Result type
Result: (T: Type, E: Type) -> Type = { ok(T) | err(E) }
// Handle with pattern matching
result = risky_operation()
match result {
ok(value) => print("Success: " + value)
err(error) => print("Error: " + error)
}Next Steps
- 📚 Check out Language Specification for complete syntax
- 🏗️ Browse Architecture Documentation for implementation details
- 💡 Read Design Manifesto for core philosophy
