LINUX.ORG.RU

Zig 0.11

 , ,


1

3

Спустя 8 месяцев и 4457 коммитов от 269 различных участников вышла новая версия Zig.

Zig — это (кросс-)компилятор языков программирования Zig, С++, С, Objective-C, Objective-C++, а также сборочная система и менеджер пакетов для них. Проект разрабатывается под лицензией MIT. Недавно в Zig Core Team вошёл ещё один разработчик на зарплате: Jacob Young.

В новой версии:

  • Появился пакетный менеджер.
  • Улучшена поддержка powerpc, powerpc64le и Plan9.
  • Архитектура i386 переименована в x86.
  • Множественные улучшения и исправления для WebAssembly и появление специфичного для него аллокатора wasm_allocator.
  • Реализация компилятора Zig на Zig (self-hosted) полностью готова, а старый компилятор на C++ «выкинут на орбиту» (требования к ОЗУ для сборки снижены с 11 до 4 ГБ).
  • Обновлены сторонние компоненты:
    • LLVM 16.0.6;
    • musl 1.2.4;
    • wasi-libc 3189cd1ceec8771e8f27faab58ad05d4d6c369ef;
  • Множество изменений в стандартной библиотеке (подробнее).

>>> Подробности

anonymous

Проверено: cetjs2 ()
Последнее исправление: cetjs2 (всего исправлений: 3)

fn LinkedList(comptime T: type) type {
    return struct {
        pub const Node = struct {
            prev: ?*Node,
            next: ?*Node,
            data: T,
        };

        first: ?*Node,
        last:  ?*Node,
        len:   usize,
    };
}

pub fn main() void {
    var node = LinkedList(i32).Node {
        .prev = null,
        .next = null,
        .data = 1234,
    };

    var list = LinkedList(i32) {
        .first = &node,
        .last = &node,
        .len = 1,
    };
}

это похоже на самый отмороженный диалект жаваскрипта для ИЕ, а хочется как у Хуго Босс

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 1)

Поздравляю всех причастных. Выглядит очень интересно, но непонятно, можно ли уже в прод затянуть чтобы потом не краснеть перед командой и начальством. Фанаты, разумеется, скажут «можно», но их мнение как раз не аргумент.

whereisthelinus
()

Это такой троллинг для сишников чтоли?

const mem = @import("std").mem;
const pattern = "ab" ** 3;
mem.eql(u8, pattern, "ababab")
alex0x08 ★★★
()
Ответ на: комментарий от snake266

Чем лучше-то? Тем, что rust синтаксис только обратной польской нотацией? Или что тогда вот это ?*Node?

Aswed ★★★★★
()

Хорошая новость. Главное, чтобы кроме них кто-нибудь пользовался.

xwicked ★★☆
()
Ответ на: комментарий от Syncro

а хочется как у Хуго Босс

А вышло как у Жана Поля не Сартра Готье в фильме «Пятый элемент», смесь Objective C с Питоном :)

gns ★★★★★
()

Всем салам, только что зарегался специально под новость (как только увидел). Довольно странно, шо очень похоже на предыдущую новомть по формату, ну да ладно.

BratishkaErik
()

с одной стороны вроде все правильно делают, вот и llvm хотят выкинуть и запилить полностью свой компилятор, с другой - какие-то у них загоны. Вместо того чтобы признать что таки да, указатель может быть нулем и ничего ты с этим не сделаешь, они фигачат какой-то наркоманский синтаксис вроде вот этого ?*Node.

Или обработка ошибок - ну нельзя сделать ничего нормального на кодах возврата. Да и не на кодах тоже, это целиком ответственность разработчика а не компилятора. В zig опять же отказываются это признать и фигачат какие-то orelse, которые только мешают…

Lrrr ★★★★★
()
Ответ на: комментарий от Aswed

?*Node Опциональный указатель на Node, всё слева направо читается (без всяких сишных спиралек) :)

BratishkaErik
()
Ответ на: комментарий от BratishkaErik

ну я и говорю, какие-то мусорные специальные ключевые слова и касты, в которых потом весь код будет. Если юзерам так нужны ненулевые указатели (спойлер, они им нафиг не нужны), они могут сделать нужные структуры на уровне своих юзерских библиотек, зачем этим язык-то замусоривать?

Lrrr ★★★★★
()
Ответ на: комментарий от Lrrr

Что-то вспомнилась древняя телега времен моего программистского детства (да и просто детства, судя по дате написания) :)

http://hosting.vspu.ac.ru/~chul/humor/babbage/babbage.htm

gns ★★★★★
()
Последнее исправление: gns (всего исправлений: 1)
Ответ на: комментарий от Lrrr

чёт сообщение не редактируется, ну ладно.

спойлер, они им нафиг не нужны

Нужны, и в Сишке нужны, оттого и пользуется народ всякими

__attribute__((notnull(blablabla)))

Здесь им просто уделили больше внимания и ээ любви.

на уровне своих юзерских библиотек

Помянем экосистему, эргономичность и возможности для оптимизации компилятором… :свечка: Вообще если кто-то хочет сравнить (офк приблизительно) код на Зиге и Си, у меня тут маленькая обвязка над libgccjit есть, туториалы плюс-минус строка в строку портировал (я не мастер Zig, так шо код может где-то страшно выглядеть):

https://git.sr.ht/~bratishkaerik/zig-libgccjit/tree/3c21e0bf8d9f4462f79059da1320679e012eafd0/item/examples/official_tutorial_part_1/src/main.zig

fn create_code(ctxt: *GccJit.Context) void {
    // Let's try to inject the equivalent of following function:

    // C form:
    // void
    // greet (const char *name)
    // {
    //    printf ("hello %s\n", name);
    // }

    // C-in-Zig form:
    // fn greet(name: [*:0]const u8) callconv(.C) void {
    //    printf("hello %s\n", name);
    // }

    const void_type: *GccJit.Type = ctxt.getType(.void);
    const const_char_ptr_type: *GccJit.Type = ctxt.getType(.const_char_ptr);
    const param_name: *GccJit.Param = ctxt.newParam(.no_location, const_char_ptr_type, "name");
    const func: *GccJit.Function = ctxt.newFunction(.no_location, .exported, void_type, "greet", @constCast(&[_]*GccJit.Param{param_name}), .not_variadic);

    const param_format: *GccJit.Param = ctxt.newParam(.no_location, const_char_ptr_type, "format");
    const printf_func: *GccJit.Function = ctxt.newFunction(.no_location, .imported, ctxt.getType(.int), "printf", @constCast(&[_]*GccJit.Param{param_format}), .variadic);
    var args: [2]*GccJit.Rvalue = undefined;
    args[0] = ctxt.newStringLiteral("hello %s\n");
    args[1] = param_name.asRvalue();

    const block: *GccJit.Block = func.newBlock(.no_name);

    block.addEval(.no_location, ctxt.newCall(.no_location, printf_func, &args));
    block.endWithVoidReturn(.no_location);
}

https://gcc.gnu.org/onlinedocs/gcc-12.2.0/jit/intro/tutorial01.html

  /* Let's try to inject the equivalent of:
     void
     greet (const char *name)
     {
        printf ("hello %s\n", name);
     }
  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *const_char_ptr_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR);
  gcc_jit_param *param_name =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name");
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "greet",
                                  1, &param_name,
                                  0);

  gcc_jit_param *param_format =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format");
  gcc_jit_function *printf_func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_IMPORTED,
				  gcc_jit_context_get_type (
				     ctxt, GCC_JIT_TYPE_INT),
				  "printf",
				  1, &param_format,
				  1);
  gcc_jit_rvalue *args[2];
  args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n");
  args[1] = gcc_jit_param_as_rvalue (param_name);

  gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);

  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call (ctxt,
                              NULL,
                              printf_func,
                              2, args));
  gcc_jit_block_end_with_void_return (block, NULL);
BratishkaErik
()
Ответ на: комментарий от gns

Это, во-первых, надо читать в оригинале, поскольку «строгая печать» (гы-гы) это strong typing, т.е. строгая типизация.

А во-вторых их попытки постебаться довольно глупые, т.к. там либо полный бред написан, либо полезные конструкции (к примеру, OR ELSE вполне себе полезная вещь, даже так, как она там на русском описана).

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от BratishkaErik

чёт сообщение не редактируется, ну ладно.

На этом сайте какое-то странное правило, что малозвездочным савсем вапще низзя комменты редактировать.

Ладно, теперь по делу. Ты этот язык знаешь более-менее? У меня вопросы.

1. Как там с типизацией постфактум, что обычно известно как имплементация интерфейсов или трейтов? Т.е. скажем Вася Пупкин написал класс, или даже разрабы этого зига написали свою std (как она у них там). А я хочу написать свой интерфейс (или класс, мне пофиг), и сказать: ваш класс выполняет мой интерфейс, вот смотрите: код-код-код ... . При этом править Васин класс и класс из std нельзя.

2. Как там с обработкой ошибок? Можно превращать воду в вино исключения в Optional (как он в зиге называется?) и обратно?

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Ответ на: комментарий от BratishkaErik

Для указателя на нулевой адрес есть *allowzero Node (они друг в друга кастаются ЕМНИП).

Т.е. ?*Node и *allowzero Node бинарно (т.е. в битах реальной памяти) реализованы по-разному?

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Aswed

Чем лучше-то? Тем, что rust синтаксис только обратной польской нотацией?

В расте можно заимплеменентить свой трейт как родительский трейт для чужого трейта? Для друга спрашиваю Пора бы мне выйти из анабиоза и посмотреть, во что превратился раст.

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Ответ на: комментарий от www_linux_org_ru
  1. Как там с типизацией постфактум, что обычно известно как имплементация интерфейсов или трейтов? Т.е. скажем Вася Пупкин написал класс, или даже разрабы этого зига написали свою std (как она у них там). А я хочу написать свой интерфейс (или класс, пофиг), и сказать: ваш класс выполняет мой интерфейс, вот смотрите: … .

На уровне языка никак, предварительный вердикт. Ещё предлагают добавить std.interface, но его пока тоже нет (есть кусочки в std.meta.trait по типу hasFn и прочих), и сторонние библиотеки по типу https://github.com/mov-rax/zig-validate.

  1. Как там с обработкой ошибок? Можно превращать воду в вино исключения в Optional (как он в зиге называется?) и обратно?
pub fn mayFall(smth: bool) error{Fall}!u32 {
    return if (smth) 0 else error.Fall;
}

pub fn theBestU64() ?u64 {
    const optional_u32 = mayFall(false) catch null; // ошибку в опциональный тип
    const errored_u32 = optional_u32 orelse error.WhyNull; // и обратно
    const optional_u64: ?u64 = errored_u32 catch null; // и обратно
    return optional_u64;
}

const std = @import("std");

pub fn main() void {
    @compileLog(comptime theBestU64()); // вызвать во время компиляции
    @compileLog(theBestU64()); // простой вызов во время выполнения
}

Вывод:

test.zig:15:5: error: found compile log statement
    @compileLog(comptime theBestU64()); // вызвать во время компиляции
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Compile Log Output:
@as(?u32, null)
@as(?u32, [runtime value])
BratishkaErik
()
Ответ на: комментарий от BratishkaErik

да блин, не ту версию скинул, ну ладно, вот выхлоп от него:

test.zig:15:5: error: found compile log statement
    @compileLog(comptime theBestU64()); // вызвать во время компиляции
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Compile Log Output:
@as(?u64, null)
@as(?u64, [runtime value])
BratishkaErik
()

Поддержка пяти языков,
С MIT лицензией файл,
И если один скажет Zig,
Миллионы ответят «compile!»

Smacker ★★★★
()
Ответ на: комментарий от www_linux_org_ru

Т.е. ?*Node и *allowzero Node бинарно (т.е. в битах реальной памяти) реализованы по-разному?

Нет, они реализованы одинаково (на нулевой адрес), просто:

_ = optional_node.?; // Здесь будет всунута проверка во время выполнения, что это не null, как Rust'овый unwrap при None.
// так как мы считаем указатель на нулевой адрес ошибкой и assert'аем, что её не произойдет.
_ = allowzero_node; // Здесь мы не считаем нулевой адрес ошибкой, а валидным значением, к примеру когда мы работаем над ядром ОС.

Они оба занимают нулевой адрес и по размерам в машине не отличаются от обычных указателей. Вот если вы совмещаете оба (не знаю зачем), нужно как-то разделить эти два случая, поэтому добавится дополнительный бит. Во всех остальных опциональных типах (не-указателей) дополнительный бит добавляется всегда:

comptime {
    @compileLog(@sizeOf(u64));
    @compileLog(@sizeOf(?u64));
}

Выхлоп:
```zig
test.zig:2:5: error: found compile log statement
    @compileLog(@sizeOf(u64));
    ^~~~~~~~~~~~~~~~~~~~~~~~~

Compile Log Output:
@as(comptime_int, 8)
@as(comptime_int, 16)
BratishkaErik
()
Ответ на: комментарий от BratishkaErik
comptime {
    @compileLog(@sizeOf(*u64));
    @compileLog(@sizeOf(?*u64));
    @compileLog(@sizeOf(*allowzero u64));
    @compileLog(@sizeOf(?*allowzero u64));
}

Выхлоп для 64-битной машины:

test.zig:2:5: error: found compile log statement
    @compileLog(@sizeOf(*u64));
    ^~~~~~~~~~~~~~~~~~~~~~~~~~

Compile Log Output:
@as(comptime_int, 8)
@as(comptime_int, 8)
@as(comptime_int, 8)
@as(comptime_int, 16)

Для 32-битной:

test.zig:2:5: error: found compile log statement
    @compileLog(@sizeOf(*u64));
    ^~~~~~~~~~~~~~~~~~~~~~~~~~

Compile Log Output:
@as(comptime_int, 4)
@as(comptime_int, 4)
@as(comptime_int, 4)
@as(comptime_int, 8)
BratishkaErik
()
Ответ на: комментарий от www_linux_org_ru

Да, кривость перевода мне тоже бросилась в глаза, когда я еще и не понимал, что такое строгая типизация :)

gns ★★★★★
()

Появился пакетный менеджер.

Ага, ну вот этого и ждал, как-то даже пробовать не хотелось без

umren ★★★★★
()
Ответ на: комментарий от umren

Ага, ну вот этого и ждал, как-то даже пробовать не хотелось без

Ну меня как гентушника не может это не настораживать)) И так наслышался от других мейнтейнеров о попаболи от таких языков, а тут ещё и C/C++ грозятся опакетить (как в https://github.com/ggerganov/llama.cpp/blob/93356bdb7a324a8f6570f99d02af392cd4c45796/build.zig или https://github.com/andrewrk/SDL/tree/aef95740310154ebd491bc35e0fdcd118b16ade0)… Но Эндрю вроде чуть-чуть понимает это в https://github.com/ziglang/zig/issues/14281#issuecomment-1644900436

BratishkaErik
()
Ответ на: комментарий от umren

Главное - сказать: «крэкс-пэкс-фэкс!» пакетный менеджер, потому что это самое главное!

gns ★★★★★
()
Ответ на: комментарий от Shushundr

Зиг выглядит проще, приятнее, и слабее раста – возможно за некоторыми исключениями, например обработкой исключений (pun intended, гы-гы). Но я за обоими не следил лет уже 5-10.

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Shushundr

Когда Зиг только создавался, у Rust’а версия только-только вышла версия 1.0, так что этот вопрос тогда не задавался. Это просто к слову. А так нужен, (к примеру) когда вы не особо паритесь с безопасностью (прога и так в песочнице и т.д.) и хочется просто писать код:

https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-rust.html

https://zackoverflow.dev/writing/unsafe-rust-vs-zig/

Ну и мне нравится, что он намного проще, меньше и всё такое.

https://ziglang.org/ru/learn/why_zig_rust_d_cpp/

BratishkaErik
()
Ответ на: комментарий от iron

Большинство бэнчмарков не совсем честные, потому что там для Zig (Crystal, Nim) иногда допускают то, что для C/C++/Rust запрещали (fastmath, simd и прочих). Как минимум два сайта с одинаковым оформлением грешили этим. Ну и к тому же пока что оба языка сидят на LLVM, так что это в основном его заслуга)

BratishkaErik
()

Ещё большее ненужно, чем раст (что само по себе достижение). Синтаксис как обычно напрочь отбитый. Всё по канонам, накрутка звездочек на гитхабе гарантирована.

bread
()

Улучшена поддержка powerpc, powerpc64le и Plan9.

таки powerpc* и plan9 разные вещи, в т.ч. одно может запускаться на другом.

anonymous
06.08.23 14:43:34

воу воу, полехше

etwrq ★★★★★
()
Ответ на: комментарий от bread

Пакетные менеджеры для геев.

Вообще-то ты написал это сообщение с браузера который был установлен пакетным менеджером)))

iron ★★★★★
()
Ответ на: комментарий от etwrq

таки powerpc* и plan9 разные вещи, в т.ч. одно может запускаться на другом.

Может, имелось в виду добавление zig-linux-powerpc* архивов на сайте?

Вообще, был бы я автором, я б просто с опеннета свою же взял и доужал)))) Незачем два раза упаковывать жирные Release Notes

BratishkaErik
()
Ответ на: комментарий от bread

ненужно + синтаксис отбитый

Каждому своё, но накрученные звёзды оч спорно, учитывая как его активно рекламят на всяких Hacker News (хотя пофиг, все равно кол-во звёзд не влияет, вот кол-во форков уже (мало, но хоть что-то) инфы даёт)

BratishkaErik
()
Ответ на: комментарий от vasya_pupkin

Чем это лучше Crystal?

Ну Crystal ведь в совсем другой нишей, со всеми этими ООП, GC, рантайм пожирнее. Других „потенциальных убийц C”, кроме Zig, по сути и не завезли. Кроме него на ЭТОМ ринге никого нет. Все остальные либо скатываются в фичодром (C++, Rust), либо и не хотят убивать C (C3 считает себя эволюцией, Odin чисто как приятная альтернатива, а не убийца, Jai для геймдева, Rust не на уровне C/Zig по минималистичности т.е. опять таки фичодром и ближе к статусу „потенциальной убийцы C++”), либо просто померли.

BratishkaErik
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.