ChanServ changed the topic of #zig to: zig programming language | https://ziglang.org | be excellent to each other | channel logs: https://irclog.whitequark.org/zig/
<daurnimator> tav: doc parsing+rendering is on the roadmap
<andrewrk> tav, not yet. see: https://github.com/ziglang/zig/issues/21
<daurnimator> tav: but yes, there is a zig parser in zig
<andrewrk> for the second question, see the std.zig module
<tav> thanks
<daurnimator> andrewrk: er, looking at that paste; which is the location where the return-as-cancellation point is required?
<andrewrk> daurnimator, have a look at the mmap/munmap in strace with different values of simulate_fail_* constants
<andrewrk> you'll notice that no resources leak because cancel causes the errdefers in scope to run before completing the return statement
<fengb> andrewrk: what if non async functions are noncancellable by default?
<andrewrk> I'm not satisfied with that solution
<daurnimator> andrewrk: I'm still lost/confused
<daurnimator> I get output https://clbin.com/puc8S
<daurnimator> And I am confused by the fact that `cancel download_frame` causes "fetchUrl returning" to happen
<daurnimator> I guess that's done so that you can e.g. call some cancellation API
<daurnimator> But I still don't then follow about why/how `return` is a cancellation point
<andrewrk> daurnimator, `cancel download_frame` does nothing except for suspend until download_frame finishes
<andrewrk> when fetchUrl gets to the return statement, it will run the errdefer as well as defers because it has been cancelled
<andrewrk> you can think of `cancel` as being the same thing as `await` except you are choosing not to accept the return value
<daurnimator> andrewrk: why not have it just immediately after the `suspend`?
<daurnimator> *just immediately stop (after running any deferred handlers)
<andrewrk> you're proposing to make every suspend point a cancellation point?
<daurnimator> uh. yes?
<andrewrk> one of the improvements I made from master branch is to change it so that suspend is no longer a cancellation point. it greatly simplified the semantics, ease of understanding, and better aligns with async-functions-are-just-functions
<andrewrk> the performance is better as well
<tav> newbie question: the documentation implies that there is support for var_args, but there's no example given — any pointers?
<andrewrk> tav, avoid var args for now, it's about to get removed in favor of tuples or something like that. you can look at std.fmt.format for an example of var args
<daurnimator> tav: `fn foo(blah: u32, args: ...) void {` now use args like an array, but of mixed types
<tav> "variadic" tuples?
<andrewrk> there are plenty of things that would benefit from being reconsidered, but I'm confident in how `suspend` and `resume` work in this branch being correct.
<daurnimator> FWIW we still need to be able to support varags for C interop: but that vararg handling would be different too.
<daurnimator> andrewrk: I don't expect a directive called "cancel" to make something "keep going"....
<andrewrk> it doesn't make it keep going. it will keep going all by itself.
<andrewrk> cancel sets a flag and then suspends until it finishes
<andrewrk> "I'm not going to accept your return value, so stop as soon as you can. Wake me up when you're done."
<daurnimator> oh right... and cancel can happen at *any* time? even in the middle of execution?
<daurnimator> (e.g. if you cancel from another thread?)
<andrewrk> yes, it's atomic. the least significant bit of the awaiter frame pointer is used as the cancel bit
<andrewrk> @cancelRequested() is essentially an @atomicLoad followed by @truncate(u1)
<andrewrk> suspend doesn't have any reason to check the awaiter pointer or cancel bit. it makes sense that it would be a separate, explicit request
<daurnimator> okay that makes sense
<andrewrk> it also means that suspending inside defer and errdefer is now allowed (was not allowed in master branch)
<andrewrk> note that `async fn Drop` is a much-desired feature that Rust does not (and cannot without significant design changes) have
<daurnimator> so going further: the "cancellation point" in 'return' is to run any defers or errdefers?
<andrewrk> equivalent in zig being the ability to suspend inside defers
<andrewrk> yes that's it, it's just that `return` might run your errdefers even if you didn't return an error
<daurnimator> that's..... odd
<andrewrk> that's the one thing that affects normal functions: we are introducing the ability to do a function call, but then say "never mind, don't give me the result."
THFKA4 has joined #zig
<daurnimator> erk, I can't think of many ways around this that don't essentially boil down to "introduce RAII"
<andrewrk> daurnimator, here's the other way to do this: https://clbin.com/TB4OO
<andrewrk> with this way of writing code, we could get rid of `cancel`. but then returning an error is not allowed in between async/await calls
marijnfs has joined #zig
<andrewrk> (this does compile & run in the branch btw; it's strictly simpler)
<andrewrk> IMO having an area of code where you can't use `try` is a pretty huge downside
<Tetralux> its also not obvious why
<scientes> why can't you just _ = await, and would be cancel?
marijnfs__ has quit [Ping timeout: 248 seconds]
kristoff_it has joined #zig
<scientes> nvm
kristoff_it has quit [Ping timeout: 248 seconds]
<daurnimator> andrewrk: if every .init() is meant to be paired with a .deinit().... perhaps we should annotate that on return types?
<mikdusan> is this one way to bail early from inside async fn? `suspend; if (@cancelRequested()) return;`
<daurnimator> like.... `fn init() cleanup(.deinit) @This() { ..... `
<daurnimator> mikdusan: yes.
<andrewrk> mikdusan, yes, that's the idea.
<andrewrk> there are a couple of syntaxes I'm considering
<daurnimator> mikdusan: though you obviously need to return *something* that matches the signature of your function
<andrewrk> well that's the thing though. if you're returning due to a cancel, you actually don't have to return anything. the caller is not interested in the return value
<andrewrk> you also don't want to necessarily return an error because it will add an incorrect error set item to your signature
<andrewrk> which is why I'm considering this `cancelpoint` block: https://github.com/ziglang/zig/issues/2377#issuecomment-517892291
<andrewrk> so you'd start a cancelpoint {} block, and have the option to break out of it if you want to, if you change your mind. but if you let it get to the end then your fn returns (no value), and runs defers/errdefers at that point
<mikdusan> what does block syntax for suspend do? `suspend { ... }`
<andrewrk> the suspend starts at the beginning, before entry into the block. so if `resume` happens on your @frame() it will begin executing after the suspend point - potentially racing with the code inside the suspend block
<andrewrk> so for example, if a function wants to put itself into an epoll set, it's going to call epoll_add(@frame()) or something like that, right? but as soon as that syscall starts, it could get resumed in another thread. so you actually need to be suspended before making the syscall
<mikdusan> (heh i was going to suggest make the block a cancelpoint)
<daurnimator> andrewrk: `canceldefer`?
<daurnimator> I guess it's not really deferred
<fengb> `cancel cancelpoint` :P
<daurnimator> I like that idea; just not the token 'cancelpoint'. `ifcancelled` is ugly....
<daurnimator> (and has the spelling issues mentioned on stream)
<daurnimator> andrewrk: I guess re-open 782?
Tetralux73 has joined #zig
laaron has quit [Remote host closed the connection]
ltriant has quit [Ping timeout: 246 seconds]
laaron has joined #zig
ltriant has joined #zig
ltriant has quit [Ping timeout: 248 seconds]
<tav> is there some way to annotate struct fields with tags by any chance?
<daurnimator> tav: 'tags'? and why?
<tav> so, in languages like Go, one can annotate a struct field with tags, e.g. `json:"some_name,omitempty" postgres:"varchar(66);primary_key;not null"`, etc.
<daurnimator> tav: okay so those sort of tags. yeah see e.g. https://github.com/ziglang/zig/issues/1099#issuecomment-514083951
<tav> sorry, I don't understand what the implications are of using `@field(ptr, f.name)` as an lvalue — does it set the value of the field when used on the lhs?
<tav> and is the general idea in the comment that you could use a secondary data structure to hold/lookup the tag info?
<daurnimator> yeah. or other decoding/encoding perculiarities.
<tav> nice. it's certainly richer/more flexible — albeit at the cost of having to duplicate field names and keep them in sync
<tav> what does it mean to assign to `@field(ptr, f.name)` btw?
<daurnimator> should be a compiler error if something is mismatched
<daurnimator> tav: essentially `@field(ptr, "foo")` is the same as writing `ptr.foo`. but it allows you compute "foo" at comptime.
<tav> nice
<andrewrk> @field gives you direct access to `a.b` syntax, except `b` is a comptime string
<tav> alright, no need for struct tags then :)
ltriant has joined #zig
<tav> are there any existing libraries for formats like json/protobuf/etc. by any chance?
<andrewrk> std.json exists
<daurnimator> tav: there's some json basics in the standard library
<tav> thx
<tav> if one wants to emit different asm based on compiler target, then is the idea to do that using comptime?
<daurnimator> tav: yep.
<daurnimator> tav: have a look at std/valgrind.zig
<andrewrk> it looks like there are 2 ways in which https://github.com/ziglang/zig/issues/1512 is blocking async/await branch
<andrewrk> 1. lazy values is needed to resolve some false positive circular dependency loops regarding frames (such as ability for an async function to destroy its own frame in a defer)
<andrewrk> 2. release mode builds are failing tests right now because optimizations do vectorizations on sret pointers which introduces a 16 byte alignment requirement, and alignments of variables are currently not respected in async functions, so this functionality is needed to address the problem
<andrewrk> so that's the next thing I'm going to work on. I think it'll be best to do in master branch and then deal with the merge conflicts
<daurnimator> sounds good
<andrewrk> good night
* daurnimator is noticing lots of "ghost" user(s) in zig issues.... did a regular or two delete their github accounts?
<mikdusan> ghost is popular. he has 1.9k followers.
<daurnimator> idea while reading over #2201 ..... what if slices were 'duck typed' where you could pass anything with `.ptr` and `.len` members?
<daurnimator> could also help with #2255....
<tav> g'nite andrewrk
<tav> I'm off too — and thanks everyone for a very helpful first day in the community
<mikdusan> #2255 syntax would restrict field names to never be { .ptr, .len }
<daurnimator> mikdusan: howso?
<daurnimator> oh right
<daurnimator> interesting
<daurnimator> I hadn't thought about it from that angle
rjtobin has quit [Ping timeout: 245 seconds]
LargeEpsilon has joined #zig
LargeEpsilon has quit [Ping timeout: 245 seconds]
ltriant has quit [Ping timeout: 245 seconds]
ltriant has joined #zig
LargeEpsilon has joined #zig
zangent has quit [Ping timeout: 260 seconds]
ltriant has quit [Quit: leaving]
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #zig
laaron has quit [Remote host closed the connection]
laaron has joined #zig
porky11 has joined #zig
<dftxbs3e> hi, how big can the zig std make a program for say, basic network I/O?
<gonz_> Network stuff is currently a bit in flux since it'll be impacted quite heavily by the async/await rewrite.
kristoff_it has joined #zig
kristoff_it has quit [Remote host closed the connection]
LargeEpsilon has quit [Quit: Leaving]
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #zig
tav has quit [Remote host closed the connection]
_whitelogger has joined #zig
hspak has quit [Ping timeout: 272 seconds]
hspak has joined #zig
avoidr has quit [Quit: leaving]
LargeEpsilon has joined #zig
tav has joined #zig
LargeEpsilon has quit [Ping timeout: 248 seconds]
NI33_ has joined #zig
mschwaig has joined #zig
<mschwaig> andrewrk, if you are looking into struct alignment you might want to take a look at https://github.com/ziglang/zig/pull/3003#issuecomment-520141020 which documents where I hit my head with that when trying to increase the alignment of u128
mschwaig has quit [Ping timeout: 260 seconds]
LargeEpsilon has joined #zig
_whitelogger has joined #zig
laaron has quit [Remote host closed the connection]
jzelinskie has quit [Remote host closed the connection]
dch has quit [Remote host closed the connection]
jzelinskie has joined #zig
dch has joined #zig
laaron has joined #zig
LargeEpsilon has quit [Ping timeout: 245 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #zig
vegax87 has joined #zig
<bheads> andrewk, what about cancledefer;
avoidr has joined #zig
LargeEpsilon has joined #zig
<fengb> bheads: I like having cancel be an error state. It feels a little weird but I can't think of many cases where I don't want to run errdefers on cancel
<mq32> fengb: there was some discussion about cancel the last days, could you do a tl;dr? I'm interested in this topic, but i don't have the full chat log
jmiven has quit [Quit: reboot]
<fengb> It's primarily discussing semantics from the stream
jmiven has joined #zig
<mq32> ah
<fengb> Any async function can be cancelled
<fengb> And cancellation triggers errdefers
<mq32> yeah i have some question on that topic too, but they are kinda special^^
<mq32> the current cancel semantics is that the function runs till the end, but then returns an error instead of a value, right?
<fengb> Current meaning current rewritten behavior?
<mq32> yes
<fengb> There's a discussion of what it means to error out. Returning an error doesn't make sense since there's no "return point". Cancel implies "go away, I don't care about your response"
<fengb> There's also an explicit cancellation point. If you add a special `error.Cancelled`, you have an extra error value that's never supposed to be a part of the API
<mq32> yeah
<mq32> my use case would be "endless coroutines"
<mq32> like
<mq32> fn foo() { while(1) { /* do stuff */ await nextFrame(); } }
<mq32> which is a convenient way to express game object logic
<fengb> The tail end of this discussion is pretty good
<fengb> mq32: that's not possible based on current semantics as async functions can only be awaited once. We'll need generators for multiple awaits
<fengb> andrewrk just mentioned that he's open to generators and async generators on stream so that might be a thing
<mq32> hmm
<mq32> is multiple resumes a thing in the new system?
<mq32> andrew didn't show that in the stream, but it may be required by some functions
<fengb> Yes, but there's only 1 return value
<fengb> Once returned, the async function is "dead" and can't be restored
dimenus has joined #zig
<mq32> yeah that's totally okay for my use case
<dimenus> andrewrk: you should do a run of zig tshirts
<fengb> I'd totally buy one
<mq32> +1
<fengb> What's our motto?
<fengb> tagline
<fengb> Thing
<mq32> Move 'zig!
<fengb> Also the past 2 streams have been very helpful for the new semantics
<fengb> "Synchronous or asynchronous is something up to the caller to the decide – not to the function itself."
<fengb> Part of the thread about await in rust
<fengb> I kinda want to respond heh
<mq32> oh there was a second stream!
<mq32> have to watch it later :)
<fengb> mq32: oh your example, you'd need something like await async nextFrame(), which is semantically identical as nextFrame()
laaron has quit [Remote host closed the connection]
<fengb> I believe in an async context, any function call that's detected as async gets automatically translated as async await under the hood
<mq32> ah yeah
<mq32> i would build nextFrame() so that it returns a @frame()
<mq32> (i just like that syntax, beat me!)
<fengb> Ah
<mq32> nextFrame() would "schedule stuff and pauses the coroutine until the next frame was rendered"
laaron has joined #zig
<fengb> I feel like that's a good candidate for generators: for(generateFrames()) { ]
<mq32> hm
<mq32> my example is much simplified
<fengb> But... that's not a real proposal yet so don't quote me :P
<mq32> you could have arbitrary complex code in an entity logic code
<mq32> even loops where you suspend inbetween
Tetralux73 has quit [Remote host closed the connection]
<mq32> like "count this value from 0 to 360 over the count of 16 frames"
<fengb> I suppose having an implicit await inside the for loop looks weird
<fengb> Yeah I think your solution is more explicit and probably better :P
<mq32> thank gamestudio a8 for this
<mq32> they have a function "wait(n)" where n is the number of frames to wait
<mq32> pretty cool concept, but their scheduler is so broken that it hurts
<fengb> Good news! Zig has no scheduler >_>
<mq32> yeah, so i have control over what my code does <3
<fengb> I've never written low level event-loop stuff before, so I'm curious how suspend/resume will work in practice
<fengb> I'm a Javascript junkie. await is the lowest I understand
<mq32> yeah i'm also quite interested in the event-loop stuff
halosghost has joined #zig
<mq32> but i'm no JS dude :D
<mq32> i have to compile a zig version myself
<mq32> want to get zig build for cortex-m3 processors and other lowlevel hardware (AVR)
<fengb> Hmm, so based on current semantics, if there's no event loop, the caller of the async function will just terminate right?
<fengb> Since it's not waiting for anything
<mq32> hmm, good question
<fengb> I think andrewrk showed that on stream how there's a resource leak
<fengb> I wonder if we should detect that, especially if the frame is on the stack
drazan has quit [Remote host closed the connection]
<lluchs> How do I get a pointer [*]u8 from a slice []u8?
<fengb> slice.ptr
<lluchs> thanks, missed that part in the documentation somehow
drazan has joined #zig
bheads_ has joined #zig
bheads has quit [Ping timeout: 244 seconds]
bheads_ is now known as bheads
<fengb> We're all learners here :)
<andrewrk> fengb, without an event loop, anything waiting on I/O will hit a `suspend` and then there will be no event loop to call `resume`
<fengb> Will there be a way to detect that?
<andrewrk> or: if the code detects there is no event loop (which yes is possible)
<andrewrk> then the code could simply do blocking I/O and then your application seamlessly is now blocking instead of event-based
<huuskes> is the new function definition syntax still planned for next milestone?
<andrewrk> huuskes, much of what is tagged 0.5.0 will have to get postponed. after merging async/await I'll be prioritizing bug fixes until the release
<andrewrk> fengb, that's the big idea here: (1) don't call suspend if you don't have a plan to get resumed, and (2) allow the presence of suspend to decide whether something is async or not
autodidaddict has joined #zig
<autodidaddict> working on some stuff where I'm trying to import from protobuf generated C... I'm curious how Zig handles importing a #define ?
<autodidaddict> so, the define looks like this:
<autodidaddict> #define CORE__COMMAND__INIT \ { PROTOBUF_C_MESSAGE_INIT (&core__command__descriptor) \ , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, NULL }
<autodidaddict> and my import is named `c` , but the compiler tells me that ".cimport:8:11 has no member called CORE__COMMAND__INIT
<dimenus> autodidaddict: can you run the header through translate-c separately?
<dimenus> what does it generate?
<autodidaddict> I don't know what that is or how to do it ;)
<dimenus> zig translate.c my_impl.c (which includes the header)
<dimenus> *translate-c
<dimenus> or just translate-c the header directly
<autodidaddict> I don't have an included header. I have a `.pb-c,h` and a `.pb-c.c` file
<fengb> andrewrk: I'm more concerned that the caller failed to initiate the loop correctly in main. Maybe it'll just need examples
<autodidaddict> and I'm using `@cInclude` on the .h file
<dimenus> that IS an included header then
<dimenus> you can generate zig symbols for that independently of your main application
<dimenus> by running zig translate-c pb.h or whatever the real name is
<autodidaddict> dimenus: ok I was able to get a list of "pub const"s
<dimenus> now search that for your symbol
<autodidaddict> the define isn't there
<dimenus> fengb: it doesn't look like his example above is trying to call anything
<dimenus> autodidaddict: you can also pass '--verbose-cimport' to see if the c translator ran into any issues
<fengb> That looks like a complex macro that's probably hard to translate properly. I think it's doing a block but I'm not sure what the comma arguments are doing
<fengb> ... oh is it a block of struct init?
<autodidaddict> the core of what I'm trying to do is this: https://github.com/protobuf-c/protobuf-c/wiki/Examples
<autodidaddict> I want to instantiate the protobuf C object, populate fields, and encode it. This sample uses the "__INIT" macro that gets generated in the header files
<dimenus> autodidaddict: zig has default initialization for structs
<fengb> So... the meat of this is, C macros are just text so sometimes it's really hard to glean semantic info
<fengb> I'm not sure if this will be possible to translate correctly
<autodidaddict> so I can do `var cmd: c.Core__Comand;` instead of `var cmd: c.Core__Command = c.CORE__COMMAND__INIT` ?
<fengb> This isn't translating at all atm. There's an issue to append a comment into the generated file instead of silently ignoring it
<dimenus> autodidaddict: I would recommend that you 'zig translate-c' your header code ahead of time and include it in your zig file
<dimenus> that way you can setup default init yourself
<dimenus> eg like what I did in the vulkan header example above
<autodidaddict> so don't use [at]cImport ?
<dimenus> nope
<dimenus> i'm not saying you can't, but it's more useful for platform headers or libc headers
<autodidaddict> this is generated code, so I'd have to regenerate and then re-translate every time I modify the proto ?
<mq32> autodidaddict: or get protobuf to emit zig code ;)
<mq32> i was thinking about porting the OpenGL headers to zig, but it seems better to generate them from the registry directly
<autodidaddict> I'm not really worried about the most efficient thing... I just want to be able to encode and decode a protobuf inside a Zig function.
<mq32> dimenus, you're doing vulkan with zig?
<dimenus> autodidaddict: i'm not familiar enough with protobuf to comment on that part
<dimenus> but you could run the generation step in your build.zig file
<autodidaddict> protobuf I'm familiar with... but not in C. The C examples don't tell me when/where I need to allocate in Zig, etc
<dimenus> mq32: yep, i'm first building the Breakout game from learnopengl.com into zig -> https://learnopengl.com/In-Practice/2D-Game/Breakout
<dimenus> *in zig/vulkan
<dimenus> then I'm probably going to write some kind of gpu accelerated gdb frontend
<dimenus> I think
<autodidaddict> I also don't have a build.zig file. I can't figure out how to get that to work with the protobuf generated code, so I'm passing `--object` to include `libprotobuf-c.a`
<dimenus> Vulkan hasn't been near as bad as expected so far
<fengb> Short term solution is to separately maintain the empty struct variables in a different file. You might be able to define this in the C file: struct CORE__COMMAND__INIT = { PROTOBUF_C_MESSAGE_INIT (&core__command__descriptor) , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, NULL };
<fengb> And stick it in a C header
<fengb> Actually might be easier to maintain in zig
<mq32> dimenus: neat. i'm thinking about a two-level OpenGL library for zig. first level would be the pure binding stuff done right (so allowing multiple contexts for different threads and so on) as well as the second layer which does semantic binding of OpenGL objects (so buffer.bind() instead of glBindBuffer(buffer))
<autodidaddict> I don't have any idea how to "maintain in zig"
laaron has quit [Remote host closed the connection]
<fengb> Sorry, it's getting messy. I've not really maintained messing compatibility with C before
laaron has joined #zig
<dimenus> autodidaddict: since Zig can't translate some of those macros, I'm not sure this is going to be a worthwile endeavor for you
<dimenus> we'd be better off having a generator that itself outputs zig
<fengb> Yeah this is one of those complex macros that probably won't translate too well
<autodidaddict> I'd love that, but what I really need is the ability to encode and decode the structs using the protobuf wire format ;)
<autodidaddict> and so I assumed that the best way to do that would be to import the C generated structs (the structs are there just fine, just no helper macros) and use libprotobuf-c to encode and decode
<autodidaddict> so in zig, how does one create an instance of a C struct?
<dimenus> same as a zig struct
<dimenus> either var foo: Type = undefined;
<dimenus> or var foo = TypeLiteral { .field1 = "foo" .field2 = 42 };'
<dimenus> etc
<dimenus> autodidaddict: have you seen the zig documentation? https://ziglang.org/documentation/master/
<autodidaddict> blick, it looks like the helper macros are what deal with a `ProtobufCMessage` which is embedded in each generated struct
<autodidaddict> so it's not like I can just manually set values
<autodidaddict> yeah, I've seen that document. It doesn't specifically say (at least I couldn't find) that C structs are initialized the same way Zig ones are
<gonz_> It seems to me like you have to figure out what the macro actually does and have a zig function that does those things.
<dimenus> autodidaddict: only basic types have separate C types
<andrewrk> autodidaddict, unfortunately it seems the API of the library you are trying to read is not in C, it's actually in a different language, the C preprocessor
<andrewrk> the C preprocessor is a much worse language than C, I don't know why people choose to use it for their APIs
<gonz_> I can't think of many things I want to deal with less than automatically generated macros :D
<gonz_> It seems to me that once you've gone ahead and relied on code generation, why wouldn't you just generate procedures?
<autodidaddict> "why wouldn't you just generate procedures?" -> because I don't own the code generator
<autodidaddict> the code generator is protoc
<scientes> Some buy wrote a prime number generator in the preprocessor, that doesn't even use preprocessor arithmatic
<scientes> but only define/undefine
<gonz_> Yes, I know you're not responsible for protobuf, I'm just complaining out loud.
<autodidaddict> hah, it looks like the macro initializes it to null
<fengb> Because macros are "faster"
<gonz_> It could be different for different types, maybe
<fengb> ™
<scientes> fengb, ^ that program written in the preprocessor includes itsself 6.8 million times
<fengb> lolwat
<scientes> just to do a Sieve of Erostates up to 1024
<fengb> I meant the protobuf example, where it's guaranteed to be an inline struct init, despite the weirdo syntax, whereas a function call could add precious cycles
<scientes> you can even #define O #ifdef http://www.ioccc.org/2004/vik2.c
<samtebbs> fengb: LLVM has instruction schedulers so Zig does by proxy
<scientes> they are important
<scientes> I was writing some code and removing volatile from my inline assembly sped it up 2X
LargeEpsilon has quit [Ping timeout: 268 seconds]
<andrewrk> samtebbs, the conversation about scheduling was in context of event-based I/O, e.g. when async functions get resumed
<andrewrk> the `suspend` keyword essentially means: "I'm suspending now. I've scheduled myself for when to get resumed."
Akuli has joined #zig
<autodidaddict> almost got a compilation to pass ;) When I try and set the c string literals, e.g. .foo = c"foo" , I get a "cast discards const qualifier" error
<autodidaddict> I guess I need to convert that into `char *`
<andrewrk> string literals do not point to mutable data
<autodidaddict> so my C struct types are `char *` . ... what's the right way to set those values from Zig?
<andrewrk> that should be documented by the API you're using
<andrewrk> who owns the memory
<autodidaddict> setting a C `char *` isn't an API. This is a struct, and I own it.
<andrewrk> if you made the struct then why are you using c strings?
<autodidaddict> It's a C struct
<autodidaddict> generated by protoc
<andrewrk> the protoc API should describe who owns the memory of that mutable char * field
<autodidaddict> the compiler wants [*c]u8
<autodidaddict> no, the protoc API doesn't describe any such thing. protoc generates the structs and expects me to manage them
<andrewrk> there's your answer: you own the memory
<autodidaddict> ^^ I just said I own it
<andrewrk> but this raises the question: why must it be mutable?
<autodidaddict> because protoc generated a `char *` , all the protoc-generated structs are assumed to be mutable in place
<andrewrk> assumed by whom?
<andrewrk> sounds like you don't fully own it
<autodidaddict> the protocol buffers standards
<autodidaddict> nearly every generator for protoc builds mutable structs / types
<autodidaddict> All I need to know is how to make a `[*c]u8` from a zig literal :(
<andrewrk> in this case it is your job to manage the memory of your field, and you're not going to be able to use string literals
<andrewrk> you would hit this error in C code as well
<autodidaddict> I fully understand that I can't use a literal in a mutable field. But most languages allow me some way to construct a mutable pointer from a string literal
<autodidaddict> Rust, `from_str` etc
<autodidaddict> I'm looking at the docs and don't see a way to do that for the `[*c]u8` type
<andrewrk> I'm sorry I assumed that you knew how to code in C
<andrewrk> you need to allocate memory and copy your string literal
<autodidaddict> maybe I am just not phrasing my question right. I'm trying to populate this value _in zig_
<autodidaddict> the code was imported via cImport
<autodidaddict> so the C code is a char *
<autodidaddict> but I want to use Zig to create the mutable pointer
<autodidaddict> I've read that section. Is your point that a) I'm too dumb for this and b) manually construct a Zig u8 pointer, fill it with a string literal, and it should auto-cast to a [*c]u8 ?
<andrewrk> I'm certainly not saying (a). Did you try what I just suggested above?
<autodidaddict> I'm trying to, but it's not compiling my intent (and no intellisense makes it difficult). I think my exposure to Rust is preventing me from understanding what's going on
<gonz_> `std.fmt.allocPrint` takes an allocator and a format string (doesn't need to have any actual interpolations in it) and allocates a string for you based on what you passed in
<gonz_> That would be one alternative
<autodidaddict> where is `std.fmt.allocPrint` documented?
<samtebbs> andrewrk, fengb: Ah sorry, I struggled to follow the whole conversation
<gonz_> In `std/fmt.zig` :D
<autodidaddict> I guess I would never have thought to look in fmt for a string allocator
<andrewrk> autodidaddict, I agree with gonz_ about generating zig code for protobuf. (I also don't endorse protobuf, I think it's poorly designed) you're trying to bend 2 APIs over backwards and learn zig at the same time
<gonz_> If you want to allocate your string separately you can also just use `std.mem.copy` to copy the contents of the literal to the allocated memory
<andrewrk> right now you are chasing a local maximum
LargeEpsilon has joined #zig
<andrewrk> I suggest aiming for the global maximum instead.
<autodidaddict> andrewk: since there's no protoc plugin for Zig, C was the only other way to explore decoding and encoding
<gonz_> autodidaddict: Coming from Rust, one thing to keep in mind is that allocating things explicitly is how you're going to keep them around. There's no magic involving things moving out of scope and analysis done to determine whether or not it should be freed or not, etc.
karrick has joined #zig
<autodidaddict> Rust also goes out of its way to hide the explicit allocations
<autodidaddict> if you use a `Vec::new()` , you're getting a pointer to a pre-allocated vector with some unknown (usually 10) capacity
<autodidaddict> but `let mut s = std::str::from_str("hello")` would then let me use that string as a mutable pointer
<andrewrk> I'm guessing in rust you also weren't using C FFI bindings, but using a rust implementation of protobuf
<autodidaddict> there are 3 different protobuf crates I've used, 1 of them uses a C++ library underneath, the other 2 are native Rust
<andrewrk> what you're trying to do is possible, but you should probably get some practice with manual memory management on a simpler project
karrick has quit [Remote host closed the connection]
<gonz_> Zig (from my perspective) aims to make allocation as explicit and obvious as possible, whereas Rust wants something that seems like a GCd language when it's not.
<autodidaddict> but my point above about the allocations is what I'm getting at... Rust is a full level of abstraction higher when it comes to allocation
<andrewrk> yep
<gonz_> Exactly.
<autodidaddict> gonz: Rust's language hiding of allocations follows the same pattern as most ARC languages (e.g. Objective-C with ARC turned on, Swift, etc).
<gonz_> This is mostly a question of values
<gonz_> Direct control vs. initial ease of use
<autodidaddict> I'm not sure what's causing the struggle for me. Switching between Rust and Go and Elixir, I usually have very little penalty for context dropping. But switching from Rust to trying to interpret Zig... I don't know, there's a lot of friction there I can't explain yet
<gonz_> Controlling which allocator to use for a given thing is much easier if you have explicit memory allocation and a good interface to it, like the `std.mem.Allocator` we have.
<autodidaddict> the use of explicit, loosely-coupled memory allocators is an inspired design choice, and I love it.
<andrewrk> autodidaddict, it sounds like you've never done manual resource management before. that's a new concept to learn. the main thing to remember is that the language does nothing: it's up to you to decide when something gets allocated and when something gets freed
<autodidaddict> I've done manual resource management in other languages (C)
<autodidaddict> I just keep expecting Zig to do things it's not doing
<autodidaddict> like I said, I'm not sure why the context switch is harder than with other languages
<andrewrk> zig will never allocate memory on your behalf
<andrewrk> you'll have to use the std lib for that
<autodidaddict> Maybe I just need more coffee
<gonz_> Is it possible that all this time with languages that don't emphasize this has made you a bit rusty? Before I got going with Zig (not that long ago) I had been away from C++ for something like 7 years and I can tell you I was absolutely not "with it" anymore.
<autodidaddict> I haven't used C in 20 years
<autodidaddict> I'm older than dirt.
<autodidaddict> no, I take that back.. I used a variant of C (wiring, e.g. Arduino) last year
<autodidaddict> but that was different also, because that program had _no_ allocations in it
<gonz_> Right. I think it's very possible that things like this just need some practice when you come back.
<autodidaddict> Or I just admit defeat. I iz teh dumb
<gonz_> Well, the question is mostly one of other motivation, no? If there's something that catches your eye about Zig you'll just work on it and get used to it. For me it's the relentless simplicity and obviousness of most things.
<gonz_> But I'll add that I'm here because I overdosed on abstractions and I feel like we're losing touch with how to write lower level things as an industry in general.
<autodidaddict> I got into FP because I was feeling overdosed on abstractions
<autodidaddict> ... then I got into Rust because I overdosed on FP :P
laaron has quit [Remote host closed the connection]
laaron has joined #zig
kristoff_it has joined #zig
<autodidaddict> okay, so last question. I'm allocating the memory (var buf = a.alloc....), I'm filling it (std.mem.copy....) , but the struct still requires a `char *` and I'm getting a type mismatch between `[*c]u8` and `*[]u8` .. which foolish noobsauce thing have I done?
<autodidaddict> sorry the error is ` error: expected type '[*c]u8', found '[]u8'`
<gonz_> Have you tried `&string_variable`?
<autodidaddict> yes, that produces a `*[]u8`
<lunamn> slice.ptr?
<gonz_> Yeah, exactly
<gonz_> `string.ptr`
<gonz_> Should work
<autodidaddict> that works
<autodidaddict> .ptr only shows up on 3 lines of the docs
<autodidaddict> is that field available on things other than slices?
<lunamn> don't think so
<autodidaddict> ok
<gonz_> Not in the standard library, I think, but I guess it depends entirely on what's going on. It's mostly that slices have the pointer and the length, so you effectively have to downgrade to only having the pointer for `[*]`
kristoff_it has quit [Remote host closed the connection]
kristoff_it has joined #zig
<autodidaddict> how do you refer to a struct field called "error" ? Zig won't let me use `.error` because it's reserved
<Akuli> maybe call it 'eror' or something? i use lizt, indeks, klass etc in my python code
<halosghost> yikes
kristoff_it has quit [Ping timeout: 258 seconds]
<halosghost> .err seems like a lot more pleasant than adding a misspelling
<autodidaddict> the code I have (in C) is generated, I can't readily change the field name
<autodidaddict> I'm not sure why structs can't have a field named `error`
<fengb> You can use @“error” for access
<autodidaddict> I get not being able to create a new type called error, because it conflicts with the keyword
<fengb> error is a keyword
<autodidaddict> ok cool
m6w6 has quit [Quit: https://m6w6.name]
m6w6 has joined #zig
LargeEpsilon has quit [Ping timeout: 245 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #zig
<autodidaddict> is there a static link alternative to `--library` when I compile with a C lib?
andersfr has joined #zig
andersfr has quit [Client Quit]
<dimenus> huh?
<dimenus> zig links statically by default
Jenz has joined #zig
<autodidaddict> not when you target wasm
<autodidaddict> when I pass `--library (path to C library` while targeting wasm, all the functions that used to be satisfied by that library appear as unsatisfied wasm imports in the output module
<Jenz> It'd be amazing if someone did an exercism.io course on zig
<gonz_> Jenz: Being that Zig i
<gonz_> Zig is in very early days, it's likely that you will have to be that someone
<Jenz> Well, unfortunately I can barely write a hello world program DX
<Jenz> Which is why I want a zig course XD
<Jenz> Anyways, I'm sure zig will do well
<fengb> autodidaddict: can you show the compiler output? --verbose-cc --verbose-link
<dftxbs3e> hi, what can zig do about kernel failing to physically commit a page and returning SIGBUS?
<dftxbs3e> on modern Linux, mmap of 140TB can work, but it's when you try to actually access memory that it crashes the program
<autodidaddict> fengb: zig build-lib src/main.zig --object /usr/local/lib/libprotobuf-c.a -isystem /usr/local/include --c-source proto/core.pb-c.c -target wasm32-freestanding-musl --library c --verbose-cc --verbose-linklld -error-limit=0 --no-entry --export-all --allow-undefined -o ./main.wasm /usr/local/lib/libprotobuf-c.a zig-cache/o/Vn04E770QL4js46KbNQkIe--kbww
<autodidaddict> jaFzhwgtvvqd5jLqQwen676GcoolXSLG2jeW/core.pb-c.o ./main.o /Users/kevin/Library/Application Support/zig/stage1/o/zeBzLFjDcpITw-oQ6twU-wsFwCEA7YnNB5zeDBTWDDWyLT8fOGUlRLxoVEXeUDSK/c.o /Users/kevin/Library/Application Support/zig/stage1/o/m4ErfeNqa8WhxW_CPG61Ra4qEhSAm-hqRUyAQ6E47TJh3_Ij--x_B8i1udX8Z_T3/compiler_rt.o
<fengb> I think there are problems detecting what’s needed for C vs WASM output so a workaround might be exporting everything
<gonz_> Jenz: https://miro.medium.com/max/700/0*AP8yBkfxP_qKDccU.jpg <- I don't think Zig is currently past the early adopters stage here and the needs of those people are generally different than the needs of the people who come in later. The work of the early adopters likely informs the materials available for the later stages.
<autodidaddict> not sure how that would help... the functions that are "missing" from the wasm module are the functions that are exported from `libprotobuf-c.a`
<fengb> Huh... it’s exporting all but not linking it in :/
<autodidaddict> as an example.. when I try and load the .wasm file compiled here, it complains that it's missing an import from the "env" (default wasm) namespace called "protobuf_c_message_pack" , which is a function that my code invokes that is in `libprotobuf-c`
<autodidaddict> the code from the library is not statically converted into wasm
<autodidaddict> it even thinks "__assert_fail" is a wasm import in the "env" namespace
<autodidaddict> wow, it even flagged "main" as a missing import
<fengb> Try --static? I’m not at my computer and I’m not that familiar with linking existing libraries
<autodidaddict> hmm. --static doesn't appear in the help
kristoff_it has joined #zig
donpdonp has joined #zig
<donpdonp> im missing something here. struct { tags: []string } is a slice of strings yes? (const string = []const u8;)
kristoff_it has quit [Ping timeout: 248 seconds]
<donpdonp> myStruct = struct {.tags = []string{}} => error: expected array type or [_], found slice
<donpdonp> whoops should say myStruct{..}
<fengb> donpdonp: new syntax requires literals to be [_], e.g. [_]string{}
<fengb> Oops
<fengb> [_]string{}
<donpdonp> isnt that an array literal? I want to make an empty slice to put into the tags slice variable
<fengb> I don't think there's a way to make a literal slice by itself, but an empty array coerces to a slice
<donpdonp> hmm, ok thx.
<donpdonp> a slice always derives from an array, so it makes no sense to try and create an slice.
<donpdonp> i wish the compiler error could state that somehow
Jenz has quit [Ping timeout: 245 seconds]
<donpdonp> when the error says 'found slice' it looks like I did successfully create a slice from an empty array, which leads me to think it should be assignable to tags
<donpdonp> instead, []string{} should be a syntax error?
DutchGh0st has joined #zig
<DutchGh0st> AccessDenied
<fengb> It's xz
<DutchGh0st> okey cool
<DutchGh0st> cuz I found another compilerbug
<DutchGh0st> but I removed the ubuntu subsystem from my machine because it was broken
<DutchGh0st> but I need gdb :3
<nrdmn> I made a list \o/ https://github.com/nrdmn/awesome-zig
<fengb> That tells me I need a better description for zee_alloc :P
<DutchGh0st> routez is verry clear tbh
<DutchGh0st> just compiletime checks to check the handler functions for the right number of args, right parameters
<DutchGh0st> hehe
andersfr has joined #zig
<donpdonp> nrdmn: thx for the zig list.
<donpdonp> gameboy emulator in zig that runs in webasm is awesome.
<fengb> It only supports 3 games atm :P
<fengb> I need to get back to it
<donpdonp> fengb: haha. i only just now realized the first step is to click on 'Bootloader'. perhaps another msg up there would be a good idea
<fengb> I should rename that to "insert cart"
<fengb> Haven't really done much user studies yet heh
<nrdmn> I'm glad I could motivate you to work on your zig projects :P
<DutchGh0st> where does the global allocator live?
<fengb> Well, I started looking at audio, then got scared at its scope...
<fengb> DutchGh0st: std.heap.direct_allocator is available in OSs but there isn't a default allocator
<DutchGh0st> mhhh
<fengb> There's also no general purpose allocator atm
<DutchGh0st> I thought you could default assign members of a struct
andersfr has quit []
dftxbs3e has quit [Quit: Leaving.]
wtw has joined #zig
DutchGh0st has quit [Remote host closed the connection]
<fengb> I didn't know tiehuis is writing a Gameboy emulator
Akuli has quit [Quit: Leaving]
<tgschultz> Someday I may understand why people are so obsessed with WASM, but not today
<fengb> I dunno about others, but I'm much more comfortable in the browser UI than native anything
<fengb> And it's easier to demo :)
<fengb> At some point, I'll probably port fundude to SDL or something
<Sahnvour> at least that's an important performance improvement over javascript
<mq32> tgschultz: i think it's sucklessness
<mq32> JS has so many quirks and weird behaviour that people already transpile code to JS
<mq32> why not make it a performance-oriented thing then
<fengb> asm.js isn't quirky. But it's also pretty fugly
<halosghost> asm.js is amazing and horrifying
<fengb> And obviously not a good compile target so I'm glad wasm is a thing :P
<gonz_> I'm surprised how negative people are about WASM, mostly. It's a no-brainer if not pushed by one single entity that's just trying a land-grab for the web.
<mq32> fengb: JSfuck is pretty fugly :D
<mq32> but also funny that it even works
<halosghost> gonz_: I'm not a fan of anything that furthers the march of the web toward webapps
<halosghost> hence my not-love of wasm
<gonz_> halosghost: I don't know how to tell you this, but that race has already finished. :D
<gonz_> They're already on the desktop at this point.
<gonz_> We may as well have ones available from more languages with the possibility of executing them more efficiently.
<halosghost> gonz_: alternatively, I could just become a hermit and drive a podbike everywhere
<halosghost> I wish I could switch entirely to links
<mq32> i would like to have separation of "apps" and "informational databases" in the web
<mq32> right now we have news pages that do only 5% news display and 95% "stuff"
laaron- has joined #zig
<gonz_> halosghost: Unrelated to the web, but my plan is to reach a point where I don't really have to cut code for anyone else anymore and just live out my life working on private libraries in some lower level language that I know every nook and cranny of (preferably Zig) and that doesn't do much magic.
<gonz_> I envy the people who've amassed their own private C89 (pick your year, really) libraries over the last 15+ years and they don't care about anything.
<halosghost> lol
laaron has quit [Ping timeout: 260 seconds]
<gonz_> This is best done as a hermit without any care for the rest of the world.
<halosghost> I'd get a podbike nowish if I could, but they're illegal in America
<halosghost> because of course they are
Ichorio has joined #zig
<mq32> gonz_: word
<tgschultz> I'm kinda with halosghost here. The way the web browser has been perverted from a simple document render into a horrifically bad application platofrm that may as well be its own OS now pushed with every application on to devices that already have an os... I believe history will look back upon it as one of early computing's most awful crimes.
<mq32> true dat as well
<tgschultz> I too would really like to go back to simpler days of computing, and nuts to the modern web.
<mq32> but: html/css is a really nice way to make frontends
<Sahnvour> s/crime/idiocie/ :p
<mq32> except for some good layouting engine
<tgschultz> incidentally: #dinghy
<fengb> But also... the web is one of the few sandboxed engines. I'd rather run untrusted code in a browser than locally
<nrdmn> documents have been non-interactive because they were printed on paper
<nrdmn> there's no reason in this day and age to not make documents interactive and thus applications
<tgschultz> There have been countless sandboxed virtual machines for applications over the decades. almost all of them were better than a web browser at being an application platform.
<mq32> i think nobody has anything against hyperlinked documents
<fengb> None of them have been standardized. The web may be shitty, but it's the most portable shitty env we have
<tgschultz> "standardized" meaning "whatever google says, goes"
<nrdmn> mq32: interactive as in "contains logic that reacts to input"
<mq32> and i have to admit: there are some tutorials in the web that make great use of javascript
<fengb> I'm not a big fan of Chrome eating the web :(
<mq32> above link is an example for an exceptionell web document
<fengb> Honestly though, the wasm design has very little to do with the actual web. It's basically a traditional stack machine
<mq32> yeah
<mq32> i heared of cloud services serving wasm instead of native apps
<fengb> So "runs in the browser" is only one of its benefits. More generally, it's a great "portable" sandbox... much better than JS anyway
<mq32> sounds reasonable to me
<fengb> Basically what the JVM was promised, without the baggage of a corporate entity or an object system
<fengb> But maybe I'm wrong... maybe it'll be as useful as Java applets :P
<mq32> one thing i did not understand:
<mq32> how does wasm interfaces "the outside"?
<tgschultz> Or a way to free memory
<tgschultz> or a standardized interface to the os
<fengb> You define symbols that don't exist locally and it expects to be there upon wasm initialization
<fengb> OS => WASI. free()... >_>
<mq32> fengb: so similar to object files?
<mq32> or dynamic libaries?
<fengb> Yeah basically
<mq32> hm, okay
<fengb> I don't know how they work outside of the browser, but in Javascript, you pass in an object with functions or values and "it works". There's a lot of memory ownership that can get complicated but it's doable
<fengb> Also... to the outside world, there's only floats and ints in wasm. So working with pointers is a bit of a pita
<mq32> huh, weird
<mq32> so a simple write("foo") is hard then?
<fengb> Yeah, you need to copy the string into special wasm memory. It doesn't have access outside of its own vm
<fengb> Emscripten and Rust (I think) sets up bindings for you
<tgschultz> WASI is only one of several such runtimes
<mq32> hm
<tgschultz> which means we're following the FOSS definition of standard I suppose
<fengb> But the spec doesn't actually help and I kinda wish there's a better, standardized userland system
<tgschultz> how long until someone comes along and writes an abstraction layer for the OS interface runtimeS?
<mq32> hm
<mq32> doesn't sound very promising yet
<fengb> I malloc the space I need for the cartridge, copy the data over, and then pass the pointer into my emulator
<fengb> https://wasmer.io there's some silly projects so far
<mq32> curl https://get.wasmer.io -sSfL | sh
<mq32> those are the most trustworthy projects ever
<mq32> "hey, just run some code you've never seen!"
<fengb> If we had proper sandboxing, that might actually be safe >_>
<mq32> hah!
<mq32> classic egg or chicken problem
<fengb> You know it's hip if it run on the blockchain :P
halosghost has quit [Quit: WeeChat 2.5]
avoidr has quit [Quit: leaving]
<mq32> if i interface C which returns "void*"
<mq32> and this may be NULL
<mq32> how do i wrap this into Zig?
<fengb> ?*c_void
<scientes> yeah c_void is very different from zig void
<scientes> its basically the same as char *
<fengb> Or ?[*] if it's always an array
<mq32> writing a wrapper for dlopen/LoadLibrary right now…
<fengb> Oh it explicitly calls out "opaque handle". You can create an @OpaqueType and use that as a pointer
<scientes> mq32, it would be cool if that could be made to work without libc
<scientes> e.g. you still use musl's dynamic loader
<scientes> but zig would be static
<mq32> scientes: i'll take a look :)
<mq32> for windows we only require kernel32.dll
<gonz_> `std.os.windows.HANDLE` exists, by the way
<scientes> but maybe its best to just use --library c in these cases
<scientes> yeah it would reduce the amount of pain
<mq32> hmm
<mq32> how do i make my string zero terminated?
<mq32> alloc a slice of u8 with len+1 and fill it?
<scientes> yep
<mq32> okidokey
<scientes> there is a propasal to make such things part of zig
<scientes> but that isn't implemented, and not clear
<gonz_> mq32: Ah, actually, I saw now that `std.os.windows.HMODULE` exists
<mq32> yeah right now i'm doing the linux part first :)
<mq32> lld: error: undefined symbol: dlopen
<mq32> okay, time to go to bed :)
<mq32> code compiles so far :)
porky11 has quit [Quit: Leaving]
ltriant has joined #zig
dimenus has quit [Ping timeout: 246 seconds]
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 245 seconds]
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 245 seconds]