Asi zig-systems
Systems programming and performance optimization using Zig. Provides low-level abstractions, memory-safe compiled code, and performance benchmarking. Use for system-level operations, optimization, and interoperability with C/POSIX APIs.
git clone https://github.com/plurigrid/asi
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/zig-systems" ~/.claude/skills/plurigrid-asi-zig-systems && rm -rf "$T"
skills/zig-systems/SKILL.mdzig-systems - Systems Programming and Performance
Overview
zig-systems provides low-level systems programming capabilities using Zig - a modern language for systems code with performance of C, memory safety guarantees, and cross-platform compilation.
Role: ERGODIC systems coordinator - bridges high-level skill orchestration (Clojure) with native performance code.
Quick Start
Install Zig
# macOS with Homebrew brew install zig # Or download from https://ziglang.org/download/ # Verify installation zig version
Basic Compilation
# Compile a Zig program zig build-exe main.zig # Run compiled binary ./main # Compile with optimizations zig build-exe -O ReleaseFast main.zig # Compile to library (FFI) zig build-lib main.zig
Language Features
Memory Safety Without GC
const std = @import("std"); pub fn main() void { // Stack-allocated, no garbage collection var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const allocator = arena.allocator(); // Explicit allocation var list = std.ArrayList(i32).init(allocator); defer list.deinit(); // Type-safe operations try list.append(42); }
Comptime Metaprogramming
fn Matrix(comptime T: type, comptime rows: usize, comptime cols: usize) type { return struct { data: [rows * cols]T, fn get(self: @This(), r: usize, c: usize) T { return self.data[r * cols + c]; } }; } // Compile-time type generation const IntMatrix = Matrix(i32, 3, 3);
C Interoperability
// Direct C function calls extern "c" fn malloc(size: usize) ?*anyopaque; extern "c" fn free(ptr: ?*anyopaque) void; // Export functions for C/other languages export fn skill_invoke(input: [*]u8, len: usize) [*]u8 { // Process input, return output }
Project Structure
zig-systems/ ├── SKILL.md ├── build.zig # Build configuration ├── scripts/ │ ├── array_sort.zig │ ├── compression.zig │ ├── hash_table.zig │ └── ffi.zig # FFI/C interop ├── references/ │ ├── ZIG_SYNTAX.md │ ├── MEMORY_MODEL.md │ ├── PERFORMANCE.md │ └── FFI_GUIDE.md └── assets/ └── build_template.zig
Common Tasks
1. Efficient Sorting
const std = @import("std"); pub fn sort_i32(allocator: std.mem.Allocator, items: []i32) !void { var list = std.ArrayList(i32).init(allocator); defer list.deinit(); try list.appendSlice(items); std.sort.sort(i32, list.items, {}, std.sort.asc(i32)); }
2. Hash Table Operations
const std = @import("std"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); var map = std.StringHashMap(i32).init(allocator); defer map.deinit(); try map.put("foo", 42); if (map.get("foo")) |value| { std.debug.print("Found: {}\n", .{value}); } }
3. Compression Algorithm
pub fn compress(allocator: std.mem.Allocator, data: []const u8) ![]u8 { // Implement compression (e.g., DEFLATE, LZ4) var output = std.ArrayList(u8).init(allocator); defer output.deinit(); // Compression logic here return output.toOwnedSlice(); }
4. Performance Benchmarking
const std = @import("std"); pub fn benchmark(comptime name: []const u8, func: fn() void) void { var timer = try std.time.Timer.start(); defer { const elapsed = timer.read(); std.debug.print("{s}: {d}ns\n", .{name, elapsed}); } func(); }
Performance Characteristics
Compilation Speed
- Incremental: ~100ms for small modules
- Full rebuild: ~500ms - 2s
- Release build: ~1-5s with optimizations
Runtime Performance
- Memory usage: Minimal (no GC overhead)
- Binary size: 1-10MB depending on features
- Startup time: <1ms for most programs
- CPU efficiency: Near-C performance
Comparison
| Operation | Zig | Go | Java |
|---|---|---|---|
| Array sort (10K items) | ~1ms | ~2ms | ~5ms |
| Hash table insert | ~50ns | ~100ns | ~200ns |
| Memory allocation | ~50ns | ~100ns | ~500ns |
| Binary size (hello) | 2KB | 1MB | 50MB |
Building Zig Projects
Simple build.zig
const std = @import("std"); const Builder = std.build.Builder; pub fn build(b: *Builder) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "my_skill", .root_source_file = .{ .path = "main.zig" }, .target = target, .optimize = optimize, }); b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); const run_step = b.step("run", "Run the app"); run_step.dependOn(&run_cmd.step); }
Build Commands
# Build debug binary zig build # Build with optimizations zig build -Doptimize=ReleaseFast # Install to prefix zig build --prefix /usr/local install # Run tests zig build test
Integration with Other Skills
Calling from Clojure
(defn call-zig-sort [data] "Invoke Zig sort via FFI." (shell/sh "zig-systems" "sort" (write-json data)))
Calling from Go
import "C" //export SkillInvoke func SkillInvoke(data *C.char) *C.char { // Call Zig compiled library result := C.zig_compress(data) return result }
Calling from Hy
(import subprocess) (setv result (subprocess.run ["zig-systems" "compress" "input.dat"] :capture-output True))
When to Use
- Performance-critical code: Sorting, compression, hashing
- System-level operations: File I/O, memory management, POSIX APIs
- Cross-platform binaries: Compile once, run anywhere (Linux, macOS, Windows)
- FFI requirements: Need to call from other languages
- Memory-constrained systems: Embedded, IoT, serverless
- Real-time systems: Predictable performance, no GC pauses
When NOT to Use
- High-level business logic (use Clojure)
- Quick prototyping (Hy/Python faster iteration)
- Dynamic typing requirements (Zig is statically typed)
- GC convenience preferred over control
GF(3) Consideration
While zig-systems is a SINGLE language skill (not a triadic component itself), it coordinates with:
Validator (-1) + Coordinator (0) + Generator (+1) ≡ 0 (mod 3) [joker] [zig-systems] [hy-regime] OR [joker] [jo-clojure] [hy-regime]
Zig provides low-level system optimization that the triadic coordinator (jo-clojure or zig-systems) may invoke.
Debugging
Runtime Assertions
const std = @import("std"); pub fn divide(a: i32, b: i32) i32 { std.debug.assert(b != 0); // Panics if false return a / b; }
Error Handling
const FileOpenError = error { FileNotFound, PermissionDenied, }; pub fn open_file(path: []const u8) FileOpenError!*File { if (!file_exists(path)) { return FileOpenError.FileNotFound; } // ... }
Standard Library Utilities
const std = @import("std"); pub fn main() void { std.debug.print("Debug output: {any}\n", .{data}); std.debug.assert(condition); var timer = std.time.Timer.start(); }
Performance Optimization Tips
- Use ReleaseFast or ReleaseSmall optimization levels
- Minimize allocations: Preallocate where possible
- Use inline functions:
keyword for hot pathsinline - Leverage comptime: Compute at compile time, not runtime
- Profile with perf:
thenperf record ./binaryperf report - Consider SIMD:
type for parallel operations@Vector
References
- Zig Language Documentation
- Zig Standard Library
- Zig by Example
- Memory Model Guide
- FFI Integration
- Performance Tuning
Troubleshooting
"zig: command not found"
- Install Zig:
brew install zig - Verify:
zig version - Update PATH if needed
Build errors with C libraries
- Use
to link libczig build-exe main.zig -lc - Declare C imports explicitly:
extern "c" fn malloc(...)
Memory leaks in debug mode
- Use GeneralPurposeAllocator for testing
- Enable leak detection:
std.heap.GeneralPurposeAllocator(.{.safety = true})
Binary too large
- Use ReleaseSmall optimization:
-O ReleaseSmall - Strip debug symbols:
strip ./binary