Skip to content

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 ​

bash
# 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 --version

Verify successful installation:

bash
./target/debug/yaoxiang --version
# Should output something like: yaoxiang x.y.z

Your First Program ​

Create file hello.yx:

yaoxiang
// 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:

bash
./target/debug/yaoxiang hello.yx
# or use release version
./target/release/yaoxiang hello.yx

Output:

Hello, YaoXiang!

Basic Concepts ​

Variables and Types ​

yaoxiang
// 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  // ✅ OK

Functions ​

yaoxiang
// 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 + 1

Type Definitions ​

YaoXiang uses unified name: type = value syntax model:

yaoxiang
// 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.0

Record Types ​

yaoxiang
// 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:

yaoxiang
// 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:

yaoxiang
// 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:

yaoxiang
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 ​

yaoxiang
// 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 ​

yaoxiang
// 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 ​

yaoxiang
// 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 ​

yaoxiang
// 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 ​

yaoxiang
// 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.

yaoxiang
// 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 ​

yaoxiang
// 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? ​

yaoxiang
// Use mut keyword to declare mutable variable
mut x = 10
x = 20  // ✅ OK

Q: How do I define a function? ​

yaoxiang
// Full form (recommended)
add: (a: Int, b: Int) -> Int = a + b

// Short form (type inference)
add = (a, b) => a + b

Q: How do I handle errors? ​

yaoxiang
// 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 ​