@michalfita @katzenmann No need to be rude. My reality is that #Zig is a) wonderfully simpler and more predictable [than the other options I understand well, which does not include Rust, this is not a slam] and b) unfinished.
@michalfita @katzenmann No need to be rude. My reality is that #Zig is a) wonderfully simpler and more predictable [than the other options I understand well, which does not include Rust, this is not a slam] and b) unfinished.
@katzenmann Reality is #Zig is a language created by #Zig zealots for other #Zig zealots. Since #Rust landed in hands of community it's a language from #Rust zealots for people. There's whole mentality of keeping error messages user friendly and have well written understandable documentation with examples.
Damn. I thought #Zig was supposed to be a simpler language coming from #Rust but compiler errors definitely aren't it's strong suit.
This is one of the first impressions I got from the language. I'm just trying to compare some strings here, nothing magical. But apparently this is not an easy task in Zig. The documentation is definitely lacking examples too.
Also it's missing a good beginner introduction like the Rust Book.
The code in question: https://bpa.st/3VYA
After a week of trying to write c++ #zig feels like the spring breeze
Still learning #zig and #raylib. I know it's not much, but I now have a button supporting different graphics for idle, hovering and presses :D And callback function on click.
I'm still not 100% sure if this is a language I'll stick with, but so far I do like it. Fast compile times and small executables, and a very explicit code!
In #Zig, is it better to hold a slice of small objects and grow it when necessary, or is it better to just hold on to an ArrayList/MultiArrayList?
I guess the use case is important. Want to track the bullets on screen in a little shoot 'em up (Every new engine I try gets a little shmup, ever since I watched @krystman's wonderful pico 8 shmup videos) and figured I'd try for "proper" data-oriented design a la Andrew Kelley's talk.
My assumption is that the (multi)ArrayLists will be more effective at managing bursts of memory, but I figure it wouldn't be _that_ difficult to build a pooling system that allocates when it needs to but re-purposes when it has instances marked "off screen".
Or. . .maybe there's a pool-like system in the std library?
Well... I went on the deepest of dives today to fix the link error I've been tangling with while working on tigerbeetle-hs!
First, GHC passes `-lm` near the beginning of the linker flags it generates when compiling an executable. Pretty normal.
Unless you're linking a shared object file compiled from Zig.
Zig's build tool chain vendors it's own versions of libc for the various target platforms. When you call 'linkSystemLibrary2` and tell it to link `"m"` and tell Zig that's it's needed... well, it ignores you.
Zig's build tool sees that you asked to link a system library once and it links libc... and nothing else.
All of this means that if you pass `-lm` before you link the Zig shared object, you get a relink error. Because Zig helpfully provides an implementation for the libc symbol (in my case, `sin`) and the linker already has an implementation for that symbol... in libm.
It looks like Zig's tool chain doesn't include any of the GNU library paths in the RPATH of the elf header and so the linker asks you to relink the library against libm... which you can't actually do with Zig's build tools.
Trying out a hack with nix's `patchelf` to add the RPATH's into the nix store for the glibc so that the object file can declare its dependency on libm's implementation and will have to work through the community to see how we can get Zig to play nicer with systems.
Can confirm that my #Zig-sty-five-oh-two emulator now correctly emulates all of the addressing modes for the baseline CPU. Yes, my friends, that does include the hardware bug with Indexed Indirect addressing on the zero page.
Tests are written, everything is green.
Plus, I have a cool debug viewer for the CPU!
#Zig has the easiest FFI support I have ever seen! #programming
Building Statically Linked Go Executables with CGO and Zig
Building Statically Linked Go Executables with CGO and Zig https://lobste.rs/s/va0h3b #go #zig
https://calabro.io/zig-cgo
Tonight, at roughly 8:30 PM Eastern, I'll be going live to continue work on my 6502 #emulator!
Come for the #Zig stay for the. . .Zig. :D
You can check out the progress so far on Codeberg: https://codeberg.org/b4ux1t3/zigsty-five-oh-two
THAT SAID. . .
I can't get #Zig's document generator to generate stuff for all of my zig files. Which, I guess, is fine, I know it's in preview, technically, but. . .ugh. It's SO CLOSE TO AWESOME.
Holy crap, #Zig documentation comments are awesome, too.
One of my favorite parts of the #DotNet ecosystem is the documentation system, where you get XMLdocs for free, and they have a first party tool for generating a docs web site.
For a while, though, I've been lamenting that weird HTML-based DSL from dotnet.
Not only do I not need to use another tool for Zig docs, I get to use MARKDOWN, like the gods intended.
Ooooooooooooh.
#Zig files are, themselves, structs.
This is awesome, and explains some of my confusion around namespacing and stuff.
Also: custom formatters for structs? So nice. Love the member accessing syntax.
Hot damn I haven't been this excited about a language in a few years.
Okay, Ziguanas, is this really the best we can do for "interfaces" in #Zig?
I can't think of another way to do it.
```zig
// The interface
pub const BusDevice = struct {
ptr: *anyopaque,
min_address: u16,
max_address: u16,
readFn: *const fn (ptr: *anyopaque, addr: u16) u8,
writeFn: *const fn (ptr: *anyopaque, addr: u16, value: u8) void,
fn read(self: BusDevice, addr: u16) u8 {
return self.readFn(self.ptr, addr);
}
fn write(self: BusDevice, addr: u16, value: u8) void {
self.writeFn(self.ptr, addr, value);
}
};
// The implementation
pub const Memory = struct {
min_address: u16,
max_address: u16,
physical_memory: []u8,
pub fn new(allocator: Allocator, min_address: u16, max_address: u16) !Memory {
const phys_mem = try allocator.alloc(u8, max_address - min_address);
for (phys_mem) |*address| {
address.* = 0;
}
return Memory{
.min_address = min_address,
.max_address = max_address,
.physical_memory = phys_mem,
};
}
pub fn write(self: *Memory, address: u16, value: u8) void {
self.physical_memory[address] = value;
}
pub fn read(self: *Memory, address: u16) u8 {
return self.physical_memory[address - self.min_address];
}
pub fn busDevice(self: *Memory) BusDevice {
return BusDevice{ .ptr = self, .min_address = self.min_address, .max_address = self.max_address, .readFn = self.read, .writeFn = self.write };
}
};
```