Implementing Forth in Go and C
-
Почему Forth?
20 лет назад прочёл про язык в книге по embedded, но не вник. В июне 2025-го захотелось просто писать код и наткнулся на статьи Dave Gauera — решил попробовать. -
Два уровня Forth
User: просто пользуешься языком.
Hacker: IF…THEN, BEGIN…UNTIL и прочие конструкции — обычные слова, которые можно переопределить; язык описывает сам себя. -
goforth (Go)
«Чистый» интерпретатор: слово хранит исходный текст, который повторно интерпретируется. Для пользователя работает, но нельзя реализовать IF внутри Forth — всё контролирует Go. -
ctil (C)
Классическая реализация: связанный словарь, токен-трединг, большая часть на Forth. Позволяет писать:
: variable create 1 cells allot ;
: if ' 0branch , here 0 , ; immediate
: then here swap - swap ! ; immediate
: else ' branch , here 0 , swap dup here swap - swap ! ; immediate
Итого: два эксперимента, показывающие разницу между «просто работает» и «можно копнуть душу языка».
Комментарии (23)
- Реализация Forth на Go оказалась «не по канонам»: стек и память описаны отдельными структурами, поэтому многие стандартные слова не работают.
- Кто-то показал элегантный вариант на C++ с continuation-passing style и musttail-атрибутом clang.
- Всплыли воспоминания о Forth-диалекте FCode в Open Firmware старых Mac, но выяснилось, что Intel-Mac’и использовали EFI, а не Open Firmware.
- Читатели посетовали на читаемость кода без комментариев о стеке и отметили, что «high-level» реализации могут потерять дух Forth.
- Автор ответил: первая версия на Go была экспериментом, а «правильная» реализация на C хранит код и данные вместе, как положено.
Show HN: I made an Animal Crossing style letter editor
Генератор писем для Animal Crossing
Создаёт автоматические письма жителям.
- Выбираете жителя → тему (подарок, благодарность, приглашение).
- Генератор подставляет имя, стиль речи и эмодзи-иконки.
- Можно добавить предмет из инвентаря: письмо придёт с вложением.
- Поддерживаются шаблоны на русском, английском, японском.
Комментарии (27)
- Пользователи в восторге от генератора писем в стиле Animal Crossing и делятся тёплыми историями о том, как отправили письма близким.
- IdreesInc удивлён внезапным наплывом сообщений и объясняет, что все «бутылочные» послания модерируются вручную через AWS.
- Найдены мелкие баги: теряются символы перевода строки при сжатии в ссылку, а слово stationary неправильно написано вместо stationery.
- Некоторые советуют сменить название и убрать «Tom Nook», чтобы избежать проблем с правообладателями.
- Появились ссылки на похожие инструменты: Death Generator и библиотека animalese для озвучки.
SpaceX's giant Starship Mars rocket nails critical 10th test flight 💬 Длинная дискуссия
- Starship IFT-10 стартовал 25 августа 2025 г. с базы Starbase в Техасе.
- Super Heavy отделился через 2 мин 40 с и мягко приводнился в Мексиканском заливе.
- Starship продолжил полёт, достиг 211 км, совершил «белковый рулон» и успешно «поймал» макет башни-ловушки.
- Через ~65 мин корабль совершил контролируемое падение в Индийский океан.
- Это первый полёт после аварии IFT-9; ключевые системы (Raptor-вакуум, теплозащита, аэродинамические поверхности) отработали штатно.
- SpaceX планирует IFT-11 через 3 недели; цель — отработка возврата и многоразовости для будущих миссий на Луну и Марс.
Комментарии (186)
- Участники сходятся: полёт IFT-10 — большой шаг вперёд, но не «абсолютный успех» из-за повреждений обшивки и взрыва при входе.
- Повреждения были частью эксперимента: SpaceX специально убрали часть теплозащиты и проверяли пределы прочности.
- Даже с потерей корабля программа считается успешной: цели полёта выполнены, а устойчивость конструкции подтверждена.
- Следующий запуск, вероятно, повторит профиль IFT-10, но может попытаться поймать бустер «руками» и выйти на орбиту.
- Обсуждают цену: Starship уже дешевле SLS и Saturn V, а полная многоразовость нужна именно для будущих миссий на Марс.
Bring Your Own Agent to Zed – Featuring Gemini CLI
Теперь в Zed можно запускать сторонних агентов. Для этого мы создали Agent Client Protocol (ACP) — открытый JSON-RPC стандарт, и первым его внедрением стал Gemini CLI от Google.
Gemini CLI в Zed
- То же CLI, что и в терминале, но с интеграцией в редактор: live-предпросмотр изменений, мульти-буфер ревью, навигация между кодом и чатом.
- Всё работает как подпроцесс, общение через ACP вместо ANSI-кодов.
Agent Client Protocol
- ACP развязывает агентов от IDE: любой клиент, поддерживающий протокол, получает готовый UI.
- Данные не уходят на серверы Zed; код остаётся локально.
- Протокол под Apache-лицензией; уже есть пример для Neovim (Code Companion).
- Внутренний агент Zed теперь тоже использует ACP, поэтому улучшения UI доступны всем.
Присоединяйтесь
ACP открыт для форков и предложений. Мы хотим видеть экосистему специализированных агентов и поддержку в других редакторах. Исходники и примеры — в репозитории Zed.
Комментарии (34)
- Zed анонсировал Agent Client Protocol (ACP), что выглядит как попытка выйти из бизнеса Cursor и дать пользователям «принести своего агента».
- Пользователи хвалят скорость и активную разработку Zed, но жалуются на ESLint-проблемы и спрашивают, насколько гибко можно перенастроить редактор.
- Некоторые готовы платить за Zed (до 79 $/год), другие опасаются VC-финансирования и предпочитают Emacs/Neovim.
- Поднимаются вопросы о поддержке ACP такими агентами, как Claude Code и Cursor-agent, а также о пересечении с IBM Agent Communication Protocol.
Nx compromised: malware uses Claude code CLI to explore the filesystem 🔥 Горячее 💬 Длинная дискуссия
Критическая уязвимость в NX
NX (Nrwl) скомпрометирован: злоумышленники внедрили вредоносный код, крадущий кошельки и учётные данные.
- Что случилось: в пакетах
@nx/nx-linux-x64-gnu,@nx/nx-linux-x64-musl,@nx/nx-win32-x64-msvcобнаружен backdoor. - Как работает: при установке пакета запускается скрипт, который крадёт файлы
.env,wallet.dat,id_rsaи отправляет их на сервер злоумышленников. - Кто под угрозой: все, кто установил заражённые версии с 2024-06-01 по 2024-06-05.
- Что делать:
- Проверить версию NX:
nx --version. - Обновиться до последней версии (≥19.1.1).
- Проверить проект на наличие подозрительных скриптов в
node_modules/.bin. - Сменить все пароли и ключи, хранившиеся в проекте.
- Проверить версию NX:
Semgrep уже выпустил правило для обнаружения вредоносного кода:
semgrep --config=auto .
Комментарии (242)
- Компрометация npm-токена позволила злоумышленнику встроить вредоносный post-install-скрипт в популярные пакеты Nx.
- Скрипт проверяет наличие Claude Code / Gemini CLI и использует LLM для поиска секретов, обходя статический анализ.
- Участники советуют отключать npm-скрипты (
ignore-scripts true), использовать pnpm/bun, изолировать установку в контейнеры/VM и минимизировать зависимости. - Подчёркивается, что AI-агенты, запускаемые без песочницы, становятся мощным вектором атаки.
What Are Traces and Spans in OpenTelemetry?
Trace — полный путь одного запроса через все сервисы.
Span — отдельный шаг в этом пути (функция, SQL, HTTP-вызов).
Root span — первый span (обычно входящий HTTP-запрос).
Child span — вложенный шаг.
Context — передаёт trace_id и текущий span по асинхронным вызовам.
Sampler — решает, записывать ли трассировку.
Exporter — отправляет spans в OneUptime, Jaeger и т.д.
Структура span
- name — короткое имя операции
- start/end time — длительность
- status — OK / ERROR
- attributes — произвольные метки (user_id, db.table)
- events — точки во времени (exception, cache hit)
- links — связи с другими traces
Быстрый старт в Node.js / TypeScript
npm i @opentelemetry/api @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node
// tracing.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
const sdk = new NodeSDK({
serviceName: 'my-api',
traceExporter: new OTLPTraceExporter({ url: 'https://otlp.oneuptime.com' }),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
Ручная инструментация
import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('my-service');
async function getUser(id: string) {
return tracer.startActiveSpan('db.users.findById', async (span) => {
span.setAttributes({ 'db.table': 'users', 'user.id': id });
try {
const user = await db.users.findById(id);
span.setStatus({ code: SpanStatusCode.OK });
return user;
} catch (e) {
span.recordException(e);
span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });
throw e;
} finally {
span.end();
}
});
}
Express/Fastify middleware
import { trace } from '@opentelemetry/api';
export function traceMiddleware(req, res, next) {
const span = trace.getTracer('http').startSpan(`${req.method} ${req.route?.path || req.url}`);
trace.getActiveContext().with(trace.setSpan(trace.getActiveContext(), span), () => {
res.on('finish', () => {
span.setAttributes({
'http.status_code': res.statusCode,
'http.method': req.method,
'http.route': req.route?.path,
});
span.end();
});
next();
});
}
Практические советы
- Именование:
verb noun(GET /users,db.users.insert). - Атрибуты: добавляйте
user.id,order.id,region. - Ошибки:
span.recordException(err)+span.setStatus({code: ERROR}). - Sampling: head-based (решение на старте) или tail-based (после завершения).
- Антипаттерны: слишком мелкие spans, отсутствие
span.end(), захардкоженные ID.
Сборка всего вместе
- Запустите SDK на старте приложения.
- Добавьте auto-instrumentations (http, express, pg, redis).
- Дополните ручными spans для критичных операций.
- Отправляйте traces в OneUptime → исследуйте flame-графы, ищите узкие места.
Комментарии (28)
- OTEL хвалят как стандарт, но реальные реализации сильно разнятся между вендорами и часто усложняют жизнь.
- Базовые понятия: span — это интервал работы с уникальным ID и ссылкой на родителя, trace — DAG спанов, рассказывающий историю запроса.
- Авто-инструментация почти даром даёт данные для JVM-приложений, но вне веб-бэкендов примеров мало и приходится искать «правильный» подмножество.
- Некоторые жалуются на объём кода и хранилище (десятки ТБ трейсов за неделю), другие считают это разовой настройкой и платой за прозрачность системы.
- Появляются упрощающие обёртки (Logfire, otelize) и примеры интеграции, но документация по дашбордам Grafana всё ещё вызывает трудности.
Running our Docker registry on-prem with Harbor
Мы перенесли Docker-реестр в собственный дата-центр на Harbor, отказавшись от Docker Hub и ECR.
Причины: счета за лицензию и трафик, 45-секундные задержки деплоя, риски утечек, лимиты API.
Критерии нового решения: надёжность, скорость, простота, open-source.
Выбрали Harbor: богаче функций, чем «голый» distribution, ставится через docker-compose.
v1-дизайн
- Хранилище: S3-совместимый Pure FlashBlade.
- Две независимые копии в Ashburn и Chicago (пока без HA PostgreSQL/Redis).
- Политики очистки для экономии места.
Минимальные права на бакет
s3:AbortMultipartUpload, DeleteObject, GetBucketLocation, GetObject, ListBucket, ListBucketMultipartUploads, ListMultipartUploadParts, PutObject
harbor.yml (фрагмент)
hostname: "#{node['fqdn']}"
http: { port: 80 }
data_volume: /data
storage_service:
s3:
bucket: docker-registry-bucket
accesskey: "#{bucket_credentials['access_key']}"
secretkey: "#{bucket_credentials['secret_key']}"
regionendpoint: "https://purestorage.#{node['domain']}"
metric: { enabled: true, port: 9090, path: /metrics }
Конфиг разворачивается Chef на выделенных нодах, SSL-терминация на F5.
Комментарии (59)
- Harbor удобен: SSO, Terraform-провайдер, но нет API для токена при
docker login, приходится создавать robot-аккаунты. - Ресурсы 32 CPU / 64 GB RAM выглядят завышенными для 32 000 пуллов за два месяца; скорее всего, просто оверпровижн.
- Многие используют один «источник истины» Harbor + региональные кэши или просто registry в режиме pull-through-cache.
- У Harbor нет OIDC-доступа из GitHub Actions, апгрейды ручные; Nexus проще для Maven/NuGet, но тоже прожорлив и иногда не чистит блобы.
- ECR в AWS дешёв (~3 $/мес) и без хостинга, но не on-prem; для S3-подобного хранилища советуют SeaweedFS, Garage или Pure Flashblade.
ASCIIFlow
ASCIIFlow — онлайн-инструмент для рисования ASCII-диаграмм прямо в браузере.
Быстро создаёт блок-схемы, схемы сетей и другие текстовые чертежи без установки ПО.
Комментарии (21)
- Пользователи обсуждают, что экспорт «ASCII» на деле выдаёт UTF-8, но из-за скрытых преобразований браузера/ОС это трудно проверить.
- Упомянуты похожие инструменты: Monodraw, d2 (новый ASCII-режим), graph-easy и ещё один, где диаграммы задаются собственным DSL.
- Популярный запрос — возможность рисовать без мыши: писать структуру текстом и получать ASCII-арт.
- Есть жалобы, что «Select & Move» работает не для целых фигур, а только для отдельных сегментов линий.
- Приведены ссылки на предыдущие обсуждения проекта на HN (2014–2022).
F-35 pilot held 50-minute airborne conference call with engineers before crash 🔥 Горячее 💬 Длинная дискуссия
- Инцидент: F-35A разбился в Аляске 28 мая 2024 г.; пилот катапультировался.
- Предшествие: за 50 мин до крушения летчик по радио обсуждал с инженерами проблемы с системами.
- Причина: предварительно — отказ вспомогательной силовой установки и гидравлики.
- Расследование: продолжается; ВВС подтвердили факт конференц-связи.
Комментарии (340)
- Пилот не участвовал в конференц-связи; советы давали инженеры Lockheed Martin.
- Причиной аварии стало замерзание воды в гидравлике амортизаторов, а не в приводах.
- После второго «touch-and-go» датчики «веса на колёсах» ошибочно перевели самолёт в режим «на земле», и пилот потерял управление.
- В системе оказалось ≈ ⅓ воды, чего быть не должно; источник загрязнения вызывает вопросы.
- Не было очевидного способа принудительно вернуть самолёт в «режим полёта».
- Комментаторы критикуют чрезмерную автоматизацию, высокую стоимость F-35 и качество журналистики CNN.
How to slow down a program and why it can be useful
-
Зачем замедлять программу?
Искать race-conditions, «виртуально» оценить выгоду оптимизации (как в Coz) и проверять точность профилировщиков. Для этого меняют расписание потоков или вставляют задержки. -
Как замедляют сейчас?
Грубо:Thread.sleep, остановка потоков, вставка лишнего байт-кода. Это снижает точность. -
Наша идея
Вставлять задержки внутри basic block на уровне x86. Нужны инструкции, которые:
– надёжно тратят циклы;
– не искажают семантику;
– не оптимизируются CPU за счёт out-of-order. -
Проблема
Современные процессоры выполняют независимыеmovпараллельно, поэтому просто добавить «тяжёлые» команды недостаточно — нужно учитывать зависимости и микроархитектуру.
Комментарии (50)
- Используются разные способы замедления: от NOP-циклов и RDTSC до AVX-нагрузок и «тормозных» устройств вроде C64 Snail или Turbo-кнопки.
- Замедление помогает выявлять N+1-запросы, неработающие кеши и другие узкие места, которые на быстрых машинах незаметны.
- Современные CPU оптимизируют NOP/MOV на стадии переименования, поэтому они плохо подходят для точного контроля времени.
- Causal-profiling (Coz) и специальные прокси (Toxiproxy, dummynet) позволяют «ускорять» выбранный код, оставляя остальное медленным, чтобы заранее оценить выгоду оптимизации.