ChanServ changed the topic of #zig to: zig programming language | ziglang.org | be excellent to each other | channel logs: https://irclog.whitequark.org/zig/
<andrewrk>
copy elision take 3 will be much more focused and educated
<andrewrk>
I know everything that went wrong last time
<daurnimator>
second system syndrome overcome..... third-system-syndrome now starts? :P
<andrewrk>
this third attempt will be much more focused. not going to attempt error union/optional special handling in this pass
<andrewrk>
that will be enough for the coroutine rewrite though. we just need `a = b;` to allow the b expression to receive the memory for `a`
MajorLag has joined #zig
MajorLag has quit [Ping timeout: 268 seconds]
MajorLag has joined #zig
MajorLag has quit [Ping timeout: 268 seconds]
MajorLag has joined #zig
MajorLag has quit [Ping timeout: 268 seconds]
MajorLag has joined #zig
sebastianlin has joined #zig
MajorLag has quit [Ping timeout: 268 seconds]
MajorLag has joined #zig
MajorLag has quit [Ping timeout: 252 seconds]
jevinskie has joined #zig
mattmcal has joined #zig
<mattmcal>
andrewrk: I saw your reply to #265 (null-terminated pointers)
<mattmcal>
I'm wondering if my proposal might be at odds with the principal that you should be able to do seamless C interop without importing std
<mattmcal>
Unless perhaps you wanted to add implicit imports, i.e. a "prelude"
<andrewrk>
hi mattmcal
<mattmcal>
Howdy :)
<andrewrk>
one reason we have explicit @import even for "std" and "builtin" is for discoverability of the language. one of the design principles is that zig should be readable, even to people who have never even heard of zig before
<mattmcal>
Sure, that makes enough sense. Though, thinking about kt, I'm not sure there's not much difference in this regard between having c_int, c_char etc. as builtin types versus making them automatically imported typedefs
<mattmcal>
*not sure there's much
<mattmcal>
Not that I'm proposing that
<daurnimator>
yeah I wouldn't see any problems if there was e.g. a @import("c")
<daurnimator>
then use c.int, c.char, etc.
<mattmcal>
Mostly I just thought that functionality related to null-terminated strings should be implemented as actual zig code
<mattmcal>
e.g. instead of a [*]null u8 to []u8 cast implicitly generating a for loop, you'd have an actual function like cstrToSlice that does it
<mattmcal>
Better yet if you can just do my_str.toSlice()
<andrewrk>
mattmcal, I wasn't planning on implementing `for` to work on null terminated pointers
<andrewrk>
but now that you mentioned it, I'm on the fence about it
<mattmcal>
You mentioned that casting to []null u8 would do a linear search
<mattmcal>
Though I suppose you probably meant a builtin function cast, not implicit
<andrewrk>
that's dubious, I have a lot of reservations about a language-generated linear search
<daurnimator>
mattmcal: andrewrk: I assume the "generate a loop" here is in reference to inserting a `strlen` call
<mattmcal>
Fair enough
<andrewrk>
I understand that my own comment contradicts what I'm saying right now
<andrewrk>
to be fair it is over a year old and I've had a lot more time to think about this stuff since then
<mattmcal>
Yeah, sorry, I wasn't trying to read too deeply into one comment, just alluding to it
kristate has quit [Ping timeout: 245 seconds]
<mattmcal>
Another issue I thought about is casting []null u8 to []u8
<mattmcal>
Should it include the null byte or not?
<daurnimator>
no.
<daurnimator>
(why would it?)
<mattmcal>
I actually dunno exactly, maybe you're writing a binary serializer that interops with C code? Kinda niche I guess
<mattmcal>
I just wanted to suggest it would be nice to be able to say something like "my_str.toSliceNul()" to accomplish that
<daurnimator>
mattmcal: would it not be `mynullarray[0..mynullarray.len]`? --> you know there is a null at the end :P
<andrewrk>
mattmcal, I think that answer is clear: the len is the len without the null
<andrewrk>
the semantic meaning of `[]null u8` is: here is a pointer and a length. it is guaranteed the value at ptr[len] is null
<mattmcal>
That's sort of dictated by the semantics of regular slices, as otherwise you'd get a surprise null byte in your strings
<andrewrk>
how so?
<mattmcal>
Well, I mean that it would be surprising if std.debug.warn("{}", null_slice) printed a nul char at the end, assuming there was a cast there
<mattmcal>
I should say slice-based strings rather than "regular slices"
<daurnimator>
yeah. also if you iterated over the slice, you wouldn't want the null to appear
<mattmcal>
Though daurnimator I think your example would be mynullarray[0..mynullarray.len + 1] then
<daurnimator>
the null is part of the 'framing'
<daurnimator>
mattmcal: no, the last element is len-1. len is past the end
<mattmcal>
But that truncates the nul byte then
<andrewrk>
that's the reason it's in the type! the type is how you know there's an extra nul byte
<andrewrk>
so if you did: var a = "ab"; var s: []null u8 = &a; assert(s.ptr[0] == 'a'); assert(s.ptr[1] == 'b'); assert(s.ptr[2] == 0);
<andrewrk>
assert(s[2] == 0); // up for debate whether this is OK, or triggers out of bounds
<mattmcal>
Isn't the upper bound in slice[0..len] exclusive?
<andrewrk>
(also, oops, forgot to make the array have the null type)
<andrewrk>
mattmcal, yes
<mattmcal>
Sorry, but I think I'm starting to distract with talk of basic C concepts :S
<andrewrk>
in zig `a..b` is start inclusive, end exclusive
<andrewrk>
so for a normal slice, ptr[len] is exactly one item out of bounds
<mattmcal>
Right, so if you wanted to create a slice *with* the nul byte included, you'd write nullslice[0..nullslice.len + 1], no?
<andrewrk>
sorry are you talking about status quo zig or if we did #265?
<mattmcal>
Sorry, nullslice has type []null u8
<mattmcal>
Anyways, it seems like I've done a good job sewing general confusion
<mattmcal>
To wrap up, my suggestion sort of assumed that one would actually *want* to import the types from std and possibly use utility functions tacked onto them
<mattmcal>
If that's not the case, it may not be a particularly good idea
sebastianlin has quit [Ping timeout: 256 seconds]
<andrewrk>
if you wanted to create a slice with the null byte included, and no longer with the "null" annotation, you would do this: nullslice.ptr[0..nullslice.len + 1]
<andrewrk>
nullslice[nullslice.len] // up for debate whether this is OK, or triggers out of bounds
sebastianlin has joined #zig
<daurnimator>
andrewrk: I think for a null slice it should be allowed
<daurnimator>
You'd expect that with null slice you could iterate until you hit null
<daurnimator>
which means that indexing to get the null needs to be defined behaviour
<andrewrk>
that's my thought as well
<daurnimator>
note that IMO `nullslice.len` *is* invoking strlen
<daurnimator>
i.e. .len on a null slice is potentially an "expensive" operation
<andrewrk>
no, the type `[]null T` has an explicit length as well as a guaranteed null value at the len index
<andrewrk>
and `[*]null T` does not have a `len` property
<daurnimator>
I'm... not so sure about that
<daurnimator>
by making 'nullslice.len' use the cached value, it opens up difficult/complex behaviour around the array possibly containing nulls itself
<daurnimator>
by making .len invoke strlen, you get to skip the "tricky" definitions, and I think it would make sense to someone glancing at the code
<mattmcal>
See, that's what sort of made me question whether []null u8 to []u8 should include the nul
<mattmcal>
I thought []null u8 == []u8 but with last byte 0
<andrewrk>
daurnimator, cached? why do you say cached?
<daurnimator>
andrewrk: if it has an explicit length, then it is stored somewhere, right?
<andrewrk>
[]u8 is struct { ptr: [*]u8, len: usize}
<andrewrk>
it's as simple as this: a slice has a pointer as one of its fields. so it can have all the pointer properties that a pointer can have
<daurnimator>
sorry, I got confused about slice syntax.
<daurnimator>
let me try again
<daurnimator>
`[]null u8` (null slice) should be `struct { ptr: [*]u8, fn len(self: @This()) usize { return strlen(self.ptr); } }`
<daurnimator>
I think `[*]null u8` may not need to exist?
<daurnimator>
normally a slice, `[]T` is pointer to runtime-known number of items. Supports index syntax: slice[i]. Supports slice syntax: slice[start..end]. Supports len property: slice.len.
<daurnimator>
a null slice `[]null T` is a pointer to a null terminated number of items. Supports index syntax: slice[i]. Supports slice syntax: slice[start..end]. Supports len method: `slice.len()`.
<andrewrk>
`[*]null u8` is the type of the parameter to strlen
<andrewrk>
I'm sad that this is causing so much confusion. if people don't understand the type right away, it kind of defeats the purpose
<daurnimator>
say I do `nullslice[0] = 0` --> I would expect that nullslice.len would now be 0.
<andrewrk>
the null pointer attribute means, exactly this, nothing more, nothing less: at the element one past the logical last element, the value is null
<daurnimator>
andrewrk: I invert that definition: the logical last element is the one with null after it.
<daurnimator>
null gets set/inserted? the logical last element is a different one.
<emekankurumeh[m]>
i mean if you making a zig interface to those lower level functions. for example in a hypothetical `std.os.socket` library what would be the "zig way" to handle those flags?
<emekankurumeh[m]>
i was working on a socket module but got stuck because i couldn't of how to design that part.
schme245 has joined #zig
<andrewrk>
using an unsigned integer for flags is fine. you could also experiment with a packed struct
<schme245>
is there any way to pass generic functions as function pointers?
<schme245>
I'm trying to figure out if there is a way to avoid defining a `greaterThan` function for u8, u32, u64 and so on, when I want to that function as a function pointer
wootehfoot has quit [Read error: Connection reset by peer]
halosghost has quit [Quit: WeeChat 2.3]
Zaab1t has quit [Quit: bye bye friends]
<daurnimator>
andrewrk: did my null terminated proposal make sense?
schme245 has quit [Remote host closed the connection]