zig-comptime — скилл для Claude Code: comptime и метапрограммирование
Скилл для агентов, который помогает писать обобщённые функции, рефлексию типов и код, вычисляемый на этапе компиляции в Zig.
npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a claude-codeЧто делает zig-comptime
Скилл ведёт агента по системе comptime в Zig: вычисление функций во время компиляции, параметры-типы, обобщения через anytype, рефлексия с @typeInfo и приёмы метапрограммирования, заменяющие шаблоны и макросы C++. Активируется на вопросах про comptime, обобщения, anytype и @typeInfo.
Внутри — рабочий процесс из разделов: основы comptime, обобщённые функции с параметрами-типами, anytype как утиная типизация, разбор структуры типа через @typeInfo, генерация кода на этапе компиляции. Есть примеры: обобщённый max, структура Stack(comptime T: type), проверки @hasDecl и @hasField с @compileError, таблица синусов через blk и @setEvalBranchQuota, обработка строк на этапе компиляции. Отдельная таблица сравнивает comptime с шаблонами C++ по синтаксису, сообщениям об ошибках, специализации и SFINAE.
Скилл рассчитан на Zig, поэтому в проектах на других языках он не сработает. Установка идёт через npx skills add с флагом -a под конкретную платформу, файл скилла кладётся в каталог платформы. Если работаете через прокси или приватное зеркало npm, настройте это в окружении или конфиге npm, а не в самой строке установки.
Какие задачи решает
- написать обобщённую функцию с параметром-типом
- разобрать поля структуры через
@typeInfo - заменить шаблон C++ на comptime-код в Zig
- принять любой тип с нужным полем через
anytype - посчитать таблицу значений на этапе компиляции
Примеры запросов агенту
- Покажи, как написать обобщённую функцию max с параметром comptime T: type
- Как через @typeInfo вывести список полей структуры?
- Объясни, чем anytype отличается от comptime-параметра типа
Как установить zig-comptime
1Через Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a claude-code2Вручную: положить файлы
~/.claude/skills/zig-comptime/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/zig-comptime/
1Через Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a codex2Вручную: положить файлы
.agents/skills/zig-comptime/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a cursor2Вручную: положить файлы
.cursor/skills/zig-comptime/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install mohitmishra786/low-level-dev-skills zig-comptime2Вручную: положить файлы
.github/skills/zig-comptime/SKILL.md1Через Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a gemini-cli2Командой платформы
gemini skills install https://github.com/mohitmishra786/low-level-dev-skills --path skills/zig/zig-comptimeВручную: положить файлы
.devin/skills/zig-comptime/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора62
Похожие
Рядом в теме «Языки программирования»
Все скиллы по теме «Языки программирования» →Вопросы о zig-comptime
Как установить zig-comptime в Claude?
Выполните npx skills add mohitmishra786/low-level-dev-skills --skill zig-comptime -a claude-code. Файл скилла окажется в ~/.claude/skills/zig-comptime/SKILL.md.
Что делает zig-comptime?
Проводит агента по comptime в Zig: вычислению на этапе компиляции, обобщениям через параметры-типы и anytype, рефлексии через @typeInfo и генерации кода.
Для каких платформ подходит этот скилл?
Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI и OpenCode. Для каждой платформы своя команда установки с флагом -a.
Исходный текст
SKILL.md · MIT
---
name: zig-comptime
description: Zig comptime skill for compile-time evaluation and metaprogramming. Use when using comptime parameters, comptime types, generics via anytype, comptime reflection with @typeInfo, or metaprogramming patterns that replace C++ templates. Activates on queries about Zig comptime, compile-time evaluation, Zig generics, anytype, @typeInfo, comptime types, or Zig metaprogramming.
---
# Zig comptime
## Purpose
Guide agents through Zig's `comptime` system: compile-time function evaluation, comptime type parameters, generics via `anytype`, type reflection with `@typeInfo`, and metaprogramming patterns that replace C++ templates and macros.
## Triggers
- "How does comptime work in Zig?"
- "How do I write a generic function in Zig?"
- "How do I use @typeInfo for reflection?"
- "How do I generate code at compile time in Zig?"
- "How does anytype work in Zig?"
- "How do Zig generics compare to C++ templates?"
## Workflow
### 1. comptime basics
```zig
// comptime keyword forces compile-time evaluation
const x: comptime_int = 42; // comptime integer (arbitrary precision)
const y: comptime_float = 3.14159; // comptime float (arbitrary precision)
// comptime block — runs at compile time
comptime {
const val = fibonacci(20); // computed at compile time
std.debug.assert(val == 6765); // compile-time assertion
}
// comptime parameter — caller must provide a comptime-known value
fn makeArray(comptime T: type, comptime n: usize) [n]T {
return [_]T{0} ** n; // array of n zeros of type T
}
const arr = makeArray(f32, 8); // [8]f32 computed at compile time
```
### 2. Generic functions with comptime type parameters
```zig
const std = @import("std");
// Generic max function — T must be comptime-known
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
// Usage: T is inferred from arguments or specified explicitly
const r1 = max(i32, 3, 7); // 7
const r2 = max(f64, 2.5, 1.8); // 2.5
// Generic Stack data structure
fn Stack(comptime T: type) type {
return struct {
items: []T,
top: usize,
allocator: std.mem.Allocator,
const Self = @This();
pub fn init(allocator: std.mem.Allocator) !Self {
return Self{
.items = try allocator.alloc(T, 64),
.top = 0,
.allocator = allocator,
};
}
pub fn push(self: *Self, value: T) void {
self.items[self.top] = value;
self.top += 1;
}
pub fn pop(self: *Self) ?T {
if (self.top == 0) return null;
self.top -= 1;
return self.items[self.top];
}
pub fn deinit(self: *Self) void {
self.allocator.free(self.items);
}
};
}
// Usage: Stack(i32) and Stack(f64) are distinct types
var int_stack = try Stack(i32).init(allocator);
defer int_stack.deinit();
int_stack.push(42);
```
### 3. anytype — duck-typed comptime parameters
`anytype` accepts any type and the compiler infers it at the call site:
```zig
// anytype: function works for any type with .len field
fn printLength(thing: anytype) void {
std.debug.print("Length: {}\n", .{thing.len});
}
printLength("hello"); // string literal — works
printLength([_]u8{1, 2, 3}); // array — works
printLength(std.ArrayList(u32){}); // ArrayList — works
// anytype with comptime checks for better errors
fn serialize(writer: anytype, value: anytype) !void {
// Verify writer has write method at comptime
if (!@hasDecl(@TypeOf(writer), "write")) {
@compileError("writer must have a write method");
}
try writer.write(std.mem.asBytes(&value));
}
// anytype in struct methods (used throughout std library)
pub fn format(
self: MyType,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype, // any writer: file, buffer, etc.
) !void {
try writer.print("{} {}", .{self.x, self.y});
}
```
### 4. Type reflection with @typeInfo
`@typeInfo` returns a tagged union describing a type's structure at comptime:
```zig
const std = @import("std");
const TypeInfo = std.builtin.Type;
fn printTypeInfo(comptime T: type) void {
const info = @typeInfo(T);
switch (info) {
.Int => |i| std.debug.print("Int: {} bits, {s}\n",
.{i.bits, @tagName(i.signedness)}),
.Float => |f| std.debug.print("Float: {} bits\n", .{f.bits}),
.Struct => |s| {
std.debug.print("Struct with {} fields:\n", .{s.fields.len});
inline for (s.fields) |field| {
std.debug.print(" {s}: {}\n", .{field.name, field.type});
}
},
.Enum => |e| {
std.debug.print("Enum with {} values:\n", .{e.fields.len});
inline for (e.fields) |field| {
std.debug.print(" {s} = {}\n", .{field.name, field.value});
}
},
.Optional => |o| std.debug.print("Optional({s})\n", .{@typeName(o.child)}),
.Array => |a| std.debug.print("[{}]{s}\n", .{a.len, @typeName(a.child)}),
else => std.debug.print("Other type: {s}\n", .{@typeName(T)}),
}
}
// Usage at comptime
comptime { printTypeInfo(u32); } // Int: 32 bits, unsigned
comptime { printTypeInfo(f64); } // Float: 64 bits
```
### 5. Comptime-generated code patterns
```zig
// Generate a lookup table at comptime
const sin_table = blk: {
const N = 256;
var table: [N]f32 = undefined;
@setEvalBranchQuota(10000); // increase for expensive comptime eval
for (0..N) |i| {
const angle = @as(f32, @floatFromInt(i)) * (2.0 * std.math.pi / N);
table[i] = @sin(angle);
}
break :blk table;
};
// Comptime string processing
fn upperCase(comptime s: []const u8) [s.len]u8 {
var result: [s.len]u8 = undefined;
for (s, 0..) |c, i| {
result[i] = std.ascii.toUpper(c);
}
return result;
}
const HELLO = upperCase("hello"); // computed at compile time
// Structural typing: accept any struct with specific fields
fn area(shape: anytype) f64 {
const T = @TypeOf(shape);
if (@hasField(T, "width") and @hasField(T, "height")) {
return @as(f64, shape.width) * @as(f64, shape.height);
} else if (@hasField(T, "radius")) {
return std.math.pi * @as(f64, shape.radius) * @as(f64, shape.radius);
} else {
@compileError("shape must have width+height or radius fields");
}
}
```
### 6. comptime vs C++ templates comparison
| Feature | C++ templates | Zig comptime |
|---------|--------------|--------------|
| Syntax | `template<typename T>` | `fn foo(comptime T: type)` |
| Error messages | Cryptic instantiation stacks | Clear, at definition point |
| Specialization | `template<> class Foo<int>` | `if (T == i32) { ... }` with `inline if` |
| SFINAE | Complex enable_if | `@hasDecl`, `@hasField`, `@compileError` |
| Variadic | `template<typename... Ts>` | `anytype`, tuples, `inline for` |
| Compile time | Can be very slow | Explicit, bounded by `@setEvalBranchQuota` |
| Values | Requires `constexpr` | Any expression can be `comptime` |
| Macros | Separate `#define` system | Comptime functions replace most macros |
### 7. Common comptime patterns
```zig
// Pattern: compile error for unsupported types
fn serializeInt(comptime T: type, value: T) []const u8 {
if (@typeInfo(T) != .Int) {
@compileError("serializeInt requires an integer type, got: " ++ @typeName(T));
}
// ...
}
// Pattern: conditional compilation
const is_debug = @import("builtin").mode == .Debug;
if (comptime is_debug) {
// included only in debug builds
validateInvariant(self);
}
// Pattern: inline for over comptime-known slice
const fields = std.meta.fields(MyStruct);
inline for (fields) |field| {
// field.name, field.type available at comptime
std.debug.print("{s}\n", .{field.name});
}
```
## Related skills
- Use `skills/zig/zig-testing` for comptime assertions and testing comptime code
- Use `skills/zig/zig-build-system` for comptime-based build.zig configuration
- Use `skills/compilers/cpp-templates` for C++ template equivalent patterns
© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills