HeadlinesBriefing HeadlinesBriefing.com

Traits в Zig: абстракция времени компиляции

Hacker News •
×

В последнее время у меня появилось больше времени на написание кода на Zig, и это пошло на пользу душе. В этой статье делятся идеями об абстракциях в Zig, включая приёмы, которые автор нашёл полезными, но которые редко применяются шире.

О интерфейсах Zig написано немало, и вполне заслуженно. Хотя интерфейсы не являются языковой возможностью, они де-факто служат способом реализации полиморфизма времени выполнения в Zig. Много говорилось и о comptime в Zig, о том, как его можно использовать, чтобы избежать проблем производительности динамической диспетчеризации и писать изящный код, ориентированный на данные.

Полиморфизм в Zig обычно достигается одним из двух способов. Динамические интерфейсы используют непрозрачные указатели, таблицы виртуальных методов и динамическую диспетчеризацию для полиморфизма времени выполнения. Утиная типизация времени компиляции использует рефлексию типов, операторы switch и мономорфизацию на этапе компиляции для статического полиморфизма. Такой подход оказался эффективным, но не лишён компромиссов. Интерфейсы предлагают контракты типов, знакомые по другим языкам, однако, будучи модульными во время выполнения, они создают жёсткий барьер для компилятора и, следовательно, накладные расходы на производительность. Для критичного к производительности кода Zig обычно опирается на утиную типизацию времени компиляции, которая выявляет нарушения интерфейса на этапе компиляции, но всё же требует тщательного документирования контракта.

Разработчикам, пришедшим из трейтов Rust или типклассов Haskell, такая схема может показаться упрощённой, и Zig действительно стремится к простоте. Автор утверждает, что при небольшой адаптации в пользовательском пространстве Zig возможны аналогичные абстракции над типами. Предложение состоит в новом соглашении о задании контрактов типов времени компиляции в виде Traits, не требующем библиотек и дополнительных механизмов. Оно вдохновлено функциональным программированием в целом и OCaml в частности.

Trait определяется как структура времени компиляции, содержащая связанные функции над заданным типом. В статье это иллюстрируется трейтом Reducer для свёртки, где тип образует редуктор при пустом значении и операции объединения. Отдельные трейты sum и product для i32 показывают, как одну и ту же обобщённую логику reduce можно переиспользовать, причём компилятор может встраивать и разворачивать цикл. Автор заключает, что трейты — это просто мешок удовольствия.

Источник: Hacker News · Сводку подготовил HeadlinesBriefing