Hacker News Digest

Тег: #go

Постов: 3

Zig's Lovely Syntax (matklad.github.io) 💬 Длинная дискуссия

Zig выглядит почти как Rust, но делает синтаксис ещё приятнее за счёт более простой семантики и ряда изящных решений.

Числа
Литералы 92 всегда имеют тип comptime_int; при присваивании они неявно приводятся к нужному типу. Суффиксов нет.

Строки
Многострочные «сырые» строки пишутся через \\ в начале каждой строки; \ не экранируется, отступы не портятся, а лексер работает построчно.

Структуры
.{ .x = 1, .y = 2 } — запись поля через .x = совпадает с присваиванием, что позволяет грепом находить именно записи, а не чтения.

Типы
Все типы префиксные: u32, [3]u32, ?[3]u32, *const ?[3]u32. Разыменование постфиксное: ptr.*.

Идентификаторы
Синтаксис @"имя с пробелом" позволяет обходить ключевые слова и экспортировать любые имена.

Функции
fn add(x: i32, y: i32) i32 — без стрелки ->, так как лямбд нет, а возвращаемый тип всегда обязателен. pub fn main() void {}.

Переменные
const и var; часто используемое const короче, чем в Rust, но всё же длиннее Kotlin-овского val.

by Bogdanp • 10 августа 2025 г. в 15:33 • 157 points

ОригиналHN

#zig#rust#kotlin#csharp#go#dlang

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

  • Обсуждение разделилось: кому-то синтаксис Zig кажется «прекрасным» минимализмом, другим — «шумным» и «капризным».
  • Спор о порядке «имя: тип» vs «тип имя»: одни хотят видеть тип первым, другие — имя.
  • Критика деталей: @-префиксы, .{}, отсутствие лямбд, перенос строк, orelse без пробела.
  • Плюсы: raw-строки Zig решают проблему отступов; обработка ошибок через try нравится многим.
  • Сравнения: Kotlin, C#, Go, Rust, D — каждый считает «своё» лучше.
  • Итог: «красота» синтаксиса субъективна и во многом привычна; после практики Zig начинает нравиться.

Build durable workflows with Postgres (dbos.dev)

  • Выбор хранилища метаданных рабочих процессов оказался ключевым. Нужно было простое: чекпойнт состояния и восстановление после сбоя. Postgres выбрали за технические возможности, а не только за популярность и 40-летнюю проверку временем.

  • Масштабируемые очереди
    Классическая таблица-очередь страдает от конкуренции: все воркеры пытаются взять одни и те же задачи. Postgres решает это через FOR UPDATE SKIP LOCKED: строки блокируются и пропускаются, если уже захвачены. Воркеры без конфликтов берут следующие N записей, позволяя обрабатывать десятки тысяч задач в секунду.

  • Наблюдаемость
    Каждый шаг сохраняется, поэтому можно строить дашборды и фильтры. SQL позволяет писать сложные запросы напрямую; индексы по created_at, executor_id, status ускоряют выборки из миллионов записей без лишних затрат.

  • Exactly-once для шагов с БД
    Обычно гарантируется «по крайней мере один раз», но если шаг меняет данные в той же транзакции, что и чекпойнт, Postgres обеспечит, что изменения зафиксируются ровно один раз даже после перезапуска.

by KraftyOne • 08 августа 2025 г. в 19:24 • 138 points

ОригиналHN

#postgresql#dbos#graphile-worker#temporal#python#typescript#java#c##go#dag

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

  • Пользователи хвалят DBOS за простоту миграции с graphile-worker и отсутствие необходимости менять инфраструктуру.
  • Сравнения с Temporal, Azure Durable Functions, Inngest, Restate и Cloudflare: DBOS выглядит проще и легче, но Temporal/Cloudflare критикуют за сложность самостоятельного хостинга и высокую цену.
  • Некоторые жалуются, что «сервер» DBOS (Conductor) не open-source, что ограничивает самостоятельное развёртывание.
  • Планы по добавлению Java, C#, Go и поддержке сообщества уже анонсированы; Python и TypeScript уже поддерживаются.
  • Отмечена возможность комбинировать DBOS с Dagster/Oban/pgflow для более сложной оркестрации.

