In Ziglings we have some exercises with array multiplication. Since it is removed from Zig, I switched to @splat(). But for exercise 005_arrays2 it doesn’t look nice.
Since that exercise is (at least currently) about array operators, and that operator no longer exists, I would personally just remove it. Maybe add @splat to the built-ins exercise?
I will take that into consideration. In this exercise there is also the ++ operator, that is still available. The next problem I encountered is:
// Use the array repeat '**' operator to make "ha ha ha ".
const laugh = "ha " ** 3;
I’ll probably have to delete that, because I can’t think of a suitable replacement. It’s a shame; I always found these operators very elegant and can’t quite understand why they’re being discontinued.
I agree with the commenter in the GitHub issue thread that the old behavior of ** would better be moved to a built-in @repeat, and that scope creep of @splat is suboptimal.
Never much liked ** for array multiplication on the syntax level, though. So it’s harder to argue against its removal.
I too like the idea of @repeat and @concat, with the added benefit of being able to control formatting with trailing commas. But rarely needed so I think comptime blk’s are fine.
Oh, just for sharing. I happened to come across this exercise two days ago. After knowing ** has been removed for only 20 hours, I repeatedly used ++ for three times manually for it.
And now, because I still regard built-in functions as magic, I’m considering whether using undefined with inline for is more explicit.
btw, I’m learning zig with ziglings, I find it so helpful. Thank you!!
Even common and core functionality uses builtin functions, such as casting (e.g. @intCast) and importing (i.e. @import), so hopefully that will help the feeling of them being magic to dissipate.
@splat provides a more ergonomic way to do what people were mostly using ** for. Features need to actively justify their existence in the language, and nobody piped up with a sufficiently convincing use case for **, so it got removed. Ziglings is designed to teach the language, so the exercises are small examples that don’t necessarily represent real usage. In this case, I think it’s reasonable to just remove this ziglings exercise.
++ is used extensively in real code, so I wouldn’t worry about its removal.
If someone needs this kind of thing, as a one off I would do:
const bit_pattern = blk: {
const pattern = [_]u8{ 1, 0, 0, 1 };
const pattern_2 = pattern ++ pattern;
// repeat as many doublings as are needed.
break :blk pattern ++ pattern_2; // binary of final number
};
and if for some reason your code actually needs to do this a lot, then a userland implementation is reasonable:
I like to set the total size instead of pattern.len * count so I use this:
fn arrayFromPattern(comptime T: type, pattern: []const std.meta.Child(T)) T {
var arr: T = undefined;
var i: usize = 0;
while (i < arr.len) : (i += pattern.len) {
const len = @min(arr.len - i, pattern.len);
@memcpy(arr[i..][0..len], pattern[0..len]);
}
return arr;
}
const arr = arrayFromPattern([5]i32, &.{ 1, 2, 3 }); // <-- {1, 2, 3, 1, 2}
// I would love this but there is no way to make this...
const arr: [5]i32 = arrayFromPattern(&.{ 1, 2, 3 });
I think this exercise should be removed or revised.
It all makes sense eventually, but hard to put together as a beginner. You’re using three builtins just to duplicate a string a few times. @as should be called @coerce and @bitCast as @typeCast (or just @cast) but that’s not a box I’m trying to open. It’s just non-obvious and confusing and easily generates as “why the hell is this so difficult??” even after solving it.
I think it completely breaks the flow of ziglings.
Quite shocked to see how elegant the SIMD solution is. Maybe it should be used instead.
I ran into this too while helping someone at a Zig Day. I’m guessing the exercise made sense when it was originally constructed, but now it has been “updated to latest zig” so many times that it should probably be re-evaluated (and probably just deleted since it’s not a language feature anymore).
You would expect simplifying the Zig language to cause Ziglings to also shrink, right?