1.5 WASM Arrays & Linear Memory
Foundation: Collections, Memory Layout, and High-Performance Data Structures
Master WASM arrays and linear memory management with Ruchy’s collection types. This section covers array operations, memory-efficient data structures, and optimized collection processing that leverages WebAssembly’s linear memory model.
Learning Objectives
- Master WASM linear memory and array representation
 - Implement high-performance array operations
 - Build memory-efficient data structures for WASM
 - Optimize collection processing for cross-platform deployment
 - Handle dynamic arrays and fixed-size buffers
 
WASM Linear Memory Fundamentals
Array Memory Layout
// WASM arrays are stored in linear memory as contiguous data blocks
// Layout: [length: i32][capacity: i32][data: T...]
fun demonstrate_array_memory() {
    // Fixed-size arrays (stack allocated in WASM)
    let numbers: [i32; 5] = [1, 2, 3, 4, 5];
    let floats: [f64; 3] = [3.14, 2.71, 1.41];
    
    // Dynamic arrays (heap allocated in WASM linear memory)
    let mut dynamic: Vec<i32> = vec![10, 20, 30];
    let mut strings: Vec<String> = vec!["hello".to_string(), "world".to_string()];
    
    println("WASM Array Memory Layout:");
    println(f"Fixed array length: {numbers.len()}");
    println(f"Dynamic array length: {dynamic.len()}");
    println(f"Dynamic array capacity: {dynamic.capacity()}");
    
    // Memory-efficient operations
    dynamic.push(40);  // May trigger reallocation
    dynamic.push(50);
    
    println(f"After push operations: len={dynamic.len()}, cap={dynamic.capacity()}");
    
    // Direct memory access patterns
    for (index, value) in numbers.iter().enumerate() {
        println(f"Index {index}: {value}");
    }
}
Linear Memory Optimization
// Memory-aligned data structures for WASM performance
struct Point2D {
    x: f32,  // 4 bytes
    y: f32,  // 4 bytes
}           // Total: 8 bytes aligned
struct Point3D {
    x: f64,  // 8 bytes
    y: f64,  // 8 bytes  
    z: f64,  // 8 bytes
}           // Total: 24 bytes aligned
fun linear_memory_optimization() {
    println("Linear Memory Optimization:");
    
    // Efficient array of structs (Array of Structures - AoS)
    let mut points_2d: Vec<Point2D> = Vec::new();
    points_2d.push(Point2D { x: 1.0, y: 2.0 });
    points_2d.push(Point2D { x: 3.0, y: 4.0 });
    points_2d.push(Point2D { x: 5.0, y: 6.0 });
    
    // Structure of Arrays (SoA) for vectorization
    let mut x_coords: Vec<f32> = vec![1.0, 3.0, 5.0];
    let mut y_coords: Vec<f32> = vec![2.0, 4.0, 6.0];
    
    println(f"AoS: {points_2d.len()} points");
    println(f"SoA: {x_coords.len()} x-coords, {y_coords.len()} y-coords");
    
    // Memory-efficient batch operations
    for point in &mut points_2d {
        point.x = point.x * 2.0;
        point.y = point.y * 2.0;
    }
    
    // Vectorized operations on SoA
    for x in &mut x_coords {
        *x = *x * 2.0;
    }
    for y in &mut y_coords {
        *y = *y * 2.0;
    }
    
    println("Memory layout optimized for WASM linear memory access");
}
High-Performance Array Operations
Core Array Algorithms
// WASM-optimized array algorithms
fun array_sum(arr: &[i32]) -> i32 {
    let mut sum = 0;
    for &value in arr {
        sum = sum + value;
    }
    sum
}
fun array_product(arr: &[i32]) -> i64 {
    let mut product: i64 = 1;
    for &value in arr {
        product = product * (value as i64);
    }
    product
}
fun array_max(arr: &[i32]) -> Option<i32> {
    if arr.is_empty() {
        return None;
    }
    
    let mut max = arr[0];
    for &value in &arr[1..] {
        if value > max {
            max = value;
        }
    }
    Some(max)
}
fun array_min(arr: &[i32]) -> Option<i32> {
    if arr.is_empty() {
        return None;
    }
    
    let mut min = arr[0];
    for &value in &arr[1..] {
        if value < min {
            min = value;
        }
    }
    Some(min)
}
fun array_search(arr: &[i32], target: i32) -> Option<usize> {
    for (index, &value) in arr.iter().enumerate() {
        if value == target {
            return Some(index);
        }
    }
    None
}
fun core_array_operations() {
    println("High-Performance Array Operations:");
    
    let numbers = [1, 5, 3, 8, 2, 7, 4, 6];
    
    let sum = array_sum(&numbers);
    let product = array_product(&numbers);
    let max = array_max(&numbers);
    let min = array_min(&numbers);
    let search_result = array_search(&numbers, 7);
    
    println(f"Sum: {sum}");
    println(f"Product: {product}");
    println(f"Max: {max:?}");
    println(f"Min: {min:?}");
    println(f"Search for 7: {search_result:?}");
}
Sorting Algorithms for WASM
// Memory-efficient sorting algorithms optimized for WASM
fun bubble_sort(arr: &mut [i32]) {
    let len = arr.len();
    for i in 0..len {
        for j in 0..(len - 1 - i) {
            if arr[j] > arr[j + 1] {
                let temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
fun insertion_sort(arr: &mut [i32]) {
    let len = arr.len();
    for i in 1..len {
        let key = arr[i];
        let mut j = i;
        
        while j > 0 && arr[j - 1] > key {
            arr[j] = arr[j - 1];
            j = j - 1;
        }
        arr[j] = key;
    }
}
fun selection_sort(arr: &mut [i32]) {
    let len = arr.len();
    for i in 0..len {
        let mut min_idx = i;
        
        for j in (i + 1)..len {
            if arr[j] < arr[min_idx] {
                min_idx = j;
            }
        }
        
        if min_idx != i {
            let temp = arr[i];
            arr[i] = arr[min_idx];
            arr[min_idx] = temp;
        }
    }
}
// Quick sort with WASM-optimized partitioning
fun quicksort(arr: &mut [i32], low: usize, high: usize) {
    if low < high {
        let pivot = partition(arr, low, high);
        
        if pivot > 0 {
            quicksort(arr, low, pivot - 1);
        }
        quicksort(arr, pivot + 1, high);
    }
}
fun partition(arr: &mut [i32], low: usize, high: usize) -> usize {
    let pivot = arr[high];
    let mut i = low;
    
    for j in low..high {
        if arr[j] < pivot {
            let temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i = i + 1;
        }
    }
    
    let temp = arr[i];
    arr[i] = arr[high];
    arr[high] = temp;
    
    i
}
fun sorting_algorithms_demo() {
    println("WASM-Optimized Sorting Algorithms:");
    
    // Test different sorting algorithms
    let original = [64, 34, 25, 12, 22, 11, 90, 88, 76, 50];
    
    // Bubble sort
    let mut bubble_data = original;
    bubble_sort(&mut bubble_data);
    println(f"Bubble sort: {:?}", bubble_data);
    
    // Insertion sort  
    let mut insertion_data = original;
    insertion_sort(&mut insertion_data);
    println(f"Insertion sort: {:?}", insertion_data);
    
    // Selection sort
    let mut selection_data = original;
    selection_sort(&mut selection_data);
    println(f"Selection sort: {:?}", selection_data);
    
    // Quick sort
    let mut quick_data = original;
    let len = quick_data.len();
    if len > 0 {
        quicksort(&mut quick_data, 0, len - 1);
    }
    println(f"Quick sort: {:?}", quick_data);
}
Dynamic Arrays and Collections
Vector Operations
// WASM-optimized dynamic array operations
fun vector_operations_demo() {
    println("Dynamic Vector Operations:");
    
    // Creation and initialization
    let mut numbers: Vec<i32> = Vec::new();
    let mut primes: Vec<i32> = vec![2, 3, 5, 7, 11];
    let mut zeros: Vec<i32> = vec![0; 10]; // 10 zeros
    
    // Push operations (may trigger reallocation)
    for i in 1..=10 {
        numbers.push(i * i); // Square numbers
    }
    
    println(f"Numbers: {:?}", numbers);
    println(f"Primes: {:?}", primes);
    println(f"Zeros length: {zeros.len()}");
    
    // Pop operations
    let last = numbers.pop();
    println(f"Popped: {last:?}");
    println(f"After pop: {:?}", numbers);
    
    // Insert and remove at specific positions
    numbers.insert(0, 0); // Insert 0 at beginning
    numbers.remove(5);    // Remove element at index 5
    
    println(f"After insert/remove: {:?}", numbers);
    
    // Capacity management for WASM efficiency
    let mut optimized: Vec<i32> = Vec::with_capacity(1000);
    println(f"Pre-allocated capacity: {optimized.capacity()}");
    
    for i in 0..1000 {
        optimized.push(i);
    }
    
    println(f"After 1000 pushes - len: {optimized.len()}, cap: {optimized.capacity()}");
}
Array Slicing and Views
// Memory-efficient array slicing for WASM
fun array_slicing_demo() {
    println("Array Slicing and Memory Views:");
    
    let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // Slice operations (zero-copy views)
    let first_half = &data[0..5];
    let second_half = &data[5..];
    let middle = &data[2..8];
    
    println(f"Original: {:?}", data);
    println(f"First half: {:?}", first_half);
    println(f"Second half: {:?}", second_half);
    println(f"Middle: {:?}", middle);
    
    // Mutable slices for in-place operations
    let mut mutable_data = [10, 20, 30, 40, 50];
    let slice = &mut mutable_data[1..4];
    
    // Modify through slice
    for value in slice {
        *value = *value * 2;
    }
    
    println(f"After slice modification: {:?}", mutable_data);
    
    // Chunking for batch processing
    let large_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
    
    println("Processing in chunks of 3:");
    for chunk in large_array.chunks(3) {
        let chunk_sum = array_sum(chunk);
        println(f"Chunk {:?} sum: {chunk_sum}");
    }
}
Multi-dimensional Arrays
2D Array Operations
// 2D array representation in WASM linear memory
struct Matrix {
    data: Vec<f64>,
    rows: usize,
    cols: usize,
}
impl Matrix {
    fun new(rows: usize, cols: usize) -> Self {
        Matrix {
            data: vec![0.0; rows * cols],
            rows,
            cols,
        }
    }
    
    fun get(&self, row: usize, col: usize) -> f64 {
        self.data[row * self.cols + col]
    }
    
    fun set(&mut self, row: usize, col: usize, value: f64) {
        self.data[row * self.cols + col] = value;
    }
    
    fun fill(&mut self, value: f64) {
        for item in &mut self.data {
            *item = value;
        }
    }
}
fun matrix_operations_demo() {
    println("2D Array (Matrix) Operations:");
    
    // Create 3x3 matrix
    let mut matrix = Matrix::new(3, 3);
    
    // Fill with values
    let mut value = 1.0;
    for row in 0..3 {
        for col in 0..3 {
            matrix.set(row, col, value);
            value = value + 1.0;
        }
    }
    
    // Display matrix
    println("3x3 Matrix:");
    for row in 0..3 {
        for col in 0..3 {
            let val = matrix.get(row, col);
            print(f"{val:4.1} ");
        }
        println("");
    }
    
    // Matrix operations
    let mut result = Matrix::new(3, 3);
    
    // Scalar multiplication
    for row in 0..3 {
        for col in 0..3 {
            let original = matrix.get(row, col);
            result.set(row, col, original * 2.0);
        }
    }
    
    println("Matrix * 2:");
    for row in 0..3 {
        for col in 0..3 {
            let val = result.get(row, col);
            print(f"{val:4.1} ");
        }
        println("");
    }
}
// Efficient 2D array using nested vectors
fun nested_array_demo() {
    println("Nested Array Operations:");
    
    // 2D array as Vec<Vec<T>>
    let mut grid: Vec<Vec<i32>> = Vec::new();
    
    // Initialize 4x4 grid
    for i in 0..4 {
        let mut row = Vec::new();
        for j in 0..4 {
            row.push(i * 4 + j);
        }
        grid.push(row);
    }
    
    // Display grid
    println("4x4 Grid:");
    for row in &grid {
        for &value in row {
            print(f"{value:3} ");
        }
        println("");
    }
    
    // Row and column operations
    let row_sum: i32 = grid[1].iter().sum();
    println(f"Sum of row 1: {row_sum}");
    
    let mut col_sum = 0;
    for row in &grid {
        col_sum = col_sum + row[2];
    }
    println(f"Sum of column 2: {col_sum}");
}
Cross-Platform Array Integration
JavaScript Array Interop
// Functions optimized for JavaScript array passing
fun process_numeric_array(arr: Vec<f64>) -> ProcessingResult {
    let length = arr.len();
    let sum: f64 = arr.iter().sum();
    let avg = if length > 0 { sum / length as f64 } else { 0.0 };
    
    let min = arr.iter().copied().fold(f64::INFINITY, f64::min);
    let max = arr.iter().copied().fold(f64::NEG_INFINITY, f64::max);
    
    ProcessingResult {
        count: length as i32,
        sum,
        average: avg,
        minimum: min,
        maximum: max,
    }
}
struct ProcessingResult {
    count: i32,
    sum: f64,
    average: f64,
    minimum: f64,
    maximum: f64,
}
fun transform_array(arr: Vec<i32>, operation: String) -> Vec<i32> {
    match operation.as_str() {
        "double" => arr.iter().map(|&x| x * 2).collect(),
        "square" => arr.iter().map(|&x| x * x).collect(),
        "increment" => arr.iter().map(|&x| x + 1).collect(),
        "filter_even" => arr.iter().filter(|&&x| x % 2 == 0).copied().collect(),
        "filter_positive" => arr.iter().filter(|&&x| x > 0).copied().collect(),
        _ => arr,
    }
}
fun batch_process_arrays(arrays: Vec<Vec<i32>>) -> Vec<i32> {
    let mut results = Vec::new();
    
    for arr in arrays {
        let sum = array_sum(&arr);
        results.push(sum);
    }
    
    results
}
fun cross_platform_array_demo() {
    println("Cross-Platform Array Integration:");
    
    // Numeric processing
    let test_data = vec![1.5, 2.7, 3.1, 4.8, 5.2, 6.9, 7.3, 8.1];
    let result = process_numeric_array(test_data);
    
    println(f"Processing result: count={}, sum={:.2}, avg={:.2}", 
            result.count, result.sum, result.average);
    println(f"Min: {:.2}, Max: {:.2}", result.minimum, result.maximum);
    
    // Array transformations
    let integers = vec![1, 2, 3, 4, 5, -1, -2];
    
    let doubled = transform_array(integers.clone(), "double".to_string());
    let squared = transform_array(integers.clone(), "square".to_string());
    let even_only = transform_array(integers.clone(), "filter_even".to_string());
    let positive_only = transform_array(integers, "filter_positive".to_string());
    
    println(f"Doubled: {:?}", doubled);
    println(f"Squared: {:?}", squared);
    println(f"Even only: {:?}", even_only);
    println(f"Positive only: {:?}", positive_only);
    
    // Batch processing
    let batch_arrays = vec![
        vec![1, 2, 3],
        vec![4, 5, 6, 7],
        vec![8, 9],
        vec![10, 11, 12, 13, 14],
    ];
    
    let batch_sums = batch_process_arrays(batch_arrays);
    println(f"Batch sums: {:?}", batch_sums);
}
JavaScript Integration Example:
// Browser array processing with WASM
async function demonstrateWasmArrays() {
    const wasmModule = await WebAssembly.instantiateStreaming(
        fetch('./arrays.wasm')
    );
    
    const { 
        process_numeric_array,
        transform_array,
        batch_process_arrays
    } = wasmModule.instance.exports;
    
    console.log("=== WASM Array Processing ===");
    
    // Numeric array processing
    const testData = [1.5, 2.7, 3.1, 4.8, 5.2, 6.9, 7.3, 8.1];
    const result = process_numeric_array(testData);
    
    console.log('WASM processing result:', result);
    
    // Array transformations
    const integers = [1, 2, 3, 4, 5, -1, -2];
    
    const doubled = transform_array(integers, "double");
    const squared = transform_array(integers, "square");
    const evenOnly = transform_array(integers, "filter_even");
    
    console.log('Transformations:', { doubled, squared, evenOnly });
    
    // Performance comparison
    const largeArray = Array.from({length: 100000}, (_, i) => Math.random() * 100);
    
    console.time('WASM array processing');
    for (let i = 0; i < 100; i++) {
        process_numeric_array(largeArray);
    }
    console.timeEnd('WASM array processing');
    
    console.time('JavaScript array processing');
    for (let i = 0; i < 100; i++) {
        const sum = largeArray.reduce((a, b) => a + b, 0);
        const avg = sum / largeArray.length;
        const min = Math.min(...largeArray);
        const max = Math.max(...largeArray);
    }
    console.timeEnd('JavaScript array processing');
}
Quality Validation and Testing
Array Testing Framework
// Comprehensive array validation
fun validate_array_operations() -> bool {
    let mut all_tests_passed = true;
    
    println("Array Operations Validation:");
    
    // Basic array operations
    let test_array = [1, 2, 3, 4, 5];
    let sum = array_sum(&test_array);
    if sum != 15 {
        println("ERROR: Array sum validation failed");
        all_tests_passed = false;
    } else {
        println("✅ Array sum passed");
    }
    
    // Array search validation
    let search_result = array_search(&test_array, 3);
    if search_result != Some(2) {
        println("ERROR: Array search validation failed");
        all_tests_passed = false;
    } else {
        println("✅ Array search passed");
    }
    
    // Sorting validation
    let mut sort_test = [5, 2, 8, 1, 9];
    insertion_sort(&mut sort_test);
    if sort_test != [1, 2, 5, 8, 9] {
        println("ERROR: Sorting validation failed");
        all_tests_passed = false;
    } else {
        println("✅ Sorting validation passed");
    }
    
    // Vector operations validation
    let mut vec_test: Vec<i32> = vec![1, 2, 3];
    vec_test.push(4);
    if vec_test.len() != 4 || vec_test[3] != 4 {
        println("ERROR: Vector operations validation failed");
        all_tests_passed = false;
    } else {
        println("✅ Vector operations passed");
    }
    
    // Matrix operations validation
    let mut matrix_test = Matrix::new(2, 2);
    matrix_test.set(0, 0, 1.0);
    matrix_test.set(1, 1, 2.0);
    
    if matrix_test.get(0, 0) != 1.0 || matrix_test.get(1, 1) != 2.0 {
        println("ERROR: Matrix operations validation failed");
        all_tests_passed = false;
    } else {
        println("✅ Matrix operations passed");
    }
    
    all_tests_passed
}
fun performance_array_benchmarks() {
    println("Array Performance Benchmarks:");
    
    let iterations = 100000;
    
    // Array sum benchmark
    let large_array: Vec<i32> = (0..1000).collect();
    let mut sum_results = 0;
    
    for _ in 0..iterations {
        sum_results = sum_results + array_sum(&large_array);
    }
    
    println(f"Array sum benchmark: {sum_results} total");
    
    // Sorting benchmark
    let mut sort_count = 0;
    for _ in 0..1000 {
        let mut test_array = [9, 5, 2, 8, 1, 7, 3, 6, 4];
        insertion_sort(&mut test_array);
        if test_array[0] == 1 {
            sort_count = sort_count + 1;
        }
    }
    
    println(f"Sorting benchmark: {sort_count}/1000 successful");
    
    // Vector operations benchmark
    let mut vector_ops = 0;
    for _ in 0..10000 {
        let mut vec: Vec<i32> = Vec::with_capacity(100);
        for i in 0..100 {
            vec.push(i);
        }
        vector_ops = vector_ops + vec.len();
    }
    
    println(f"Vector operations: {vector_ops} total elements processed");
    println("WASM array operations completed successfully");
}
fun main() {
    println("=== WASM Arrays & Linear Memory Demo ===");
    
    demonstrate_array_memory();
    println("");
    
    linear_memory_optimization();
    println("");
    
    core_array_operations();
    println("");
    
    sorting_algorithms_demo();
    println("");
    
    vector_operations_demo();
    println("");
    
    array_slicing_demo();
    println("");
    
    matrix_operations_demo();
    println("");
    
    nested_array_demo();
    println("");
    
    cross_platform_array_demo();
    println("");
    
    performance_array_benchmarks();
    println("");
    
    let validation_passed = validate_array_operations();
    
    if validation_passed {
        println("🎯 Chapter 1.5 Complete: WASM Arrays & Linear Memory");
        println("Ready for cross-platform deployment!");
    } else {
        println("⚠️  Validation failed - check implementation");
    }
}
Platform Deployment Commands
# Compile for different platforms
ruchy wasm arrays.ruchy -o arrays.wasm --target browser
ruchy wasm arrays.ruchy -o arrays_node.wasm --target nodejs
ruchy wasm arrays.ruchy -o arrays_worker.wasm --target cloudflare-workers
# Quality validation
ruchy check arrays.ruchy
ruchy score arrays.ruchy  # Target: ≥ 0.8
# Deploy to platforms
ruchy wasm arrays.ruchy --deploy --deploy-target vercel
ruchy wasm arrays.ruchy --deploy --deploy-target cloudflare
Key Insights
- Linear Memory: WASM arrays use contiguous memory blocks for optimal performance
 - Memory Alignment: Proper data structure alignment improves WASM execution speed
 - Zero-Copy Slicing: Array views avoid unnecessary memory allocations
 - Batch Processing: Vectorized operations leverage WASM’s computational efficiency
 - Cross-Platform: Array operations maintain consistency across deployment targets
 
Next Steps
- Master WASM Function Exports
 - Explore WASM Structs & Data
 - Learn WASM Closures & Higher-Order Functions
 
Complete Demo: arrays.ruchy
All array operations tested across browser, Node.js, and Cloudflare Workers. Memory optimization and performance benchmarks included.