ChanServ changed the topic of #zig to: zig programming language | ziglang.org | be excellent to each other | channel logs: https://irclog.whitequark.org/zig/
atk has quit [Quit: Well this is unexpected.]
atk has joined #zig
zolk3ri has quit [Remote host closed the connection]
dbandstra has quit [Quit: Leaving]
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
JinShil has joined #zig
dbandstra has joined #zig
<GitHub55>
[zig] binary132 closed pull request #1127: Fix 1117: Use realpath in stage1 Darwin os_self_exe_path (master...fix-1117-macos-realpath) https://git.io/vhMpC
<GitHub120>
[zig] binary132 opened pull request #1128: Fix 1117: Use realpath in stage1 Darwin os_self_exe_path (master...fix-1117-macos-realpath) https://git.io/vhDKP
<GitHub45>
zig/master 8fd7cc1 Andrew Kelley: disallow opaque as a return type of fn type syntax...
Ichorio has joined #zig
<MajorLag1>
andrewrk, I was about to update 1132 with examples of the casts producing errors when used on inferred variables. Do you know if d49d6f0 would fix that too?
Hejsil has joined #zig
<andrewrk>
I believe it does
bodie__ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
bodie__ has joined #zig
ManDeJan has quit [Ping timeout: 276 seconds]
davr0s has joined #zig
xtreak has quit [Remote host closed the connection]
kristate has quit [Remote host closed the connection]
<very-mediocre>
is there a decent pattern for making a struct property point to another in a constructor-ish function e.g. init()
<very-mediocre>
my particular case: a ring buffer implementation wraps over a regular array, both the array and ring buffer are properties of the same struct
<very-mediocre>
in struct.init() which returns a struct instance, doing something like instance.ringbuffer.init(&instance.array) doesn't work because &instance.array is local to the struct.init() function
<very-mediocre>
Do you have plans for the compiler to generate warnings?
<very-mediocre>
feels like "returning pointer to local variable" would be a good one
<very-mediocre>
hm or actually maybe that shouldn't even compile
<very-mediocre>
oh, it already doesn't compile i think
<andrewrk>
compiler warnings has been proposed and rejected
<very-mediocre>
the reason the compiler let me get away with it is I wasn't returning the local pointer, I was returning an instance of a struct, which has a property that points to a local variable
<very-mediocre>
i see
<andrewrk>
it is planned for more advanced data flow / control flow analysis to be able to catch the problem as you just described
<very-mediocre>
awesome
<very-mediocre>
the vast majority of modern languages heap allocate everything so it's such a huge footgun for anyone coming in from one of those
<GitHub109>
[zig] andrewrk closed pull request #1128: Fix 1117: Use realpath in stage1 Darwin os_self_exe_path (master...fix-1117-macos-realpath) https://git.io/vhDKP
<very-mediocre>
So I take it when we return an instance in an init() function, it's implemented as a pointer and not passed by value?
<very-mediocre>
or is that determined by the size of the returned instance?
<very-mediocre>
(as per the fairly recent commit allowing non-copyable types to be passed via an implicit mechanism decided by the compiler)
<andrewrk>
for return values, currently it's implemented as a memcpy, but optimizations can do the same kind of copy elisions that happen in C code. However it's not guaranteed
<andrewrk>
so that's what the well-defined copy eliding semantics are for - to provide guarantees about what will or won't be copied
<very-mediocre>
understood
<andrewrk>
my recommendation is, if you don't have the unusual (but valid) use case where one field points to its neighbor, use the bare struct as the return value. this will be eventually made to be non-copying
<andrewrk>
however for now if you need to have that use case, unfortunately the solution is to workaround by making the init function accept a pointer to the return value
<very-mediocre>
I don't quite follow the workaround
<very-mediocre>
You mean to manually assign the returned instance?
<Hejsil>
Is there a reason debug.global allocator does not reset between tests?
<andrewrk>
Hejsil, new best practice is to use std.heap.FixedBufferAllocator for all the tests
<andrewrk>
or just anything that isn't std.debug.global_allocator, really
<Hejsil>
But debug.global allocator is soooo convenient :(
<andrewrk>
hahaha
<Hejsil>
Is there a reason for this?
<Hejsil>
I mean, I can imagine people could shoot them self
<Hejsil>
But really, should tests be self contained and not rely on global state
<andrewrk>
oh, we could reset it in std/special/test_runner.zig
<Hejsil>
Actually, what reason does debug.global_allocator have, if not for tests?
<Hejsil>
and toy programs
<andrewrk>
just toy programs and quick testing
<Hejsil>
So long term, production ready tests should not use it
<andrewrk>
correct
<Hejsil>
Alright, time to be a good boy and get rid of it!
<andrewrk>
it's allocator training wheels
<bheads_>
Seems like a good wiki topic, intro to allocators, and best practices :)
<Hejsil>
I think that is a Todo on the docs :)
<andrewrk>
docs have seen steady progress lately
<andrewrk>
the number of TODOs is dropping
<MajorLag1>
andrewrk, should calling @noInlineCall on an inline fn be an error? because it looks like it just has no effect instead.
<very-mediocre>
>Alright, time to be a good boy and get rid of it! -> time to say see you later, allocator
<very-mediocre>
I'll see myself out
* andrewrk
claps
<Hejsil>
Oooh god
<bheads_>
*slow clap*
<andrewrk>
MajorLag1, yes that should be a compile error
Hejsil has quit [Quit: Page closed]
<MajorLag1>
interesting note: this came up because I was testing if it was possible to abuse inlining to get the copy eliding behavior being discussed. Turns out you can, if you trick the compiler into returning a ptr to a local variable.
<very-mediocre>
That sounds fancy
<very-mediocre>
my current mediocre workaround is to have a `new()` function that returns the instance
<very-mediocre>
followed by `init(self: *Whatever)` (as per andrewrk's example)
<MajorLag1>
I wouldn't recommend abusing inline in this fashion
<GitHub13>
zig/master cd4676a Andrew Kelley: stage1: update darwin code to workaround old libc bug...
<very-mediocre>
I take it zig will generally apply copy elision everywhere it can instead of explicit move semantics, right?
<very-mediocre>
ok i realized that's silly
<very-mediocre>
and probably a yes
<very-mediocre>
silly question i mean
<very-mediocre>
I'm more wondering if that lends itself to Rust-style compiler errors
<andrewrk>
I've tried to think about how move semantics apply to zig, and I don't think move semantics are relevant to zig
<very-mediocre>
I was just thinking you almost always want to move everything
<very-mediocre>
that's the main thing Rust nailed
<andrewrk>
assuming we get copy elision semantics working how I want them to work, the only time zig would generate a memcpy is for variable declarations
<andrewrk>
because variable declarations represent memory storage locations
<very-mediocre>
makes sense
xtreak has quit [Read error: No route to host]
<very-mediocre>
so declaration-assignment isn't a move since this isn't Rust
<very-mediocre>
and there's no `borrowing` concept
xtreak has joined #zig
<andrewrk>
I think even in Rust, struct assignment will do a memcpy to copy the fields
<very-mediocre>
oh, really
<andrewrk>
it's not making the new variable reference the old data is it?
<andrewrk>
let me try something
<bheads_>
would it be usful to have a debug flag that reports were memcpy's are happening?
<very-mediocre>
good question
<very-mediocre>
I'm very rusty on rust, no pun intended (really)
<bheads_>
maybe simular to -profile=gc with the DMD compiler
<very-mediocre>
I thought absolutely everything in Rust was "borrowed" unless you explicitly cloned it
<very-mediocre>
bheads_: seems reasonable
<very-mediocre>
like if `let a = whateverStruct; let b = a;` then you can't use a anymore
<very-mediocre>
Rust is really on to something with the realization that in most programs, you almost always want to move stuff
<very-mediocre>
but then because everything is a move by default, you end up with a hairy situation regarding passing things to functions
<very-mediocre>
hence `borrowing`
<bheads_>
That works for about 90% of things, its the other 10% that makes rust a PITA
<very-mediocre>
for me it's lifetime annotations that hurt me most
<bheads_>
if zig can make the 10% safe then the other 90% should be safe as well
<very-mediocre>
imho there's a ratio, if you lose 80% of your productivity to go from 80%->90% safety, that's not a tradeoff I want to make
<bheads_>
sure, but rust did the oposite
<bheads_>
they targeted the 90% but now the hard stuff is even harder
<very-mediocre>
Yeah, it's great for some projects
<very-mediocre>
imho the biggest flaw with Rust
<very-mediocre>
is that part of the tradeoff wasn't for safety
<bheads_>
but really an experianced programmer doesn't mess up the easy stuff
<very-mediocre>
productivity was lost for reasons other than safety at times, i.e. all those sigils
<very-mediocre>
it's very dense and hard to read
<very-mediocre>
bheads_: don't be so sure, I do stupid things all the time :)
<bheads_>
lol yeah, I avoided rust due to language and the fact that the hard stuff is not safe or easy
<very-mediocre>
yeah, but I have to give Rust credit
<bheads_>
oh I mess up the easy stuff too, but writting a threaded job handler that has messaging, sequencing and multiple memory patterns in all languages is hard enough
<very-mediocre>
iirc the section about ownership in the Rust manual had a section called "move semantics"
xtreak has quit [Ping timeout: 265 seconds]
<very-mediocre>
what's with all these memcpys!
<very-mediocre>
possibly an optimization?
<bheads_>
Thats really odd, I thought the point was that it moved ownership...
<very-mediocre>
like does it get optimized out at a later stage?
<very-mediocre>
i'm not at all familiar with llvm ir
<bheads_>
I mean I guessed it did, maybe the point class is small enough that it a copy is "okay" (tm)
<bheads_>
thats good, and it makes sense, as both are const
<bheads_>
but in rust, are a and b really pointers on the heap?
<very-mediocre>
iirc you have to Box<> things to put them on the heap
<very-mediocre>
so these should be stack?
<very-mediocre>
interesting test
<very-mediocre>
I'm sure we're missing something though
<very-mediocre>
why does Rust do 3 memcpy
<bheads_>
then why is it memcpy the assignment to a?
<very-mediocre>
Is that really an rvalue in the initial assignment?
<andrewrk>
very-mediocre, one for the variable declaration of `a`. one for the assignment to `b`. a third to do a by-value function call
<very-mediocre>
hm that's weird, the whole point of move semantics is not being wasteful with rvalues
<bheads_>
the call to foo is the only one that makes sense
<andrewrk>
zig has 2 because we defined "by-non-copying-value" function call semantics
<very-mediocre>
right
<very-mediocre>
tbf in idiomatic rust you'd pass a reference
<andrewrk>
right but my point is that `let b = a`, even with move semantics, does not elide the memcpy
<bheads_>
foo could be transfering ownership into a global space
<very-mediocre>
yeah, hmm
<bheads_>
so you cant barrow
<very-mediocre>
like C++ defines move semantics as copy elision for rvalues
<andrewrk>
so that's why I think move semantics are not relevant to zig
<very-mediocre>
those are very weird results though
<very-mediocre>
I get your point, that explicit moves might not be part of the language design
<andrewrk>
move semantics make sense if you have constructors and destructors
<bheads_>
there still is ownership transfer
<andrewrk>
yes but it's a userland concept
<very-mediocre>
agree with bheads_
<bheads_>
very true
<very-mediocre>
I'm surprised Rust does memcpy
<very-mediocre>
when you do b=a, a can no longer be used
<very-mediocre>
why copy it then?
<andrewrk>
I do think we will have the ability to disallow copies via assignment
<bheads_>
@notCopyable() on a struct def?
<andrewrk>
something like that
<bheads_>
sounds legit
<very-mediocre>
that sounds like move semantics :)
<andrewrk>
fair enough :)
<bheads_>
more of, dont copy this, you need to call self.copy() to handle this!
<very-mediocre>
Shooting from the hip here: inline fn move(a: T, b: T) T {}
<bheads_>
you would need pointer to pointer
<bheads_>
and b would need to be nullable
<very-mediocre>
not with the new copy elision semantics iirc
<very-mediocre>
but yeah
<very-mediocre>
i'd do pointers anyway, I'm OCD like that
<very-mediocre>
or perhaps
<very-mediocre>
a.move(b)
<very-mediocre>
I like userland for this I guess
<bheads_>
it would have to be a language construct since a pointer is not a struct
<bheads_>
const b #= a; // a is now null
<bheads_>
but as andrew pointed out, this is a userland idea
<very-mediocre>
just pointer swap, no?
<bheads_>
if your avoiding a memcpy
<very-mediocre>
in C++ the move constructor is implemented as a manual userland pointer swap
<very-mediocre>
the compiler is just there to call the move constructor when you assign
<bheads_>
sometimes
<very-mediocre>
yeah, typically
<bheads_>
if the result is on the stack in the calling function you could use that memory in place
<bheads_>
no sure how many compilers can do that though
<very-mediocre>
hm I'm finding that Rust result hard to believe
<bheads_>
maybe a debug build thing?
<very-mediocre>
Why is the initial declaration a memcpy
<very-mediocre>
like it instantians the Point anonymously, then copies it to a new address and assigns it?
<very-mediocre>
instantiates**
<very-mediocre>
andrewrk: could the Rust test have been in a debug configuration?
<andrewrk>
very-mediocre, yes it was, as was the zig one
<bheads_>
in D the compiler has a block of memory for a struct in ROM that is in the init state. when you create an instance it copies the init state to the new location, then it calls a postblit function on it (a constructor)
<very-mediocre>
andrewrk: I bet the memcpy's get optimized out in release builds then, no?
<andrewrk>
with optimizations on, in both the zig and rust examples, there would be no memcpy's
<very-mediocre>
ah
<very-mediocre>
thanks for clarifying
<very-mediocre>
I guess Rust relies on the optimizations
<very-mediocre>
btw andrewrk on a different note, do you plan to have an idiomatic style regarding snake case vs camelCase vs PascalCase?
<very-mediocre>
some languages endorse a particular style
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<very-mediocre>
any idiom for explicitly discarding an unused return value?
<donpdonp>
_ = returnvaluefunc();
<very-mediocre>
ahhh
<very-mediocre>
awesome thanks
<very-mediocre>
i knew i'd seen it somewhere but couldn't find it
jjido has joined #zig
<GitHub129>
[zig] andrewrk opened pull request #1134: remove error set casting syntax. add `@errSetCast` (master...no-explicit-casting) https://git.io/ffC41
<MajorLag1>
andrewrk, is the old casting syntax meant to still work on the condition that the type you're casting to is the same signedness and >= bit_count of the source type?
<andrewrk>
yes, all the casts still work where you could do: var x: T = value;
<andrewrk>
this is now equivalent to T(value)
<andrewrk>
so now there is no "cast harder" syntax. instead there are explicit builtins for all the kinds of casting you would want
<andrewrk>
this is in line with the "communicate intent precisely" philosophy
<MajorLag1>
There had been some talk of removing the `var x = T(value);` variation, so I wasn't sure.
<andrewrk>
that'll be a separate proposal. not happening any time soon, if ever
<MajorLag1>
good to know, thanks.
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
davr0s has joined #zig
noonien has quit [Quit: Connection closed for inactivity]
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jjido has joined #zig
very-mediocre has quit [Quit: Page closed]
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
bheads has joined #zig
bheads__ has joined #zig
bheads_ has quit [Ping timeout: 248 seconds]
Ichorio has quit [Ping timeout: 256 seconds]
hinst has quit [Ping timeout: 260 seconds]
hinst has joined #zig
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]