Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Hey Mr Loris.

Well, your explanation doesn't really tell why do I call .deinit() on a structure before alllocator() call and calling all the rest important stuff on a structure after such call. I think you guys, while doing great job by the way, are kind of stuck in a thinking from inside language creators' perspective. From outside, certain things look so weird.

I need also to be a picky about "that's just how computers work" phrase, you know uttering such a phrase has always a danger of bumping into someone who wrote assembly before you were even born and hearing this makes a good laugh..



> Well, your explanation doesn't really tell why do I call .deinit() on a structure before alllocator() call and calling all the rest important stuff on a structure after such call.

That's because the Allocator interface doesn't define that an allocator must be deinitable (see in the link above the fn pointers held by the vtable field). So just like you have to call flush() on a BufferedWriter implementation (because the Writer interface doesn't define that writers must be flushable), you have to call deinit on the implementation and not through the interface.

Fun fact, not all allocators are deinitable. For example std.heap.c_allocator is an interface to libc's malloc, and that allocator, while usable from Zig, doesn't have a concept of deiniting. Similarly, std.heap.page_allocator (mmap /virtualalloc) doesn't have any deinit because it's stateless (i.e. the kernel holds the state).


Ok that's very helpful, thank you.


I don't know about the deinit thing, but I think this allocator/writer stuff has nothing to do with "inside language creators' perspective". To me, even though it wouldn't be my first guess as someone who's never used Zig, it does make sense to me that it's done this way since apparently Zig does not really have interfaces or traits of any kind for structs to just have. In fact when Googling about Zig interfaces I found another post from the same blog:

https://www.openmymind.net/Zig-Interfaces/

which says that an interface is essentially just a struct that contains pointers to methods. In other words when you call the .thing() method on your SpecificThing, that method is producing a Thing that knows how to operate on the SpecificThing, because functions that accept Things don't know about SpecificThings. You can't manufacture that Thing without first having a SpecificThing, and a SpecificThing can't be directly used as that Thing because it's not. There's essentially no other way to do this in Zig.


> why do I call .deinit() on a structure before alllocator() call

This is explained right in the documentation about arena allocator. Arena allocator deallocate everything at once when it goes out of scope (with defer deinit()). You need to call .allocator() to get an Allocator struct because it's a pattern in Zig to swap out the allocator. And with this, other code can call alloc and free with out caring about the implementation.

This is just how arena allocator works and not related to Zig's design. You may take issue with how Zig doesn't have built-in interface and having to resort to this implementation struct returning the interface struct pattern, but I think the GP clearly explained the Why.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: