A comparison of Ada and Rust, using solutions to the Advent of Code 🔥 Горячее 💬 Длинная дискуссия
В репозитории представлено детальное сравнение решений Advent of Code 2023, где анализируются подходы к решению задач, эффективность кода и производительность. Основное внимание уделено различиям в алгоритмах и структурах данных, используемых участниками, а также их влиянию на время выполнения и потребление памяти.
Приводятся конкретные примеры кода на разных языках программирования, демонстрирующие оптимизации и trade-offs. Упоминаются ключевые инсайты, такие как важность выбора правильных структур данных для сокращения сложности алгоритмов. Это полезно для разработчиков, стремящихся улучшить свои навыки решения алгоритмических задач.
Комментарии (196)
- Участники отмечают сильные стороны Ada, такие как ограниченные числовые типы для предотвращения ошибок, выразительная система типов и удобочитаемость, но сожалеют о его недостаточном распространении вне сообщества safety-critical разработки.
- Rust ценится за безопасность памяти, фокус на надежности и растущую экосистему, но критикуется за отсутствие формальной спецификации (хотя она сейчас разрабатывается) и сложность с компилятором и асинхронностью.
- Поднимаются вопросы о различиях в подходах к строкам (Ada использует массивы символов, Rust — UTF-8), многопоточности (встроенные потоки vs. async) и индексации массивов (произвольные типы в Ada vs. словари в Rust).
- Обсуждаются практические аспекты: скорость компиляции, поддержка Unicode, необходимость спецификаций и влияние экосистемы (инструменты, библиотеки) на выбор языка.
- Упоминаются нишевые применения Ada (например, в 3D-печати) и потенциальные заимствования его функций (ограниченные типы) в другие языки, такие как Rust, C++ и Nim.
UTF-8 history (2003)
Роб Пайк рассказывает, как Кен Томпсон изобрёл UTF-8 за один вечер, и как они вместе внедрили его в систему менее чем за неделю.
В 1992 году, во время ужина в Нью-Джерси, Томпсон придумал битовую упаковку UTF-8. Изначально в Plan 9 использовалась кодировка UTF от ISO 10646, но она была неудобной. После звонка от представителей IBM и X/Open, которые просили оценить их проект FSS/UTF, Пайк и Томпсон предложили создать улучшенный стандарт.
За ночь Томпсон написал код для упаковки и распаковки, а Пайк адаптировал библиотеки. К пятнице Plan 9 уже полностью работал на UTF-8. X/Open принял их предложение, отказавшись от собственного FSS/UTF из-за недостатка синхронизации в потоке байтов.
Пайк опровергает миф о том, что UTF-8 разработала IBM, а Plan 9 лишь реализовала его, ссылаясь на архив переписки, подтверждающий их авторство.
Комментарии (35)
- Обсуждаются исторические и социально-экономические причины доминирования США в ранней компьютерной индустрии, включая военные разработки и инфраструктуру.
- Выдвигается гипотеза о преимуществе англоязычного мира из-за простого алфавита без диакритиков по сравнению с такими языками, как китайский или хинди.
- Подробно разбирается история создания UTF-8 и критикуется решение Microsoft использовать в Windows NT кодировку UCS-2 вместо UTF-8, названное "ошибкой на миллиард долларов".
- Участники отмечают, что ранние компьютерные кодировки (6-битные, ASCII) наследовали принципы докомпьютерных эпох (телетайпы, перфокарты).
- Обсуждается влияние разных алфавитов на технологическое развитие, проводятся параллели с историей книгопечатания в Европе и Китае.
- Упоминается, что стандартизация Unicode и UTF-8 была сложным процессом с участием нескольких конкурирующих организаций.
- Отмечаются практические проблемы, вызванные использованием в Windows кодировок CP-125X вместо UTF-8, и наследие этого решения в виде API-функций с суффиксами "A"/"W".
- Приводится ссылка на RFC 3629, который ограничил UTF-8 4 байтами на символ, отказавшись от первоначальной поддержки 5- и 6-байтных последовательностей.
UTF-8 is a brilliant design 🔥 Горячее 💬 Длинная дискуссия
UTF-8 — гениальное решение: 1–4 байта на символ, полная совместимость с 7-битным ASCII.
Старший бит первого байта сразу говорит, сколько байт идёт дальше:
| Паттерн 1-го байта | Длина | Пример |
|---|---|---|
0xxxxxxx |
1 | ASCII |
110xxxxx |
2 | |
1110xxxx |
3 | |
11110xxx |
4 |
Продолжения всегда 10xxxxxx.
Программа читает байт, по префиксу понимает длину, выделяет «полезные» биты, получает кодовую точку Unicode и выводит символ.
Пример:
хинди «अ» = 11100000 10100100 10000101 → U+0905.
Файл Hey👋 Buddy (13 байт):
H e y 👋 B u d d y
👋 кодируется 4 байтами 11110000 10011111 10010001 10001011 → U+1F44B.
Комментарии (305)
- UTF-8 — гениальное, простое и обратно-совместимое с ASCII решение, придуманное Кеном Томпсоном и Робом Пайком за ужином.
- Продолжение-байты
10xxxxxxпозволяют за O(1) найти границы символа, не парся весь поток. - Критика: Unicode «раздулся» (комбинирующие символы, эмодзи, 25-байтовые «графемы»), а UTF-8 не сам компактен для нелатиницы.
- Спор о «переполнении»: 4 байт хватает на 21 бит → 2 097 152 кодовых точек; 5-6 байт запрещены специально.
- Некоторые считают, что красота UTF-8 — не комитетное изобретение, а удачный частный хак, вышедший в мировой стандарт.
A new experimental Go API for JSON
Новый экспериментальный JSON-API в Go
Go 1.25 предлагает encoding/json/v2 и encoding/json/jsontext — переработанные пакеты для работы с JSON. Они решают давние проблемы стандартного encoding/json и пока доступны только по флагу GOEXPERIMENT=jsonv2.
Главные недостатки старого API
- Неточности синтаксиса: принимает невалидный UTF-8, дублирует ключи, трактует числа как float64.
- Производительность: 2-3× медленнее современных альтернатив; каждый вызов тратит память на рефлексию.
- Гибкость: нельзя пропустить неизвестные поля, работать с потоковым JSON, получать исходный текст, сохранять порядок ключей, использовать сторонние типы.
Что нового в v2
-
Три пакета
–jsontext— низкоуровневое чтение/запись токенов, сохраняет формат.
–json— высокоуровневый marshal/unmarshal, совместим с v1, но строже и быстрее.
–jsontextможно использовать отдельно для потоковой обработки. -
Строгость
UTF-8 проверяется, дубли ключей — ошибка, числа не теряют точность. -
Производительность
Без рефлексии в hot-path, 2-3× быстрее, меньше аллокаций. -
Новые возможности
Пропуск неизвестных полей, сохранение порядка, работа сany, доступ к сырому JSON, совместимость с v1 через теги.
Как попробовать
GOEXPERIMENT=jsonv2 go mod download
import "encoding/json/v2"
Фидбек приветствуется: golang.org/issue/71497.
Комментарии (82)
- Вышел экспериментальный
encoding/json v2: новый API, лучшая производительность, но спорные решения по nil-значениям. - Часть пользователей рада росту скорости и модульному пакету
jsontext; другие считают, что костыли сnil → nullостались. - Кто-то уже прогнал тысячи тестов — почти всё прошло; кто-то нашёл регрессию аллокаций. Авторы просят больше отзывов.
- Сравнения со сторонними библиотеками (Sonic, goccy) показывают выигрыш в CPU, но проигрыш в безопасности и поддержке ARM.
- Обсуждение выродилось в холивар: «почему за 15 лет JSON до сих пор не решён» vs «две v2 за всю историю — отличный результат».
Show HN: Writing Arabic in English
Как я сделал фонетическую арабскую клавиатуру
Фонетическая раскладка — это когда английские клавиши отображаются на арабские звуки.
Проблемы: арабский пишут справа налево, буквы сочетаются в слове, 11 букв не имеют англогодных пар и ещё есть «хамза» и диакритики.
- RTL:
direction: rtl;— готово. - Скрипт: браузер сам стыкует буквы (Safari требует ZWJ).
- Прямые пары (17 букв):
b→ ب,t→ ت,s/c→ س и т. д. - «Эмфатические» (5): произносятся в глотке, похожи на базовые, но «сильнее». Назначил заглавные:
H→ ح,S→ ص,D→ ض,T→ ط,Z→ ظ. - «Уникальные» (6): добавляем точки к уже назначенным.
sh→ ش (с + 3 точки),th→ ث (т + 3 точки),dh→ ذ (д + 1 точка),kh→ خ (ḥ + 1 точка),3→ ع,gh→ غ (ع + 1 точка).
Код: две таблицы — обычная и шифт; по нажатию выбираем нужную и отдаём UTF-символ.
Комментарии (15)
- Обсуждение крутится вокруг новой «арабской QWERTY»-раскладки, которая привязивает арабские буквы к латинским по принципу транслитерации (ع → e рядом с 3, ش → shift+S и т.д.).
- Пользователи сравнивают проект с уже существующими решениями: Yamli (2005), Buckwalter, SATTS, старым Windows-переводчиком и даже пиньинь-вводом для китайского.
- Главный аргумент «за» — не нужны наклейки на клавиатуре: запоминаешь английскую букву и сразу получаешь арабскую.
- Некоторые ждали именно «чат-транслит»-режима (3=ع, 7=ح, 2=ء), но авторы делают упор на полноценную клавиатуру, а не на транслитерацию текста.
- В итоге идею признают полезной для изучающих язык и для быстрого набора без смены раскладки, но отмечают, что подобные инструменты существуют уже два десятилетия.
ASCIIFlow
ASCIIFlow — онлайн-инструмент для рисования ASCII-диаграмм прямо в браузере.
Быстро создаёт блок-схемы, схемы сетей и другие текстовые чертежи без установки ПО.
Комментарии (21)
- Пользователи обсуждают, что экспорт «ASCII» на деле выдаёт UTF-8, но из-за скрытых преобразований браузера/ОС это трудно проверить.
- Упомянуты похожие инструменты: Monodraw, d2 (новый ASCII-режим), graph-easy и ещё один, где диаграммы задаются собственным DSL.
- Популярный запрос — возможность рисовать без мыши: писать структуру текстом и получать ASCII-арт.
- Есть жалобы, что «Select & Move» работает не для целых фигур, а только для отдельных сегментов линий.
- Приведены ссылки на предыдущие обсуждения проекта на HN (2014–2022).
RFC 9839 and Bad Unicode
RFC 9839 и плохой Unicode
Unicode хорош, но не все его символы. Часто приходится исключать «проблемные». Чтобы формализовать это, мы с Полом Хоффманом написали черновик, и теперь он стал RFC 9839 — всего 10 страниц, читайте, если проектируете текстовые поля.
Пример боли: JSON-поле username может содержать:
U+0000— нулевой байт, ломает языки;U+0089— устаревший C1-контрол «HTJ»;U+DEAD— несвязанный суррогат, запрещён в UTF-8;U+7FFFF— «noncharacter», не должен передаваться.
RFC 9839 перечисляет такие категории и предлагает три готовых подмножества, которые можно просто запретить.
Не вините Дуга Крокфорда: JSON создавался раньше, когда Unicode был молод. Но теперь нужен способ явно сказать «эти символы не нужны».
PRECIS (RFC 8264, 2002) уже решал похожую задачу, но 43 страницы сложностей и привязка к конкретной версии Unicode мешают внедрению. RFC 9839 проще и тупее — и, возможно, именно поэтому пригодится.
Комментарии (122)
- Участники спорят, нужно ли на уровне JSON/протокола запрещать «плохие» символы Unicode (управляющие, суррогаты, заломы направления и т. д.) или оставить это прикладной валидации.
- Одни считают, что жёсткие ограничения защищают от ошибок и атак (RTL-override, залого-текст, сломанные UTF-16-реализации).
- Другие указывают на полезные кейсы C0-символов (EOF, ESC, разделители) и опасаются, что «закрыть и забыть» приведёт к 20-летней несовместимости (эмодзи, старые файлы).
- Ссылаются на RFC 8264/9839 и PRECIS-фреймворк как готовый список «что разрешать», но подчёркивают: правило должно быть явным, а не «тихо удалять».
It’s not wrong that "\u{1F926}\u{1F3FC}\u200D\u2642\uFE0F".length == 7 (2019) 💬 Длинная дискуссия
В JavaScript "🤦🏼♂️".length == 7 — не ошибка, а результат подсчёта UTF-16 кодовых единиц.
Эмодзи состоит из 5 скалярных значений Unicode, но в UTF-16 они занимают 7 code units:
- 🤦 U+1F926 → 2
- 🏼 U+1F3FC → 2
- ZWJ U+200D → 1
- ♂ U+2642 → 1
- VAR-16 U+FE0F → 1
Итого 7 — именно это и возвращает .length.
Другие языки считают по-своему:
- Python 3 →
len("🤦🏼♂️") == 5(кодовые точки, но допускает суррогаты). - Rust →
"🤦🏼♂️".len() == 17(байты UTF-8). - Swift →
"🤦🏼♂️".count == 1(расширенный графем-кластер).
Каждый подход отвечает на свой вопрос: «сколько code units / bytes / графем». Ни один не универсален; выбор зависит от задачи.
Комментарии (233)
- Обсуждение вокруг статьи показало, что «длина строки» не имеет единого определения: бывают байты, UTF-16/UTF-32 код-юниты, скалярные значения Unicode и расширенные графем-кластеры.
- Пользователи жалуются, что разные языки и API возвращают разные числа для одного и того же эмодзи, что ломает UI-ограничения, индексы БД и обработку текста.
- Часть участников считает, что нужно явно различать «длину для хранения», «длину для отображения» и «длину для человека»; другие мечтают вернуться к чистому ASCII.
- Примеры кода на Java, Python, Raku и JS показывают, как получить каждый из вариантов длины, но подчеркивают отсутствие общего стандарта.
- Итог: «length» — слишком расплывчатое слово; без контекста использования любое его значение может оказаться не тем, что действительно нужно.
We'd be better off with 9-bit bytes 💬 Длинная дискуссия
-
В 70‑х некоторые системы (например, PDP‑10) имели 9‑битовые байты, но стандарт закрепился за 8 битами. Если бы байт был 9‑битным, ряд исторических случайностей сыграли бы нам на руку.
-
IPv4: при 9‑битовых байтах адрес IPv4 был бы 36‑битным (~64 млрд адресов). Этого хватило бы до 2030‑х без массового NAT и тормозов с IPv6; позже проблему решили бы мягкими рыночными механизмами.
-
UNIX time: 32‑битные метки ломаются в 2038, а 36‑битные прожили бы до 3058. Отрицательные охватывали бы времена с 882 года — достаточно для исторических нужд.
-
Юникод: вместо 16‑битных 65 тыс. символов было бы 18‑битных 262 тыс. — хватило бы без болезненной унификации CJK; сейчас всех символов ~155 тыс. UTF‑9 стал бы скорее компрессией и уступил бы GZip; либо однобайтно‑двухбайтная схема при умеренной экономии на эмодзи.
-
Указатели и память: 36‑битные ОС дали бы до 32 ГБ на процесс (вместо 2 ГБ у 32‑битных). Серверы всё равно виртуализируют; меньшие указатели экономят память и ускоряют код, хотя строки стали бы длиннее — общий баланс близок к нулю.
-
Прочие выигрыши:
- 18‑битные AS‑номера не иссякли бы; порты/PID/UID просторнее.
- Кодирование инструкций x86/A64 чуть опрятнее; Thumb работал бы лучше.
- Полуточные 18‑битные числа прижились бы раньше; экзотика 4–5 бит не взлетела бы.
- Расширенный ASCII влез бы с греческим и стал бы «натовской» кодовой страницей; UTF‑9 привилегировал бы почти всю Западную Европу.
- Права Unix умещались бы в один байт (без «липких» битов). Оctal стал бы нормой вместо hex.
- 18‑битный цвет 6/6/6 даёт различия на грани восприятия; потеря альфа‑канала неприятна.
-
Издержки? Существенных нет: адресация по битам не используется; деления на девять не требуется; размеры страниц/блоков ОС могли бы остаться прежними, ядру не пришлось бы менять основы работы.
Комментарии (314)
- Обсуждение крутится вокруг гипотетического мира с 9-битными байтами: часть участников отмечает аппаратную неудобность непоказательных (не 2^n) размеров и сложность для мультипликаторов, адресации и сдвигов.
- Скептики считают аргументы «добавим по одному биту и всё станет лучше» натянутыми: решения о размерах всё равно принимались бы иначе, а выигрыш в 12.5% не компенсирует издержки и усложнение.
- Приводятся исторические примеры: PDP-8/10 с 12/36-битными словами, 6-битные коды, термин «octet» для однозначности; упоминается даже N64 с «внутренними» 9-битными байтами для GPU.
- По сетям: 36-битный IPv4 дал бы ~64 млрд адресов, но это лишь отсрочка дефицита; проблемы ASLR и безопасности 32-битной адресации 36 битами решаются слабо, переход на 64 бита всё равно был бы.
- Есть идеи альтернатив: 10-битные байты, тернарные системы, 9-й бит как признак продолжения для варинтов/инструкций, либо как служебный (ECC/контроль/метка данных).
- Отмечают экономику кремния: лишние провода/логика удорожают дизайн; если уже расширять шину, логичнее идти к степеням двойки (например, к 16 битам на «байт»).
- Итоговый тон дискуссии: 9 бит могли бы немного смягчить отдельные «почти-не-хватает» пороги (16/32-бит), но в целом это привнесло бы больше сложностей, чем пользы; ключ — лучше прогнозировать размеры, а не «маскировать» ошибки лишним битом.