Как стать автором
Обновить

Комментарии 8

Про собственный компилятор Эндрю говорил на одном из последних стримов немного в другом ключе. Они собираются его выкатить для того чтобы ускорить дебажные сборкии, чтобы начать быстрее разгребать беклог, который растет сильно быстрее чем они могут с ним справиться. Одной из главных причин он называл медленную итерацию из-за скорости llvm при сборке промежуточных билдов. Собственный компилятор должен дать супер быструю сборку в debug режиме, на одной десктопной платформе, не более того. А отказываться от llvm совсем, они точно не собираются, поскольку для сборки тех же релизных билдов, да еще и под пару десятков железных архитектур они точно никогда такой компилятор не осилят. Так же терять interop с С/C++, который прям киллер фича, тоже такая себе затея.

Я может быть утрирую в статье, не отрицаю. Но уже сейчас по описанию самих авторов, цитата

Zig now generates LLVM bitcode module files directly and then passes those to LLVM. This means that a Zig compiler built without LLVM libraries can still produce .bc files, which can then be passed to clang for compilation.

Для меня это означает, что они теперь могут попробовать реализовать свой «конвертер» байткода в машинные инструкции. Я не буду утверждать, что речь об этом шла, так как я не смог найти ссылки на подтверждение. Но когда-то давно об этом речь заходила. Не в ключе замены, а в ключе критики LLVM. Типа LLVM штука крутая, но имеет свои особенности.

И так же, цитата

Async functions regressed with the release of 0.11.0 (the previous release to this one). Their future in the Zig language is unclear due to multiple unsolved problems:

  • LLVM's lack of ability to optimize them.

То есть у них есть причины отказа от LLVM. Посмотрим, что будет

Zig Roadmap 2024, первоисточник так сказать, тут интересный сегмент начинается на 4:00 и заканчивается в районе 20:00.

Вы не подумайте, я не спора ради, а скорее про то что изначальная причина в моём понимании немного другая.

Про последнее где LLVM's lack of ability to optimize them. Да, очевидно что проблемы с LLVM есть, и вероятно далеко не последние. Просто масштаб этих проблем не сопоставим. Да llvm не умеет чего-то делать так как им нужно. Но написать адаптер, который будет транспайлить код на Zig в тот же C, и затем скомпилировать это с помощью того же LLVM всё ещё сильно проще чем писать что-то своё. Опять таки, речь и в стриме и в релиз ноутах идёт именно про Debug сборки, для десктопов.

По вашей же ссылке чуть ниже написано:

These problems are surmountable, but it will take time.

В общем причины для отказа есть, но я готов поставить все $7 на то что они от него не откажутся, пока LLVM будет актуален в других местах и будет развиваться.

В остальном держу кулачки за Zig, классная штука. Пусть я на нём и не пишу но тулчейн для своих поделок на С++ использую. Спасибо что занимаетесь популяризацией данного проекта в рунете!

Вы не подумайте, я не спора ради, а скорее про то что изначальная причина в моём понимании немного другая.

У меня никаких претензий. Я легко принимаю свою неправоту. И без проблем могу извиниться, если где-то наврал.

По видео их цель упростить себе работу, и это верно, но на видео их доска называется «Ditch LLVM». Вероятнее всего в версии 0.13.0 будет сделано только часть. И этим сложно не согласиться. При чём, дальше по видео на слайдах видно их цель для инкрементальной компиляции в блоке In-house Backend. Строка «No LLVM». И сам Эндрю Келли своими словами (тайм код) говорит о том, что они ведут исследования в этом направлении. То есть, я не на что не намекаю, и это не претензия к вам, так как вы можете быть правы в том числе, что не всё будет сделано до релиза 0.13.0. Но уточню, что об этом речь шла ранее. Я не смог найти статью, где было упоминание этого ранее, чтобы это можно было добавить в мою статью. Может быть это даже было где-то в телеграме или дискорде. Но я информацию о выпиливании LLVM не из воздуха взял. То есть разработчики языка Zig работают в этом направлении.

Можно в функции вернуть структуру, как тип, и это станет новым типом. И за счёт этого механизма по сути и создаются новые типы. Невероятно мощная штука. Практически киллер-фитча.

А можно здесь поподробнее?

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

Пример создания нового типа взят из стандартной библиотеки:

pub fn Once(comptime f: fn () void) type {
    return struct {
        done: bool = false,
        mutex: std.Thread.Mutex = std.Thread.Mutex{},

        pub fn call(self: *@This()) void {
            if (@atomicLoad(bool, &self.done, .Acquire))
                return;

            return self.callSlow();
        }

        fn callSlow(self: *@This()) void {
            @setCold(true);

            self.mutex.lock();
            defer self.mutex.unlock();

            if (!self.done) {
                f();
                @atomicStore(bool, &self.done, true, .Release);
            }
        }
    };
}

Ключевое слово type здесь как раз выступает эдаким указателем компилятору, что функция возвращает новый тип, который будет создан из того, что программист отправит в возврате.

Если вызвать в коде

const SomeThingOnceExecutor = Once(doSomeThing);
const OtherThingOnceExecutor = Once(doOtherThing);

то это станет новыми типами. doSomething и doOtherThing здесь ссылки на функции, которые должны быть известны на этапе компиляции.

И потом можно создавать «объекты» с этими типами. И вызывать методы этих типов

var some_thing_executor = SomeThingOnceExecutor{};
some_thing_executor.call();

var other_thing_executor = OtherThingOnceExecutor{};
other_thing_executor.callSlow();

Вообще в Zig присутствует рефлексия, и она достаточно серьёзная, но я в ней не разбираюсь пока ещё. Потому более крутые примеры не могу предоставить

То есть по сути это вывод типов. Но тип строится из того, что возвращает функция. И тип, как я понимаю, номинативный, а не структурный. Интересная фича.

Я честно напишу, что не понял, что такое «номинативный». Пришлось гуглить. Век живи, век учись, как говориться.

Я упомянул ниже в комментарии, что в языке Zig есть достаточно серьёзная рефлексия и выглядит она примерно так:

const T2 = @Type(.{ .Struct = .{
  .fields = std.meta.fields(T),
  .is_structural = true,
}});

То есть по сути можно создавать тип, описывая его. Я как раз этот вид рефлексии не знаю хорошо. И не смог найти хороший пример из стандартной библиотеки. Взял этот:

pub fn isSlice(comptime T: type) bool {
    if (comptime is(.Pointer)(T)) {
        return @typeInfo(T).Pointer.size == .Slice;
    }
    return false;
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории