3 ms·
I find Zig syntax noicy. I dont like the @TypeOf (at symbol) and pals, and the weird .{.x} syntax feels off. Zig has some nice things going on but somehow code
by phplovesong 1y ago
I find Zig syntax noicy. I dont like the @TypeOf (at symbol) and pals, and the weird .{.x} syntax feels off.
Zig has some nice things going on but somehow code is really hard to read, admitting its a skill issue as im not that versed in zig.
- flohofwoe 1y agoThe dot is just a placeholder for an inferred type, and IMHO that makes a lot of sense. E.g. you can either write this: const p = Point{ .x = 123, .y = 234 }; ...or this: const p: Point = .{ .x = 123, .y = 234 }; When calling a function which expects a Point you can omit the verbose type: takePoint(.{ .x = 123, .y = 234 }); In Rust I need to explicitly write the type: takePoint(Point{ x: 123, y: 234); ...and in nested struct initializations the inferred form is very handy, e.g. Rust requires you to write this (not sure if I got the syntax right): const x = Rect{ top_left: Point{ x: 123, y: 234 }, bottom_right: Point{ x: 456, y: 456 }, }; ...but the compiler already knows that Rect consists of two nested Points, so what's the point of requiring the user to type that out? So in Zig it's just: const x = Rect{ .top_left = .{ .x = 123, .y = 234 }, .bottom_right = .{ .x = 456, .y = 456 }, }; Requiring the explicit type on everything can get noisy really fast in Rust. Of course the question is whether the leading dot in '.{' could be omitted, and personally I would be in favour of that. Apparently it simplifies the parser, but such implementation details should get in the way of convenience IMHO. And then there's `.x = 123` vs `x: 123`. The Zig form is copied from C99, the Rust form from Javascript. Since I write both a lot of C99 and Typescript I don't either form (and both Zig and Rust are not even close to the flexibility and convenience of the C99 designated initialization syntax unfortunately). Edit: fixed the Rust struct init syntax.
- do_not_redeem 1y agoZig is planning to get rid of explicit `T{}` syntax, in favor of only supporting inferred types. https://github.com/ziglang/zig/issues/5038 https://github.com/ziglang/zig/issues/5038 So the explanation of a dot standing in for a type doesn't make sense in the long run.
- flohofwoe 1y agoAh, I wasn't aware of that proposal. But yeah in that case I would also heavily prefer to "drop the dot" :) IMHO Odin got it exactly right. For a variable with explicit type: a_variable : type = val; ...or for inferred type: a_variable := val; ...and the same for constants: a_const : type : val; a_const :: val; ...but I think that doesn't fit into Zig's parser design philosophy (e.g. requiring some sort of keyword upfront so that the parser knows the context it's in right from the start instead of delaying that decision to a later time).
- dminik 1y agoAhh, a perfect example of why Zig is uninteresting to me: https://github.com/ziglang/zig/issues/5038#issuecomment-2441741345 https://github.com/ziglang/zig/issues/5038#issuecomment-2441... A language hostile to LSP/intellisense.
- surajrmal 1y agoHow is it hostile? The lsp can do type inference just the same as the compiler.
- dminik 1y agoYes. And by "do type inference just the same as the compiler", that includes having to do comptime execution. Plus with no interfaces/traits/concepts and comptime being mostly any-typed makes it difficult to have helpful intellisense.
- Defletter 1y agoThat's... honestly really disappointing. I use explicit `T{}` because otherwise becomes too unreadable, too Assembly-like: I like knowing what types I'm using. It also provides a convenient thing to click on to inspect the type. I genuinely do not understand this headlong pursuit of conciseness to the detriment of readability.
- hinkley 1y agoThanks for the explanation, but I don’t think you’ve sold me on .x Think I’d rather do the Point{} syntax.
- deleted 1y ago[deleted]
- tialaramex 1y agoBecause we've said x is a constant we're obliged to specify its type. For variables we're allowed to use inference and in most cases the type can be correctly inferred, but for constants or function signatures inference is deliberately prohibited. const x: Rect = .... [Note that in Zig what you've written isn't a constant, Zig takes the same attitude as C and C++ of using const to indicate an immutable rather than a constant]
- flohofwoe 1y ago> Zig takes the same attitude as C and C++ of using const to indicate an immutable rather than a constant I think it's a bit more complicated than that: AFAIK Zig consts without explicit type may be comptime_int or comptime_float, and those don't exist at runtime. Only consts with an explicit type annotation are 'runtime consts'. Also see: https://www.godbolt.org/z/esTr463bT https://www.godbolt.org/z/esTr463bT ...still, I think Rust should allow to infer the type at least inside struct initialization, it would make designated init code like this a lot less noisy (Zig would suffer from the same problem if it hadn't the .{} syntax): https://github.com/floooh/sokol-rust/blob/main/examples/texcube/texcube.rs#L125-L147 https://github.com/floooh/sokol-rust/blob/main/examples/texc... ...C99 is still the 'benchmark' when it comes to struct initialization: https://github.com/floooh/sokol-samples/blob/29d5e9f4a56ae1884c4ffa7178b1af739d827d07/sapp/texcube-sapp.c#L119-L136 https://github.com/floooh/sokol-samples/blob/29d5e9f4a56ae18...
- tialaramex 1y agoSurely Rust can infer the type in your example? It just doesn't provide Zig's syntax to use the inferred type to manually initialize. If you wrote some_fn() here where some_fn's return type was genericised, Rust would ask for the appropriately typed some_fn not say it doesn't know the type.
- flohofwoe 1y ago> Surely Rust can infer the type in your example? Well in Rust code like this: pass_action.colors[0] = sg::ColorAttachmentAction { load_action: sg::LoadAction::Clear, clear_value: sg::Color { r: 0.25, g: 0.5, b: 0.75, a: 1.0 }, ..Default::default() }; ...I cannot write: pass_action.colors[0] = { load_action: sg::LoadAction::Clear, clear_value: { r: 0.25, g: 0.5, b: 0.75, a: 1.0 }, ..Default::default() }; ...even though the Rust compiler has all the type information it needs (from the 'left-hand-side'). For comparison, in Zig it would look like this: pass_action.colors[0] = .{ .load_action = .Clear, .clear_value = .{ .r=0.25, .g=0.5, .b=0.75, .a=1.0 }, }; ...Zig is still only halfway there compared to C99 (e.g. Zig doesn't allow designator chaining and is much less flexible for initializing nested arrays - in those areas it's closer to Rust than C).
- dsego 1y agoZig is noisy and and the syntax is really not elegant. One reason I like odin's syntax, it's minimal and so well thought out.
- ngrilly 1y agoYes, Zig’s syntax is a bit noisier, but it enables things such as using if/for/while/switch in expressions, or using anonymous struct literals to emulate named and default parameters in functions.