Hacker News Digest

Тег: #comptime

Постов: 4

Why is Zig so cool? (nilostolte.github.io) 🔥 Горячее 💬 Длинная дискуссия

Zig - это не просто замена C или C++, а совершенно новый подход к программированию, который удивил автора с 45-летним опытом. Самые впечатляющие особенности языка - встроенная возможность компилировать C-код и кросс-компиляция "из коробки", что уже оказывает значительное влияние на индустрию.

Установка компилятора Zig проста и доступна для различных платформ и архитектур на официальном сайте. Автор подчеркивает, что эти функции сами по себе уникальны, но сосредоточен на том, как программировать на Zig и почему стоит выбрать его вместо других языков.

by vitalnodo • 07 ноября 2025 г. в 23:04 • 528 points

ОригиналHN

#zig#c#c++#rust#ada#comptime#cross-compilation

Комментарии (467)

  • Статья преувеличивает инновативность Zig, не подкрепляя заявления о "революционности" реальными уникальными фичами.
  • Пользователи отмечают практические преимущества: простота установки (через PyPI), кросс-компиляция, явный синтаксис и компиляция C-кода.
  • Критика включает отсутствие безопасности памяти, спорные решения (политика идентификаторов, отсутствие данных в ошибках) и сравнение с Rust/Ada как более зрелых альтернатив.
  • Отдельные хвалят метапрограммирование (comptime), простоту навигации по коду и удобство для низкоуровневого программирования.
  • Обсуждение подчеркивает субъективность восприятия: для одних Zig "меняет подход к программированию", для других — лишь "улучшенный C" без уникального позиционирования.

I'm too dumb for Zig's new IO interface (openmymind.net) 💬 Длинная дискуссия

Zig 0.15 сменил IO: std.Io.Reader и std.Io.Writer.
Старый способ тормозил и путался из-за anytype.

Подключаемся к www.openmymind.net:443:

const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.DebugAllocator(.{}).init;
    defer gpa.deinit();
    const a = gpa.allocator();

    const s = try std.net.tcpConnectToHost(a, "www.openmymind.net", 443);
    defer s.close();

    var wbuf: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
    var rbuf: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
    var w = s.writer(&wbuf);
    var r = s.reader(&rbuf);

    var bundle = std.crypto.Certificate.Bundle{};
    try bundle.rescan(a);
    defer bundle.deinit(a);

    var tls_buf: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
    var tls = try std.crypto.tls.Client.init(
        r.interface(),
        &w.interface,
        .{
            .ca = .{ .bundle = bundle },
            .host = .{ .explicit = "www.openmymind.net" },
            .read_buffer = &.{},
            .write_buffer = &tls_buf,
        },
    );
    defer tls.end() catch {};

    try tls.writer.writeAll("GET / HTTP/1.1\r\n\r\n");

    var out: [1024]u8 = undefined;
    var fw = std.Io.Writer.fixed(&out);
    const n = try tls.reader.stream(&fw, .limited(out.len));
    std.debug.print("read: {s}\n", .{out[0..n]});
}

Ключевые моменты

  • stream.reader() и writer() требуют буфер.
  • Чтобы передать их в tls.Client, нужно .interface() и &interface.
  • tls.Client.init обязательно просит ca, host, read_buffer, write_buffer.
  • Чтение ответа: tls.reader.stream в std.Io.Writer.

by begoon • 23 августа 2025 г. в 06:39 • 169 points

ОригиналHN

#zig#tls#tcp#io#comptime#discriminated-unions

Комментарии (161)

  • Автору пришлось вручную вызывать flush у двух обёрток и разбираться с тем, что первое чтение всегда возвращает 0.
  • Основная жалоба — отсутствие документации и примеров; сообщество отвечает «читай исходники», но участники признают, что API ещё нестабилен.
  • Некоторые считают новый I/O-интерфейс элегантным, но сложным даже для «Hello, world!»; другие предпочитают прямое использование системных API.
  • Zig позиционируется как язык системного программирования, близкий к C, с преимуществами вроде discriminated unions и comptime, но сопровождается постоянными breaking changes.

Partially Matching Zig Enums (matklad.github.io)

by ingve • 09 августа 2025 г. в 08:50 • 129 points

ОригиналHN

#zig#comptime#metaprogramming#memory-safety#data-race-safety#multithreading

