I thought about dynamically sized types (DSTs) in zig recently. Was considering writing about it. I came to a different conclusion. Why not use zig's opaque?
It's pretty clean at this imo:
Less metaprogramming but I think nicer to use in some cases.
> Zig does not, and will not, have VLAs in the language spec. Instead, you can allocate a slice on the heap. If you want to have the data on the stack, use an array as a bounded backing store, and work with a slice into it[.]
Too bad, aligned byte-typed VLAs (and a license to retype them as a struct) are what you need to get stack allocation across ABI boundaries the way Swift does it. (A long long time ago, SOM, IBM’s answer to Microsoft’s COM, did this in C with alloca instead of VLAs, but that’s the same thing.) I guess I’ll have to use something else instead.
> A long long time ago, SOM, IBM’s answer to Microsoft’s COM, did this in C with alloca instead of VLAs, but that’s the same thing.
Was kind of the other way around, given the whole OS/2 versus Windows history, and that COM started as the evolution of OLE and VBX technologies, Windows 9X and Windows NT weren't as COM heavy as OS/2 was with SOM.
There was no COM to worry about on Windows 3.x back in 1991.
Also SOM was so much better, bettwen C++, Smalltalk and C, with support for meta-classes and proper inheritance implementation across such disparate languages.
Zig articles tend to get a little too excited about rediscovering longstanding techniques.
The author has described a metaprogramming utility for allocating a contiguous hunk of memory, carving this hunk into fields (in the article's example, a fixed-sized Client header, then some number of bytes for host, then some number of bytes for read_buffer, and then some for write_buffer). I'll acknowledge the syntax is convenient, but
That first pointer is needless indirection and probably a cache miss. You should (unless you have specific performance data showing otherwise) store the sizes in the object header, not in an obese pointer to it. (It's bigger than even a fat pointer.)
You have raised a good discussion point or two, but I am not inclined to engage with them due to the tone you've created with the rest of your comment.
Would it be productive to jump into a thread on a Ruby article and puff your feathers about how you've always been able to do this in Perl, and also in Python 4 you can do XYZ? I don't think so.
For whatever reason, inevitably in threads on systems languages, someone comes in and postures themselves defensively like this. You might want to reflect on that.
Should I try Zig? I wanted to learn something that's more low level than the JVM/Node and i have been contemplating rust and go. zig never occurred to me until now.
11 comments
[ 7.6 ms ] story [ 68.0 ms ] threadIt's pretty clean at this imo: Less metaprogramming but I think nicer to use in some cases.
going off memory so I expect it to not actually compile, but I've definitely done something like this before.Too bad, aligned byte-typed VLAs (and a license to retype them as a struct) are what you need to get stack allocation across ABI boundaries the way Swift does it. (A long long time ago, SOM, IBM’s answer to Microsoft’s COM, did this in C with alloca instead of VLAs, but that’s the same thing.) I guess I’ll have to use something else instead.
Was kind of the other way around, given the whole OS/2 versus Windows history, and that COM started as the evolution of OLE and VBX technologies, Windows 9X and Windows NT weren't as COM heavy as OS/2 was with SOM.
There was no COM to worry about on Windows 3.x back in 1991.
https://www.edm2.com/index.php/SOM_%26_DSOM_-_An_Introductio...
Also SOM was so much better, bettwen C++, Smalltalk and C, with support for meta-classes and proper inheritance implementation across such disparate languages.
why not to make it heap-only type? it seems such a useful addition to type system, why ignore it due to one usecase?
The author has described a metaprogramming utility for allocating a contiguous hunk of memory, carving this hunk into fields (in the article's example, a fixed-sized Client header, then some number of bytes for host, then some number of bytes for read_buffer, and then some for write_buffer). I'll acknowledge the syntax is convenient, but
1. we've done this since time immemorial in C. See https://learn.microsoft.com/en-us/windows/win32/api/evntcons...
2. you can implement this pattern ergonomically in C++, and even moreso once the C++26 reflection stuff comes online
3. the zig implementation is inefficient. It desugars to
That first pointer is needless indirection and probably a cache miss. You should (unless you have specific performance data showing otherwise) store the sizes in the object header, not in an obese pointer to it. (It's bigger than even a fat pointer.)Would it be productive to jump into a thread on a Ruby article and puff your feathers about how you've always been able to do this in Perl, and also in Python 4 you can do XYZ? I don't think so.
For whatever reason, inevitably in threads on systems languages, someone comes in and postures themselves defensively like this. You might want to reflect on that.
> you can implement this pattern ergonomically in C++,
lmao