<AlexMax>
probably, but as I just get a TODO and no error position I haven't the foggiest what it's complaining baout
<scientes>
AlexMax, you can break on zig_panic in gdb
<AlexMax>
I'll try that sometime. If it piques anybody's curiosity, I get the same panic even with an empty function body.
<AlexMax>
panic, TODO, whichever mechanism it uses
<dimenus>
why woudl vulkan make the y axis point downwards? o.0
<dimenus>
*would
<scientes>
dimenus, maybe they think they are piloting an airplane?
<dimenus>
it' uses the same depth range as D3D, but the choice to flip Y feels random
<AlexMax>
i always flip Y-coordinates dealing with opengl
kristoff_it has joined #zig
<dimenus>
yeah, i guess it's just clip space
kristoff_it has quit [Ping timeout: 245 seconds]
marijnfs has joined #zig
<Tetralux>
[Modified the "Troubleshooting Build Issues" wiki page to mention how to fix apparently problem with building on Ubuntu.]
marijnfs__ has quit [Ping timeout: 244 seconds]
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 245 seconds]
kristoff_it has joined #zig
laaron has quit [Remote host closed the connection]
laaron has joined #zig
<mikdusan2>
is 'DutchGhost' on irc?
curtisf has joined #zig
<dimenus>
777 issues!
<dimenus>
I think Zig is popular
<Tetralux>
It seems we are _one_ better than the devil.
<Tetralux>
In three different digits no less!
batok has quit [Remote host closed the connection]
<AlexMax>
Out of curiosity, is there a nice way to get "zig build" to deposit the executable in my current directory
<AlexMax>
or someplace other than somewhere in the cache?
laaron has quit [Remote host closed the connection]
<mikdusan2>
b.setInstallPrefix(".");
laaron has joined #zig
NI33_ has quit [Ping timeout: 248 seconds]
mikdusan2 is now known as mikdusan
darithorn has quit [Quit: Leaving]
dimenus has quit [Remote host closed the connection]
<andrewrk>
AlexMax, for what it's worth, the reason for the default is that there are other kinds of things to be installed besides binaries: libraries, headers, and other data files
<andrewrk>
I don't consider that aspect of the design to be complete, I'd welcome a well thought out proposal for where things should be "installed" by default
<andrewrk>
there are also the differences between platforms to be considered
<fengb>
translate-c somehow converted `c=a+((b-a)>>1)` into `c = (a + ((b - a) >> @import("std").math.Log2Int(c_int)(1)));`
<andrewrk>
yep
<andrewrk>
that's how C works. if your type doesn't fit in that cast it's undefined behavior
<andrewrk>
it should be @intCast though. I think that translate-c code outlived explicit-casting-as-functions
<fengb>
What's with the log?
<andrewrk>
note that's a function that takes a type and returns a type
<andrewrk>
shift operations take, as a right-hand-side operand, a type which has log2 the number of bits of the left-hand-side operand
<fengb>
Oh I see
<fengb>
I totally forgot about that. So overshifting is undefined?
<andrewrk>
well you can't overshift in zig
<andrewrk>
because of the types
<andrewrk>
but @intCast is illegal behavior if you cast your int to a type that can't fit it
<Tetralux>
It seems very weird to me that C doesn't just say "oh - if you overshift, it just shifts in zeros"
<Tetralux>
Like - I hate undefined-behavior-that-doesn't-need-to-be, SO. Much.
<Tetralux>
Just do the reasonable thing or error already x'D
<andrewrk>
zig has std.math.shl for that
<andrewrk>
it even supports negative operands
<curtisf>
did some really old cpus have only one of shift rotate / shift zeros maybe? and maybe some of them only took a few bits to do the shift instead of a full word? it also helps compilers somewhat to just always assume the rhs is in bounds
<curtisf>
specifying an assert is probably something they didn't think they could do
<curtisf>
but it would have been nice if some c compilers came prepackaged with a way to insert asserts on all of these things
<curtisf>
I'm really happy with Zig's choice to have a "safe" mode, because it makes UB a whole lot less scary
<Tetralux>
Personally, I might prefer to totally remove UB completely, and allow the compiler to optimize anything it can provided that behavior is maintained.
<curtisf>
I don't really believe it's meaningful to eliminate UB from a language without having an extremely expressive type/constraint/invariant language
<curtisf>
meaningfully possible*
<fengb>
The only way to remove UB completely is bubble up every possible error. Either you take the performance check for error bounds checks, or you have to convince the compiler it cannot happen
<fengb>
Like... a + b is undefined for edge cases of a and b. That'd make math insanely tedious
<curtisf>
it's far, far beyond bounds checks, though
<curtisf>
what do you do if you pass `qsort` a non-transitive comparison function?
<curtisf>
you can detect this _sometimes_, but you won't always detect it unless you compare every element to every other element
<fengb>
Eh... I'd argue userland bugs are userland bugs. Otherwise you have a halting problem
Tetralux2 has joined #zig
<fengb>
I like the way Zig handles it. UB is an error for safe mode, but I can still "escape" if I ask the compiler nicely
<fengb>
And thar be dragons but it's my own fault
<curtisf>
parallelism is also a problem, because you can't specify the language to behave like an interleaving of atomic instructions, since that's not possible without taking a lock every other cycle. so data races also produce undefined behavior
<curtisf>
you can try to push this to say "oh, the language doesn't have undefined behavior, but things can still go arbitrarily wrong if you miscall libraries" which is maybe better but the thing that's actually bad about UB is still there
Tetralux has quit [Ping timeout: 245 seconds]
<fengb>
Rust kinda solves that
<Tetralux2>
The only way to solve it is to bubble up every possible error
<Tetralux2>
I mean
<Tetralux2>
Just define the behaviour?
<Tetralux2>
Like
<curtisf>
How do you solve the `qsort` example?
<Tetralux2>
"shifting always shifts in zeroes"
<fengb>
Well, if you have one reference implementation, you can always define it as the "defined" behavior
andrewrk has quit [Ping timeout: 244 seconds]
<fengb>
Whether it's sensical is up for debate
<Tetralux2>
point is
<Tetralux2>
Choose Sane Behaviour
<Tetralux2>
If you tell me that you don't know what a shift is gonna do I'm gonna burn a hole in your soul XD
<Tetralux2>
It seems the most sane to just define it that in debug mode trying to shift to far is an assertion failure
<Tetralux2>
Or just so nothing
<Tetralux2>
Do*
<Tetralux2>
Or something
<Tetralux2>
But more importantly
<Tetralux2>
If you shift to far, it shifts in zeroes
<Tetralux2>
And in debug mode, you could enable bound checks for it if you want them
<fengb>
C was also created at a time when "portable assembly" was more important than language spec
<Tetralux2>
There. Typing on a phone with autocorrect is hard work man
<Tetralux2>
And you don't need a reference implementation to do that
<fengb>
Yeah it's kludgy and underdefined, but people build stupid C compilers that worked on weirdo architectures
<Tetralux2>
Even an informal spec would do XD
<fengb>
ANSI was the first real spec, and it basically left anything that existing C compilers disagreed on as "undefined". Maybe it should have been more strict?
<Tetralux2>
Force people who want to compile for those arch's to provide a `--enable-real-bollocks` flag
<Tetralux2>
Just to make it THAT obvious
<Tetralux2>
And yes
<Tetralux2>
I like Jais approach
<Tetralux2>
Choose Sane Behaviour.
<Tetralux2>
It's just like "stack vars are always zeroed unless you declare them uninit"
<Tetralux2>
This is Sane Behaviour.
<Tetralux2>
I *want* Sane Behaviour.
curtisf has quit [Remote host closed the connection]
<andrewrk>
I don't think this "sane" "insane" characterization is helpful. it's better to make actual arguments
Tetralux2 has quit [Ping timeout: 260 seconds]
<andrewrk>
for example: not defining zero as a meaningful initialization value has benefits in that tools can know when use of undefined values occur. with guaranteed zero initialization, bugs are indistinguishable from well-defined behavior
kristoff_it has joined #zig
laaron has quit [Remote host closed the connection]
<emekankurumeh[m]>
with stage 2 would there be any value in rewriting it in pure zig? or is that stage 3 I'm thinking of?
batok has quit [Remote host closed the connection]
<samtebbs>
scientes: I see. Just pausing with an infinite loop is less desirable than sleeping as sleeping explicitly tells the scheduler that this process can be yielded in favour of other processes
<scientes>
I still think we should have a @halt() and then set it as undefined
<gonz_>
mq32: Whatever you end up writing about it, maybe just releasing some code, etc., toss me a message.
<scientes>
if you have an OS @halt() will call the os, and sleep infinitely
<samtebbs>
mq32: I'd be interested too :)
<samtebbs>
scientes: Yeah, that's a nice idea
Tetralux has quit [Ping timeout: 268 seconds]
<scientes>
we can probably also trick the compiler to tell use where all the infinite loops are so we don't forget to convert soe
<mq32>
gonz_, samtebbs: you guys give me a motivational boost :) something to do for the weekend :)
<mq32>
hm, random brainfart:
<samtebbs>
scientes: Perhaps a warning on finding an halting loop (while(true) {}) that suggests converting it to a sleep or halt would be good
<scientes>
samtebbs, zig does not have warnings
<samtebbs>
By design?
<scientes>
yes
<samtebbs>
mq32: Looking forward to it :)
<scientes>
but the most trivial version could be pattern matched and be an error
<samtebbs>
Is it really an error?
<mq32>
does anyone except me find the idea of having arbitrary significance integer literals useful (or just literals for bit groups)
<mq32>
so like quaternary numbers or similar?
<scientes>
mq32, the problem with such things in the language is that it require the compiler writer to understand such math
<scientes>
and you would really need to get it into LLVM to be worth putting into Zig
nairou_ has joined #zig
<scientes>
LLVM is in the process of adding complex numbers
<mq32>
nah, it's just number iterals (binary, quaternary, octal, hexadecimal), ...
<scientes>
oh, no, just binary and headecimal
<scientes>
octal should be removed
<scientes>
and quaternary is too similar to "quaternian"
<mq32>
quaternary is useful for writing stuff like manchester encoding, color values with 2 bit per channel, ...
<scientes>
which is something totally different
<scientes>
mq32, you can do that in comptime, this is zig after all
<scientes>
and octal should be removed and replaced with a comptime implementation
batok has joined #zig
<mq32>
you mean like
<mq32>
xq.numbers.quaternary("031234");
<mq32>
damn. I like zig
<mq32>
this whole comptime thing is just too powerful
laaron has quit [Remote host closed the connection]
<dimenus>
does anyone build zig with the vs2019 toolchain?
<mikdusan>
yes in a vm
<dimenus>
Mine used to compile but now it fails when building libuserland
<dimenus>
what version mikdusan?
<mq32>
gonz_, neat. does it support spaces like seconds("3h 23m 33s"); ?
<dimenus>
i have a master tree that builds fine with v2017 but fails on v2019
<gonz_>
mq32: Not right now, but it's a `continue` in the `switch`
<mikdusan>
dimenus: i usually build against windows10 vs2019 before making a PR but it's been a week or so
<gonz_>
+ "... away"
<mikdusan>
dimenus: i'll fire it up and run against master. do you get a build error or test error?
<gonz_>
mq32: Actually, it does ignore any other character that isn't relevant
<gonz_>
so yeah, it'll just happily truck on with those spaces
<dimenus>
mikdusan: build error
<dimenus>
i'm running 19.22.27905 for cl
<kristoff_it>
gonz_: nice library! if you want to improve it, remove some `comptime` constraints. the function doesn't seem to really need comptime arguments and a caller would still be able to call your function at comptime using `const seconds = comptime humantime.seconds(...);`
<kristoff_it>
gonz_: this way it's possible to use it to parse user input, for example
<gonz_>
kristoff_it: I did have that from the beginning, yes, but was debating whether or not to constrain it. I'll open it up and let it be decided at the call-site.
nairou_ has quit [Read error: Connection reset by peer]
nairou_ has joined #zig
<gonz_>
`comptime` should be needed for the `@compileError` bit, but I guess I'll just make it crash
<gonz_>
I still don't know that it's worth it to even handle it because of the condition already being checked in the `switch`
<mikdusan>
dimenus: i'll launch a build as soon as the vm settles down. every week or so windows likes to do a ton of disk IO (prob security scan or somesuch) and I can't get anything done until that finishes because VM disk IO is sloooow
<dimenus>
heh
<dimenus>
sounds good
<mikdusan>
builds for me: windows10, cl 19.21.27702.2, master branch 7f23dac6dce2ce897295e8186f164f695cacdbc9
<mikdusan>
what build error do you see?
<dimenus>
o.0
<dimenus>
invalid builtin function 'hasDecl'
<dimenus>
it's like the FNV32 hash has a bug or something when compiled on my system
<dimenus>
ah, your cl is older
<dimenus>
which would fit with my memory that it used to compile for me but doesn't now
laaron- has quit [Remote host closed the connection]
<mikdusan>
i'll try to upgrade. do you have a buildtools update link handy? :)
<dimenus>
no, this is my work pc - i use the full vs install
<dimenus>
it's not as bad now with 2017/2019
<dimenus>
unlike the 50GB install it used to be
<dimenus>
you can pick and chose components in an adhoc fashion
<dimenus>
yeah i saw that issue yesterday, I'm glad we have it narrowed down to being msvc
<dimenus>
i was so frustrated yesterday
<kristoff_it>
gonz_: you could also change the function return an error in such case. at comptime making the build fail is probably ok, at runtime the right reaction really depends on the usage context. I think that it would be best to let the caller decide what to do in both cases.
<gamester>
I'd just have it comptime-only.
<gamester>
gonz_: The library is a really nice idea btw, I love it!
nairou_ has quit [Read error: Connection reset by peer]
nairou_ has joined #zig
<scientes>
dimenus, no, and I don't really see a reason why, because any code that uses vectors in C uses non-portable x86, arm, or ppc intrinsics
andersfr has quit []
<dimenus>
hmmm, zig clang is not picking up that it's a native target
porky11 has joined #zig
THFKA4 has joined #zig
<scientes>
dimenus, can you give more details?
<dimenus>
i take that back, it is
<dimenus>
basically, i'm getting a bunch of undefined references for intrinsic instructions on win10 x64
<dimenus>
eg _mm_setr_epi16
<scientes>
dimenus, that is a known bug
<scientes>
those are not functions
<dimenus>
this worked before o.0
<scientes>
I think I explained this before
<dimenus>
i know they're not supposed to be
<scientes>
no, the compiler should error out when importing those special header files
<scientes>
I think we already have special handling for #include <stdbool.h>
<scientes>
and there are a few other special header files
<andrewrk>
dimenus, did something change on your computer? I've been building with win10 x64 msvc2019
<dimenus>
andrewrk: yes, msvc updated
<dimenus>
19.21 works fine, 19.22 does not
<andrewrk>
hmm let me try it now
<dimenus>
andrewrk: mikdusan confirmed the issue on his vm
<scientes>
see we don't have all these __builtin_* functions
<andrewrk>
dimenus, I guess we can make sure it's not UB
<scientes>
there are some we should implement, like __builtin_popcount and __builtin_clz
<gonz_>
We do have popcount, no?
<gonz_>
`@popcount`
<gonz_>
`@popCount`*
<scientes>
gonz_, yeah but we don't convert from GNU popcount extension to @popCount
<scientes>
in translate-c
<gonz_>
Ahaa
<gonz_>
Right
<scientes>
but of course if you just build with zig cc (which is clang) then it will work
<mikdusan>
vs2019 19.22.xxx CMAKE_BUILD_TYPE=Release is build failure
<mikdusan>
here is a hint: CMAKE_BUILD_TYPE=MinSizeRel is build success
Tetralux has joined #zig
<mikdusan>
her is another hint: changing `/Ob2` -> `/Ob1` is build success with CMAKE_BUILD_TYPE=Release
<scientes>
mikdusan, you could set up an automated bisection
<mikdusan>
no
<dimenus>
scientes: I'm sorry i'm being thick here, but I don't know why SSE2 intrinsic would not work on x64
<dimenus>
i've totally used this setup before
<scientes>
dimenus, you can compile it with clang, but zig doesn't implement those __builtin_* functions, those are not in C, they are implemented by the compiler
<donpdonp>
nice writeup on 'comptime' at the top of lobste.rs
<dimenus>
scientes: nothing is calling a __builtin_* function here
<dimenus>
this is straight _mm_set_epi16
<dimenus>
which compiles just fine with mingw on windows
<dimenus>
it's only the msvc toolchain that's failling
<scientes>
that's the definition of _mm_set_epi16 in the clang headers
<scientes>
dimenus, the only way to use those directly is to use llvm's inline assembly
<scientes>
which is what clang does
<dimenus>
i'm compiling a c file using zig cc
<scientes>
oh then it should work
<dimenus>
....
<dimenus>
indeed
<scientes>
maybe you are using a differn't compiler's headers
<scientes>
are those headers are compiler-specific
<Tetralux>
mq32: RE UB, you can remove it in low level languages. You just put effort into thinking about what sane behavior would be, and then implement that on all platforms.
<dimenus>
mikdusan: so MSVC is generating invalid code when it tries to inline either the table get call or the hash itself
<dimenus>
i bet this is msvc's fault again....
<mikdusan>
yes something is manifesting with `/Ob2` and 19.22.xxx
<dimenus>
le sigh, yep it's msvc
<dimenus>
scientes: msvc defines _mm_setr_epi16 as extern
<dimenus>
good call
<scientes>
dimenus, but why are you using the wrong headers? it should use the internal (clang) headers first
<dimenus>
scientes: I'm not using the wrong headers, zig just appends msvc's headers first
<dimenus>
let me make that change....
<scientes>
that sounds like a bug
<scientes>
like it will probably break <stdbool.h> <stdnoreturn.h> et cetera
<gonz_>
gamester: Yeah, it's one of those small things that I've really liked having in our code in other languages.
<gonz_>
kristoff_it: In this case I don't know that it actually needs to be handled explicitly since the pre-requisite is checked in the switch anyway.
laaron has joined #zig
<dimenus>
scientes: it was indeed a header precedence bug, thanks for the tip
<scientes>
dimenus, i think you should file a bug/write a patch
<scientes>
cause I'm pretty sure the clang headers should come first
<dimenus>
/ According to Rich Felker libc headers are supposed to go before C language headers.
<scientes>
oh ok
<dimenus>
the problem here is that it's not just libc, it's the intrinsics for the compiler
<scientes>
then complain to him in #musl that stuff breaks then
<scientes>
or rather, special C language headers should come first
<scientes>
the ones in the C standard and the SIMD extension headers
<scientes>
well, the C standard also defines libc stuff
<dimenus>
i'll write a patch, winsdk headers should come first
<scientes>
so there is complicated overlap
<dimenus>
but not MSVC specific sones
<dimenus>
in msvc, stdio, stdlib, stddef = winSDK - stdarg, stdbool, intrinsics etc = MSVC dir
<scientes>
ahh yes, that sounds right
kristoff_it has quit [Ping timeout: 245 seconds]
<dimenus>
actually, we really shouldn't even be using msvc's header dir
<dimenus>
since clang does that grunt work
<scientes>
are you sure?
<scientes>
oh yes, indeed
<scientes>
just winSDK
<dimenus>
ah, native clang does include it - but it uses its own headers first
<dimenus>
so i think we should just replicate what regular clang does
<dimenus>
andrewrk: do you care to weigh in here? Not sure where you read that detail from Rich
<dimenus>
andrewrk: to summarize, because we're adding libc headers to the search path before the C language headers from clang - intrinsics and anything specific to MSVC are broken
<dimenus>
we either need to separate "compiler specific headers" into its own list and put them further down the totem pole
<dimenus>
or just move clang's headers up to the top of the list
<dimenus>
(which is what regular clang does on windows)
<andrewrk>
if it needs to be the other way around for intrinsics to work, so be it. let's make that change.
<dimenus>
do you want me to submit a PR/issue for it then?
<andrewrk>
yes please, feel free to skip to the PR
Akuli has joined #zig
<dimenus>
andrewrk: submitted
<andrewrk>
emekankurumeh[m], thank you for the great question about an async function being able to destroy its own frame. that's now part of the semantics in the branch, and i'm about to write a test for it
<dimenus>
andrewrk: code note updated
<andrewrk>
dimenus, merged. the code was this way for some time so I'm pretty sure it should be ok. if it breaks things then we can investigate
<dimenus>
clang uses its own headers first
<dimenus>
so we have it mostly correct, we should just split "libc" headers from other platform headers
<dimenus>
eg with windows, WinSDK can be high up on the list, but MSVC headers cannot be above clang's
<andrewrk>
I see
<mikdusan>
makes sense. by putting clang-intrinsics first, other "libc" can be used. beit zig+musl, or linux /usr/include or winsdk provided, or macos-sdk provided
<scientes>
andrewrk, I am interested in submitting a proposal to give a talk on SIMD in Zig at the LLVM dev mtg in october, here are what I have for slides for my proposal (which can of course change) https://git.icu/dl/LLVM2019.pdf and here is the abstract https://bpaste.net/raw/xjbK I am also hoping you can give a thumbs-up thumbs-down to the general direction of my patch series
<andrewrk>
scientes, that's exciting. I can do that within a couple weeks
<scientes>
ok, but I have to submit the proposal this week
<andrewrk>
ok I can give a high level patch series lookover tomorrow
<scientes>
thank you
<scientes>
the submission deadline is sunday night
<donpdonp>
hmm could be a prob with the installation. 2019-07-06/lib/zig/include/stddef.h is there but 2019-08-05 has it in the wrong place. probably my problem. <grin>
laaron has joined #zig
nairou_ has quit [Read error: Connection reset by peer]
nairou_ has joined #zig
laaron has quit [Remote host closed the connection]
laaron has joined #zig
nairou_ has quit [Ping timeout: 268 seconds]
nairou_ has joined #zig
<emekankurumeh[m]>
wait, I thought you can't `try` in defer...
SimonNa has joined #zig
wootehfoot has quit [Read error: Connection reset by peer]
<scientes>
i only see that it wouldn't make sense in errdefer
<emekankurumeh[m]>
I've got an error whenever I've tried to do it in the past...
<scientes>
well i guess you would want all the defers to run
<scientes>
and try would mean that wouldn't be the case
<scientes>
like return should also not be allowed
<andrewrk>
the only way to prevent the rest of the defers from running is to panic / exit
<andrewrk>
you can't "return early" to skip defers
<andrewrk>
in the async/await branch, I've made it legal to suspend inside a defer - e.g. await or cancel - because these operations are now guaranteed to complete. cancellation points are now fully explicit
huuskes has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
<shachaf>
Is "fn foo() int { defer { return 1; } return 2; }" permitted?
<shachaf>
I guess I can test it.
<shachaf>
It's not permitted. Why would try be different?
<Tetralux>
Because try is different? xD
<Tetralux>
I'm also not sure what 'defer return' should do.
<Tetralux>
Override any return you otherwise did?
<andrewrk>
you shouldn't be able to `try` inside a defer either, sounds like a missing compile error
<Tetralux>
try is just "attempt to do something that may fail"
<shachaf>
Oh, maybe it's not permitted and I misunderstood the above.
autodidaddict has quit [Remote host closed the connection]
<Tetralux>
'defer try' is orthogonal to 'defer return' isn't it?
<andrewrk>
`try x` can be desugared to: `x catch |e| return e`
<Tetralux>
Oh yeah... fair point.
<Tetralux>
Though, to be fair, I still think those two things are different.
<Tetralux>
'defer return' doesn't make much sense.
<Tetralux>
I'd prob be okay with both being illegal though.
<fengb>
Try is just a special return so it would also not make sense
<fengb>
*conditional return
<Tetralux>
Well
<Tetralux>
Actually.
<Tetralux>
Both _do_ make sense, IF you don't otherwise return normally.
<Tetralux>
fn foo(x: usize) bool { defer return x == 0; x *= 2; }
<Tetralux>
Or at least 'defer return' does - I'd have to think more about the other.
<mikdusan>
defer is not a return hook
<Tetralux>
I mean it makes logical sense in the context I laid out.
<Tetralux>
I'm not saying that it should be in Zig x)
<Tetralux>
It might help to set up the expectation of what's being returned at the top of a procedure before you read anything about what happens to the expression in the rest of the procedure though, which I think might help reading code.
SimonNa has quit [Remote host closed the connection]
<scientes>
it is well defined, but it makes the control flow too confusing the reason about
<Tetralux>
I dunno - maybe some research in that direction could be interesting.
<scientes>
and the whole point of defer and errdefer is to have more understandable control flow
<scientes>
so i think forbidding return and try from defer and errdefer makes sense
<Tetralux>
I think that it would _not_ make it harder to understand, expressly because it'd be at the top of a procedure. Like, "we always return x at the end" sets an expectation in your mind up front, and lays out perspective as to what the "end goal" is, as it were.
<Tetralux>
It may mean you don't have to read some code more than once.
<Tetralux>
(.. in order to correctly understand it.)
ntgg has joined #zig
<Tetralux>
But I think research would be warranted to explore that.
<Tetralux>
And yeah, we'll be fine without it.
<Tetralux>
Though, I have no actual evidence with which I say that.
<Tetralux>
You can still express the intent either way.
<scientes>
you can always use if() for your control flow
<Tetralux>
Indeed, and you can return an if.
<Tetralux>
Although curiously
<scientes>
defer and errdefer is just to simplify common stuff
<Tetralux>
return if() { code } else expr;
<scientes>
as is the whole error handling stuff
<Tetralux>
^ doesn't seem to work iirc.
<Tetralux>
and yeah, indeed.
<scientes>
Tetralux, yes it does
<scientes>
a similar thing with return switch is all over the code
<Tetralux>
scientes: I say that because I tried returning an if the other day and I seem to recall that putting braces for the else fixed it
<fengb>
defer isn't always at the top
<Tetralux>
fengb: I know. But the context I was describing, the point would be that you probably would.
<Tetralux>
Also, andrewrk, you said about how coroutines will be cancelled explicitly; can you clarify how that's different from before exactly?
<Tetralux>
Does doing cancel destroy the frame immediately? Or more like "marks it as done without a result value".
<mikdusan>
Tetralux: i'm ok with idea of defer code to examine/modify stuff *before* return, i just don't want it messing with result-location already "defined" by actual return/sugar semantics
<scientes>
Tetralux, the main difference is that memory allocation of the co-routine frame is separate
<scientes>
AFAIU
<andrewrk>
Tetralux, `cancel` is the same as `await` except it sets the cancel bit
<andrewrk>
cancel is a suspend point
<Tetralux>
cancelling just means "we would have resumed it otherwise, we now will not"
<andrewrk>
almost. it means we would have *awaited* it otherwise, we now will not
<andrewrk>
using `resume` on a frame that is ready to be awaited is a safety panic
<andrewrk>
`resume` goes with `suspend`. `cancel` goes with `await`
<Tetralux>
You'd use cancel on something that doesn't give a result and you don't care when it's done? Kind fire-and-forget style thing?
<andrewrk>
basically after every await, you're going to defer a cancel
<andrewrk>
sorry, after every *async* call
<Tetralux>
.. Had me confused for a sec there xD
<Tetralux>
So it's like
<andrewrk>
after async, you have 2 choices: cancel, or await. cancel is safe to do multiple times
<Tetralux>
.. because if you already cancelled, it does nothing?
<andrewrk>
right, if you already canceled or awaited
<Tetralux>
Does awaiting multiple times return the same result as the first time?
<Tetralux>
Or is that panic?
<andrewrk>
awaiting multiple times is panic
<Tetralux>
How do you know if a promise is complete?
<andrewrk>
you don't. you await it when you want the result
<scientes>
these are co-routines, they run in a single thread
<dimenus>
is it possible to create a slice from a ptr?
<andrewrk>
scientes, we're calling them async functions now
<andrewrk>
dimenus, you can slice the ptr
<andrewrk>
ptr[0..n]
<scientes>
andrewrk, but are they always asyncronos?u
<andrewrk>
nope, you can in fact define a function whose async-ness will be inferred by what functions it calls
<scientes>
but I mean, co-routines are not really asyncronous
<scientes>
and they do not have race conditions that asyncronous code has
<Tetralux>
From the point of view of the imperative code you are writing, they are though. No?
<andrewrk>
what's the question?
<fengb>
I thought the point is you can toss the async function to a thread pool and then it'd be really asynchronous
<dimenus>
'slice of single-item pointer'
<andrewrk>
fengb, it's the other way around: std.fs.File.write will decide whether it should use an event loop or a blocking syscall based on some comptime configuration (e.g. pub const io_mode = .blocking; // in root source file)
<dimenus>
do i just change the c import?
<andrewrk>
dimenus, this is an auto generated type?
<scientes>
like if you do if (some_variable) { do_something() }; well, if some_variable is change by another thread then that is a race condition
<andrewrk>
or did you decide the type?
<scientes>
and you would need to do an atomic load with .Acquire semantics
<scientes>
but you don't if you know the only other thread to change it is actually a co-routine
<dimenus>
andrewrk: the c type is [*c]const stbi_uc
<andrewrk>
scientes, yes we're going to need some safety features for concurrency
<dimenus>
I want []Pixel
<dimenus>
which is align 4
<andrewrk>
dimenus, oh you can't slice [*c] pointers? that's a bug
<scientes>
some calling it "async" seems kind of funny, when it isn't necessarily asyncronous
<dimenus>
maybe i can
<andrewrk>
scientes, they are "async functions" because unlike normal functions, the start and end of the function call are not at the same call site
<scientes>
or rather, because they use the "async" keyword (which is fine)
<andrewrk>
I think the name works and it gives people a better idea of the semantics than "coroutines"
<scientes>
yeah, its fine
<scientes>
and if you write async then you will always be fine
<andrewrk>
they really are just functions
<andrewrk>
functions that can suspend
<dimenus>
andrewrk: I can slice them, i was just doing this backwards
<Tetralux>
.. and only when they return with .Complete, effectively, do they _actually_ return.
<andrewrk>
but normal functions can be suspended by the kernel. so really they're just functions! it's beautiful
<scientes>
andrewrk, yes, user-space programs are always async
<Tetralux>
I assume that you have to defer cancel by the way, because you _must_ await or cancel an asynfn.
<Tetralux>
And if you cancel, does that mean the function won't resume once it next suspends, even if it didn't get to the '.Complete' stage?
<andrewrk>
it's well-defined what happens if you don't await/cancel
<fengb>
JS promises let you await multiple times. Can we emulate that behavior? (Or is it even desirable?)
<Tetralux>
andrewrk, Oh? What happens?
<andrewrk>
Tetralux, the defers don't run. probably a resource leak. but if you don't have any resources to leak, it's fine
<scientes>
but that would mean the async function would have to be stackless
<scientes>
to not leak any resources
<andrewrk>
fengb, I don't think that's going to happen. async functions really are equivalent to functions, but with separate start (async) and end (await/return) positions
<andrewrk>
however you could design a userspace type which does this
<Tetralux>
Where _does_ stack variables inside the async function get stored?
<fengb>
I think I'll need to relearn this. JS async map to promises directly so it's a lot more value driven than control flow
<andrewrk>
async functions have a "frame" which all their state is stored on. the async caller supplies the frame to the callee
<Tetralux>
Does "supply" mean that the callee essentially does 'alloca' on the caller's stack for this?
<fengb>
It wouldn't be alloca since we know the callee's stack size
<scientes>
and can they both use the caller's stack and their own stack?
<mikdusan>
callsite choice. if LHS is a stackvar then it goes in stackvar. if LHS is a `p.* = async foo()` then p is presumably heap alloc
<scientes>
because they aren't really async they can actually all share a stack
<andrewrk>
Tetralux, not literally alloca (a runtime stack bump) but yes it goes in the caller's frame
<andrewrk>
you decide where it goes, it's the return type of async
<andrewrk>
var frame = async foo(); // you chose for it to go in the frame of the caller
<andrewrk>
heap_ptr.* = async foo(); // you chose for it to go on the heap
<Tetralux>
AHHHHH
<Tetralux>
I see
<scientes>
but how do you set the stack pointer?
<Tetralux>
So the promise, IS, quite literally, the stack of the async fn?
ntgg has quit [Ping timeout: 248 seconds]
<andrewrk>
scientes, async functions are generated with all locals in a struct, which is passed as a secret pointer parameter
<andrewrk>
Tetralux, yes but just one stack *frame* though, not an entire stack
<scientes>
andrewrk, but what if the async function calls another function, which expects a stack?
<Tetralux>
It depends on where the top level async fn put the promise.
<andrewrk>
scientes, async functions have a kernel stack which they use for function calls. it's only their one frame that does not go on the kernel stack
<scientes>
so all functions calls from a async function would have to use @newStackCall ?
<andrewrk>
why don't you have a look at the passing tests in the rewrite-coroutines branch - all the tests from master branch are (modified and) passing
<scientes>
oh ok, cool
<andrewrk>
there are also some interesting safety panic tests
<andrewrk>
here's how you can think about this: you take a normal function, ok, everything is the same so far, and you take its stack frame, and you put it somewhere else.
<andrewrk>
that's it. that's the main idea
<andrewrk>
everything else follows from that
<Tetralux>
.. and the stack frame of the async fn, is just it's promise?
<andrewrk>
the concept of "promise" is deleted
<andrewrk>
`anyframe->T` is the type you can await
<andrewrk>
which is a pointer to a frame of a function which has return type T
<Tetralux>
.. and is the type that you get back from 'async f()' which can be awaited or cancelled.
<andrewrk>
from async f() you actually get a @Frame(f)
<andrewrk>
but you can implicitly cast *@Frame(f) to anyframe->T where T is the return type of f
<andrewrk>
@asyncCall returns a anyframe->T
<andrewrk>
because that one lets you call async function pointers
<fengb>
andrewrk : I found an edge case where I want a @call(). The compiler is inlining incorrectly, so I want release-small to force @noInlineCall(), but I don't have a default fallback for non-small variants
<andrewrk>
fengb, that's a good use case
<fengb>
Should I write up a proposal?
<andrewrk>
I think we can solve this by making inline and noinline calling conventions, and having @call let you choose a calling convention from an enum
<andrewrk>
hmm maybe not. yeah a proposal would be welcome
<mikdusan>
so if a fn has suspend keyword, what happens if it is call'd just like a good'ole regular function without `async` keyword?
<mikdusan>
*fn body
<andrewrk>
mikdusan, then it makes the calling function also be an async function
<Tetralux>
Turns the fn async, and gives an error along the lines of "must cancel or await" ?
<Tetralux>
Or no - it's fine - because defer just don't get run right.
<Tetralux>
defers*
<andrewrk>
when you call an async function (without the async keyword), that's the same thing as doing `await async foo();` which is a particularly efficient way to call an async function
<andrewrk>
it works like a normal function
<Tetralux>
Presumably, 'await async f()' means "suspend myself, run f(), give me the result and resume myself", essentially.
<Tetralux>
And by "means", I mean "does." xD
<Tetralux>
Hmmm. What circumstance would you want to NOT cancel or await?
<Tetralux>
Surely you'd always want defers to be run upon asyncfn completion, no?
<mikdusan>
i am amazed at how much is going into zig 0.4.0 -> 0.5.0
<nrdmn>
will #786 (better handling of error set integer type) be going into 0.5.0?
gamester has joined #zig
Ichorio has joined #zig
huuskes has joined #zig
<gamester>
andrewrk: The idea of detecting unused functions and raising a compile error on them is interesting. I imagine the experience is going to be very varied when testing out ideas as sometimes the unused functions are behind an import which can be commented out, and sometimes they aren't which would then entail hunting down a chain of functions to comment out. Once you comment a line out, you have to comment out a function, which would then make
<gamester>
another function not called and you'd have to comment it out, and so on.
<Tetralux>
Yeah - that'd be fatal for me.
<Tetralux>
"Dead code elim except for exported functions" + 1
<Tetralux>
+1*
kristoff_it has joined #zig
<dimenus>
does the std lib have any kind of generic lexer? eg expectChar (or rune)..
<mikdusan>
dimenus: std.mem has tokenize() and separate() for some basic stuff
<Tetralux>
+1*
<Tetralux>
Whoops, wrong window lol
kristoff_it has quit [Ping timeout: 248 seconds]
huuskes has left #zig ["Konversation terminated!"]
Ichorio has quit [Ping timeout: 264 seconds]
dimenus has quit [Ping timeout: 272 seconds]
<emekankurumeh[m]>
andrewrk: so without `try` in `defer` blocks, an async function deallocating its own frame would look like `allocator.destroy(@frame()) catch unreachable`?
dimenus has joined #zig
laaron has quit [Remote host closed the connection]
laaron- has joined #zig
<mikdusan>
allocator.destroy() doesn't return an error
<emekankurumeh[m]>
ohhh, that makes a lot more sense
laaron has joined #zig
laaron- has quit [Ping timeout: 260 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #zig
ltriant has joined #zig
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 245 seconds]
porky11 has quit [Quit: Leaving]
ltriant has quit [Ping timeout: 248 seconds]
ltriant has joined #zig
<fengb>
I can't alias a builtin function? `const smallNoInlineCall = @noInlineCall;`
ky0ko has joined #zig
<scientes>
fengb, i didn't even know we could alias regular functions