We shouldn't have needed lockfiles (tonsky.me) 💬 Длинная дискуссия

Представьте, вы пишете проект и вам нужна библиотека — назовем ее libpupa.

Вы находите текущую версию 1.2.3 и добавляете в зависимости: "libpupa": "1.2.3" Автор libpupa 1.2.3 в свою очередь зависел от liblupa версии 0.7.8 и записал это: "liblupa": "0.7.8" То есть libpupa 1.2.3 навсегда зависит от liblupa 0.7.8. Алгоритм разрешения зависимостей простой и детерминированный: берем версии верхнего уровня, затем версии их зависимостей, и так далее. Достаточно указать только верхние уровни — транзитивные получатся одинаковыми всегда. Зачем отдельный lockfile?

Но люди изобрели lockfile из‑за диапазонов версий. Диапазоны делают сборку зависимой от времени: сегодня вы получите liblupa 0.7.8, через 10 минут — 0.7.9. Это определяется не при публикации, а при сборке: вы можете подтянуть версию, которой не существовало на момент выпуска libpupa 1.2.3. Откуда автор libpupa знает, что будущая 0.7.9 не сломает его код? Семантическое версионирование — это лишь намек, не гарантия.

И смешно то, что эти диапазоны все равно «замораживают» в lockfile, и вы не получаете предполагаемой пользы. «Перегенерируй lockfile и обновись» — это ничем не отличается от обновления верхнеуровневых зависимостей. «Lockfile решает конфликты версий?» — нет: библиотека либо работает с новой версией, либо нет; запись «0.7.*» не помогает — все равно нужно выбрать рабочую версию.

«Но раз lockfile существует, значит, нужен!» — не обязательно. Пример: Maven. Экосистема Java 20 лет обходится без lockfile, при этом тянет сотни библиотек — и все детерминировано.

Вывод: lockfile усложняет без достаточных причин. Менеджеры зависимостей могут работать без него.

UPD: В Maven при конфликте транзитивных зависимостей выбирается версия, ближайшая к корню. Это детерминированно и позволяет переопределять версии. Если вышла d 2.1 с патчами безопасности, добавьте ее в корень — она и будет выбрана, не дожидаясь обновлений у всех. Если автоматически брать самую большую версию, вы потеряете возможность переопределения.

by tobr • 06 августа 2025 г. в 15:33 • 133 points

ОригиналHN

#dependency-management#versioning#rust#java#go#scala#maven#cargo

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

  • Обсуждение крутится вокруг необходимости lock-файлов и версионирования: одни считают, что фиксированные версии и детерминированные алгоритмы достаточно, другие настаивают, что lock-файлы критичны для воспроизводимости и безопасности.
  • Приводят примеры из экосистем Maven/Java, Go (MVS), Cargo/Rust, .NET, Scala: у каждого свои компромиссы; даже при детерминированном резолве сеть/репозитории делают сборки недетерминированными без lock-файлов и хэшей.
  • Аргументы за версии-диапазоны: автоматическое получение патчей безопасности без вмешательства авторов верхнеуровневых библиотек; но это ломается при конфликтующих транзитивных зависимостях и несовместимых API/ABI.
  • Много комментариев о том, что lock-файлы особенно нужны приложениям (прод, стейджинг, аудит), а для библиотек — меньше, но всё равно полезны из-за пересборок и целостности (хэши артефактов).
  • Подчёркивают проблемы разных языков: в компилируемых — типы из разных версий несовместимы; в JS Node могут сосуществовать несколько версий, но это не решает безопасность/детерминизм.
  • Некоторые отмечают, что главная путаница — не в lock-файлах, а в культуре семвера, централизованных репозиториях и UX инструментов; предлагают BOM/snapshot-подходы и периодические обновления с тестами/реновейтом.
  • Отдельная ветка критикует дизайн сайта с анимированными иконками, мешающими чтению.