I still am confused about zig sometimes.
The following is understandable but still a bit strange.
I experience loops sometimes as inconvenient.
Will there ever be a “typed” loop?
Probably there are more related syntactical things like this.
// error: expected type 'u3', found 'usize'
for (0..8) |i|
{
show(i);
}
// just compiles, magically i is an u3 here?
inline for (0..8) |i|
{
show(i);
}
fn show(u: u3) void
{
std.debug.print("{}", .{u});
}
So in a way its type depends on whether it is evaluated at comptime or at runtime.
I’m not sure if I would prefer a compile error here but it would certainly be more consistent if you would have to use casting builtins or at least cast to comptime_int first before such type coercions are possible.
I would love such a syntax (though with correctly placed braces ).
I really appreciate Zig, hate nit-picking on the language, and am always pleasantly surprised with new features that I didn’t even know I wanted with each version, but being able to iterate a range using a specified integer type, and using negative numbers is one of my very few “wish-list” items.
Sure, casting is easy and cheap, but adds it adds noise to an already verbose language that feels needless here. I know there are a multitude of ways to accomplish the same, such as while loop, counters, but simply being able to:
Just out of curiosity, were/are you a C# developer?
I ask because it was my goto language many years ago, and I also got accustomed to using Allman style braces, as it is pretty much the only accepted style for that language. Even after I slowly phased out my C# development in favor of other languages that predominately used K&R, it took quite a while before I fully accepted it as the One True and Correct Style™. I still have some of my first C projects where I was using it actually.
The idea of possibility to give type |i: u8| to the range capture group is great imo.
Especially since you can make the default non-specified scenario behave the same way (no breaking change).
It can have same implicit type like break; in loops is actually break void;, here |i| would just be implicitly |i: usize|.
I know Zig is strongly for explixitness, but there are nice minimal places where implicitness makes sense.
I also dont like to nit-pick on the language.
I stand by most of the language choices and even the auto-formater has good style.
But there is one auto-formater choice that still makes me unhappy:
if (.........) {
// stuff
} else { // <- this
// stuff
}
I get that its tighter and cleaner to put the } and else on same line, but my autistic ass is scanning only the first keyword each line when fast orienting in code. This always gets me
Yep for my job I use C# (and Delphi in the past). In my hobbytime I do real programming in Zig
The company uses braces on line for everything.
It is funny because of the keywords begin and end in Delphi I did at a certain moment switch to "begin at the end of the line, which I liked. I can match begin end, which stand out.
if true begin
// dothings
end;
is for me much more readable than
if (true) {
// do things
}
The begin and end were not such a bad idea I think from the old Pascal guy.
I tried several times already but my head simply refuses to “match” a keyword with a brace.
My head matches a brace with a brace.
seeing lines like
) type {
no no no
I would like very much to be able to read the non-aligned asymmetrical code as well as the c# style.
But I will not force matters. Maybe some day…
I read it. Yes, these kind of things.
Zig is very strongly typed, but inference or compller details sometimes makes it feel less strongly typed or we have to dig deep what is happening.