Комментарии (89)

  • Zig вызывает интерес благодаря мощному comptime и «inline else», позволяющим абстрагироваться без рантайм-оверхеда.
  • Участники сравнивают его метапрограммирование с C, D и Rust, отмечая, что похожие идеи уже были, но Zig может сделать их популярнее.
  • Главный упрек Zig — отсутствие гарантий memory- и data-race safety, из-за чего многие считают его неподходящим для многопоточного кода.
  • «comptime unreachable» воспринимается как способ доказать компилятору недостижимость кода, а не как runtime-assert.
  • Некоторые считают, что язык ещё нестабилен и экосистема незрела, поэтому широкое внедрение отложено.

Zig Error Patterns (glfmn.io)

Введение

Я часто использую отладчик, но привык и к выводной отладке, особенно в юнит-тестах. Хотелось улучшить её и чаще подключать отладчик.

Улучшение выводной отладки

Главная проблема — «шум»: в цикле интересна одна итерация, а печатается всё. Или удобнее читать форматированную структуру, но приходится раскидывать print’ы по коду. В Zig тесты используют error’ы, значит можно печатать только при падении теста через errdefer:

test { errdefer std.debug.print("{f}", .{ast}); // ... }

Так контекст появляется только при ошибке, без засорения лога.

Запуск тестов в отладчике

Просто запустить seergdb или gdb -tui неудобно: тестовые бинарники лежат в zig-cache. Трюк из ziggит: build.zig может запускать команды и передавать путь артефакта:

// seergdb — GUI фронтенд для gdb const debugger = b.addSystemCommand(&.{ "seergdb", "--run", "--" }); debugger.addArtifactArg(exe_unit_tests);

const debug_step = b.step("debug", "Run unit tests under debugger"); debug_step.dependOn(&debugger.step);

Это запускает правильный бинарник. Но отладчик сработает лишь на брейкпоинте или панике, тогда как раннер тестов «проглатывает» ошибки.

Комбинация трюков

Добавим @breakpoint через errdefer:

test { errdefer @breakpoint(); }

Так мы попадаем в точку ошибки, видим контекст и вывод std.testing.expect*. Минус: при zig build test отчёт показывает падение всего шага тестов, а не отдельных кейсов. Нужна возможность включать брейкпоинты выборочно.

Условная компиляция

Через build options пробрасываем флаг, решающий, вызывать ли @breakpoint в тестах.

Минимальный скрипт сборки, запускающий тесты, дополняем опциями:

const std = @import("std");

pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{});

const lib = b.addModule("zig-test-patterns", .{
    .root_source_file = b.path("src/root.zig"),
    .target = target,
    .optimize = optimize,
});

const options = b.addOptions();
options.addOption(bool, "debugger", false);
lib.addImport("config", options.createModule());

const mod_tests = b.addTest(.{ .root_module = lib });
const run_mod_tests = b.addRunArtifact(mod_tests);

const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_mod_tests.step);

}

В коде тестов:

const std = @import("std"); const config = @import("config");

test "errdefer @breakpoint()" { errdefer if (config.debugger) @breakpoint(); return error.FixMe; }

test "no breakpoint" { return error.FixMe; }

zig build test — без брейкпоинтов. Но менять значение флага так — значит пересобирать build.zig. Добавим опцию прямо в систему сборки:

var options = b.addOptions(); const use_debugger = b.option( bool, "debugger", "Enables code intended to only run under a debugger", ) orelse false; options.addOption(bool, "debugger", use_debugger);

Теперь можно переключать поведением командой:

zig build -Ddebugger test

И, при желании, привязать шаг запуска отладчика к этому флагу.

by Bogdanp • 06 августа 2025 г. в 15:03 • 148 points

ОригиналHN

#zig#debugging#unit-testing#error-handling#comptime#errdefer#build.zig#gdb#seergdb

Комментарии (46)

  • Участники хвалят согласованность базовых конструкций Zig: минимализм синтаксиса и мощь comptime позволяют элегантные решения без излишней сложности.
  • Особый интерес вызвал errdefer: многие отмечают, что это упрощает тесты и отладку; звучит мнение, что такую возможность «стоит иметь каждому языку».
  • Обсуждают практики отладки: полезны советы по интеграции дебаггера в build.zig, что избавляет от ручного поиска исполняемого файла в кэше.
  • Поднимается вопрос об ошибках без полезной нагрузки в Zig: при парсинге (например, JSON) типовые ошибки вроде UnexpectedToken недостаточно информативны; интересуются паттернами передачи дополнительного контекста.
  • Есть замечание о смешении стилей именования (camelCase в stdlib vs snake_case у автора), что может сбивать с толку.
  • Отмечают эстетику сайта и блога: шрифты (Berkeley Mono), цветовую схему и ретро-оформление — «как в старых DOS-играх».
  • Проводится параллель с D: аналогичная идея реализована через scope(failure), что подчеркивает общность концепции.