ChanServ changed the topic of #zig to: zig programming language | | be excellent to each other | channel logs:
oconnor0 has quit [Ping timeout: 252 seconds]
oconnor0 has joined #zig
<daurnimator> andrewrk: let me know when you'd like to revisit.
<andrewrk> daurnimator, will do
<daurnimator> does zig have a http library?
<andrewrk> daurnimator, what were you saying about how you solved a blocking function call creating a one-time-use event loop?
<andrewrk> no http lib yet
<andrewrk> that's pending coroutines rewrite, which is pending copy elision
<daurnimator> andrewrk: if we solve the coroutine question I think I'd like to start on a http lib for zig
<daurnimator> :)
<daurnimator> andrewrk: okay I might tell you the story of cqueues :)
<daurnimator> andrewrk: as you may know, lua has coroutines as a language feature
<daurnimator> the primitive operations are "resume" and "yield".
<andrewrk> same in zig - resume and suspend
<daurnimator> however they require no annotations
<andrewrk> same in zig so far
<daurnimator> function foo() print("A") coroutine.yield() print("B") end
<daurnimator> wouldn't that require an 'async' annotation in zig at the moment?
<andrewrk> what does the coroutine body look like?
<daurnimator> andrewrk: huh?
<daurnimator> andrewrk: if you call foo above from outside of a coroutine, then coroutine.yield() would throw an error: "attempt to yield from outside a coroutine"
<andrewrk> ah, I see, foo *is* the coroutine in this example
<daurnimator> foo is just a function in this example :)
<andrewrk> in zig: async fn foo() void { print("A"); suspend; print("B"); }
<shachaf> Hmm, how are coroutines implemented? Is it with stack switching or something else?
<daurnimator> instead you would usually call it like so: myco = coroutine.create(function() foo() somethingelse() end); ok, err = coroutine.resume(myco)
<andrewrk> shachaf, it's with LLVM's coroutines IR support. it splits functions up into multiple functions
<andrewrk> however there is a planned rewrite which changes how they are implemented and some of the semantics
<shachaf> Ah, so they all use the regular thread stack, and variables declared in async functions go into a state struct or something?
<shachaf> I guess I should read about how LLVM coroutines work.
<daurnimator> andrewrk: does the above make sense so far?
<andrewrk> shachaf, it's the same as C++ coroutines. they are stackless - imagine the function accepts a hidden first argument which is a struct containing all its stack variables
<shachaf> Right, that sounds like what I'm describing.
<shachaf> Does the planned rewrite work the same way?
<daurnimator> shachaf: I think I'm trying to influence that now :)
<andrewrk> daurnimator, can you do your example without an anonymous function and I'll translate it into zig for you?
<shachaf> I've been wondering lately what the real cost of userspace threads/coroutines with stack switching is over manually managing state for asynchronous operations (or apparently what LLVM does).
<shachaf> I think there's a hidden cost that people often don't appreciate, which is that when you switch stacks all the time, you get a bunch of cache misses for code that uses the stack for some regular computation that doesn't suspend.
<andrewrk> shachaf, it will work mostly the same, except: zig will create the struct for the local variables and do the function splitting rather than llvm; the async keyword will not be used to create a coroutine, and the memory for the coroutine frame is passed to the coro rather than it using an allocator to alloc/free the frame
<daurnimator> andrewrk: function foo() print("A") coroutine.yield(42) print("B") return 84 end; myco = coroutine.create(foo); ok, yielddata = coroutine.resume(myco); ok, moredata = coroutine.resume(myco);
<shachaf> andrewrk: OK, that sounds like an improvement.
<andrewrk> shachaf, what's beautiful about how zig does it though, is that coroutines generally don't yield until they cannot continue due to an I/O operation not being ready yet. if a thread would sit there doing nothing, better to have it switch tasks, right?
<shachaf> By "usespace thread" I mean something very lightweight and cooperative, like coroutines.
<shachaf> (But with some sort of scheduler? I guess that's the difference between coroutines and threads, in my mind.)
<shachaf> I do think stack switching is suboptimal, though. I just don't know how big the effect actually is. People often measure the wrong thing.
<andrewrk> daurnimator, sorry just a moment, working on example code
<daurnimator> shachaf: the difference is that a scheduler goes in the stdlib/external. the coroutine support goes in the language.
<daurnimator> shachaf: i.e. you build a standard scheduler interface/API using the coroutine support in the language.
oconnor0 has quit [Ping timeout: 252 seconds]
<shachaf> But a good userspace thread library should probably let you schedule threads yourself.
<daurnimator> shachaf: sure
oconnor0 has joined #zig
<shachaf> Anyway I'm interested in the Zig approach -- which is apparently used in C++20 too? I didn't know about that.
<andrewrk> I'm not sure how that would fit in. the current implementation uses, for example, epoll_wait on linux - all threads in the thread pool at the same time - and lets the OS pick one to resume with the I/O task
<shachaf> I think I'm just using confusing words here.
<andrewrk> daurnimator, status quo zig does not have a way to yield a value when suspending - however that is one of the things I am considering changing
<shachaf> I'm treating "OS thread" and "userspace thread" as two different things, with many userspace threads scheduled onto one OS thread.
<daurnimator> andrewrk: k. you can leave that out of your translation for now :)
<andrewrk> daurnimator, what is the `ok` value?
<daurnimator> andrewrk: the resume is implicitly a try/catch
<daurnimator> andrewrk: translating that to zig, resume() would be able to throw errors.
<andrewrk> daurnimator, this is post-rewrite code
<shachaf> I really like that Zig has named-break-with-value. I was looking for a language with that feature recently and I was surprised I didn't find anything.
<andrewrk> shachaf, with the way zig does coroutines, there is no userspace thread
<shachaf> andrewrk: I agree. Well, depending on whether you consider coroutines to be threads.
<andrewrk> I think that "thread" implies stack space for more than one frame
<shachaf> Not in the usual sense of the word at least.
<shachaf> Right.
<daurnimator> andrewrk: oh one thing; create() doesn't kick off the coroutine, it just allocates the room for it
<andrewrk> daurnimator, same, in the zig translation
<shachaf> So if an async function wants to call another async function, does it add extra space for the second function's state struct in its own state struct?
<andrewrk> daurnimator, oops, sorry, not quite true - but it will be possible to do that, let me show you
<daurnimator> andrewrk: yeah I think you put a suspend right at the start to do that?
<andrewrk> yes
<shachaf> Or is that the plan with the new system, I guess I should ask, because it sounds like LLVM does something strange here.
<andrewrk> daurnimator, hang on let me send another code snippet
<andrewrk> shachaf, in status quo (LLVM), you pass an allocator to a coroutine and it uses the allocator to create and destroy the frame. post-rewrite, calling an async function uses the "result location" (which is a copy elision concept) as the frame, which means the frame can be static data, on the heap, or on the stack, depending on the expression. and so yes if it is on the stack, then it would add extra space for the second function's state
<andrewrk> struct in its own
<shachaf> Shouldn't it be irrelevant whether it's on the stack?
<shachaf> I guess I should ask a more general question. If you have two async functions F and G, can F use G, and what does the memory layout for that look like?
darithorn has quit [Ping timeout: 250 seconds]
oconnor0 has quit [Ping timeout: 268 seconds]
oconnor0 has joined #zig
qazo has joined #zig
oconnor0 has quit [Ping timeout: 268 seconds]
jmiven has quit [Quit: co'o]
jmiven has joined #zig
qazo has quit [Ping timeout: 260 seconds]
<daurnimator> context for channel: I just showed andrewrk what I'm trying to get to with my coroutine suggestions.
oconnor0 has joined #zig
<shachaf> Hmm, Zig lets you take the address of an rvalue?
<shachaf> Maybe it doesn't have C-style r/l values
<andrewrk> shachaf, I believe that's related to the copy elision branch I'm working on
<andrewrk> to your other question: F decides where the memory for G is depending on the syntax used to invoke it. It could be on the stack, heap, or it could even be global
<shachaf> Can it be inside F's memory struct?
<shachaf> Does G's memory include a return address or something like that that yields control back to F when G is done?
darithorn has joined #zig
clownpri1 has joined #zig
clownpriest has quit [Ping timeout: 252 seconds]
wink_ has quit [Quit: - A hand crafted IRC client]
<andrewrk> shachaf, sorry for the delay. yes it can. let me code up a few examples...
oconnor0 has quit [Ping timeout: 268 seconds]
oconnor0 has joined #zig
<andrewrk> shachaf,
<daurnimator> andrewrk: hey I'm trying out your fix for and it doesn't seem to be working?
<shachaf> andrewrk: Aha.
<shachaf> This is in the new proposal, it sounds like, not the LLVM implementation?
<andrewrk> shachaf, correct
<andrewrk> daurnimator, can I see your test case?
<andrewrk> oh right
<benjikun> It's not possible to use zig with z80 architecture ATM is it
<benjikun> I wonder if that's too obscure to warrant making it compatible
<andrewrk> benjikun, looks like llvm does not support z80 which means zig does not either
<benjikun> oh I see
<MajorLag> I don't think llvm supports any 8bit archs?
<MajorLag> or 16 for that matter.
<shachaf> andrewrk: Does this generate code equivalent to something like const @frame(g) = struct { returnAddr: *fn() noreturn } ?
<andrewrk> oh right, ok so how await works:
<andrewrk> imagine the 2 threaded case, 1 thread races toward return, the other thread races towards await
<benjikun> MajorLag: yeah, ig it doesn't from looking at their features page
<andrewrk> await does a suspend, then @atomicRmw xchg, putting the ptr to coro frame into g's frame in the awaiter field
<andrewrk> return does @atomicRmw xchg, putting 0xffffffff into its own frame in the awaiter field
<andrewrk> if the await got 0xfffffffff then the return won the race; the result is in the result field of g's coro frame. it resumes itself. otherwise the suspend completes, relying on g to resume f
<MajorLag> benjikun: yeah, it's a shame. I'd have liked to try writing a C64 or DOS game in zig. Maybe some day, but probably not.
clownpri1 has quit [Quit: clownpri1]
<andrewrk> if the return got 0x0 (initial value) then the return won the race. suspend itself, knowing the awaiter will look at its result field of the coro frame. otherwise the return gets the awaiter ptr, and resumes the awaiter
<shachaf> OK, I think I've been assuming too much about how this works, I was figuring something much more deterministic.
<andrewrk> it's designed to work in a multi-threaded environment
<benjikun> MajorLag: true, maybe in the future
<andrewrk> sorry let me clarify, I just realized post-rewrite it will be slightly different: `return` puts the result in its own coro frame in the "result" field, begins a suspend, *then* does the atomic xchg. then either the xchg gave an awaiter handle, in which case it tail resumes the awaiter handle, or completes the suspend
<shachaf> So "g()" in your example schedules g to run on some thread at some point?
<andrewrk> `await` starts a suspend, does the atomic xchg, then if it got a zero value, it completes the suspend, knowing the `return` will resume it. otherwise, it tail resumes itself, and the first thing it does out of suspend is get the return value from the target's frame
<andrewrk> the way to think about it is that "g()" is responsible for getting to the `return` instruction (which may be implicit at the end of the function if the return type is `void`).
<andrewrk> this means that if g suspends, it must have a plan for how to get resumed
<andrewrk> so one way to do this would be to start a suspend and then put its handle onto a scheduler, yes
<andrewrk> another way would be to suspend, and then put its handle into an epoll set, kqueue, or IOCP
<andrewrk> MajorLag, benjikun, I see some projects that are plugins to llvm to add z80 support. I don't know how far along they are or what the quality is though
<benjikun> interesting
<benjikun> LLVM+SDCC
<shachaf> Oh, I see, g chooses whether to suspend
<andrewrk> shachaf, right. if it does not suspend it will proceed right along to the return statement, and be guaranteed to finish before it is possible to `await` it
<shachaf> I think this makes sense, though in the common case it seems like there wouldn't be any races?
<shachaf> Maybe I'll try it out and look at the generated code to figure it out. :-)
<andrewrk> there could be races because std.event.Loop creates a thread pool, and async I/O functions use it. so if you do multiple things that wait on I/O the OS will choose threads to resume the appropriate coroutines
<daurnimator> andrewrk: any hints re: 1719?
<andrewrk> daurnimator, sorry, I'm having a look at it
<andrewrk> daurnimator, I think I know what's going on. the code is actually working, but then C1 and C2 are marked for normal code generation (in addition to being analyzed in a comptime context), which is impossible because of the ++, so we emit an error
<andrewrk> i'll comment on the issue
<oats> andrewrk: how have you set up your vim in your videos to give you linter info?
<andrewrk> oats, no. I have a very primitive vim setup
<oats> I noticed :)
<oats> are you just using !command then?
<andrewrk> oats, oh, I'm using the zig vim extension which runs zig fmt on save, is that what you're talking about?
<oats> ahhhh, yeah
<oats> I remember reading that in the zig.vim readme
<oats> is the stage2 compiler the one that's going to be self-hosting?
<andrewrk> yes
<andrewrk> stage2 is when you compile self-hosted with stage1; stage3 is when you compile self-hosted with stage2. stage3 is what we want to ship
<andrewrk> stage2 can only compile hello world at the moment
<oats> TIL of streaming parsers
<oats> that's a cool concept
<daurnimator> andrewrk: so should I declare the functions only inside a comptime block for now or something?
<andrewrk> daurnimator, I'm going to try and fix it for you in 10 minutes
<daurnimator> ah k
<daurnimator> I thought it sounded like a bigger fix :P
<andrewrk> if it turns out to be bigger I'll give you a workaround
<andrewrk> oh, a workaround is to make the args comptime
<daurnimator> andrewrk: yeah that's what I have in my gist at the moment/
<daurnimator> felt like marking a function as comptime would be better
<andrewrk> I think marking the args comptime is a better communication of what the function needs
<andrewrk> one of the goals in zig is to make it unnecessary to distinguish what functions are comptime and what are runtime
<benjikun> andrewrk: Would you be open to making a spreadshirt for zig shirts / stuff to go along side your patreon
<daurnimator> andrewrk: I like that.... but as observed, without that flag we only have the arg annotations as a workaround here.
<daurnimator> hopefully the fix is easy :)
<benjikun> Spreadshirt or teespring
<andrewrk> benjikun, I dunno, I think I'll wait until 1.0.0 for that
<benjikun> Fair enough
scientes has left #zig ["Leaving"]
scientes has joined #zig
<diltsman> How would I reference a variable defined in the linker script?
<andrewrk> diltsman, declare an extern variable with the same name, and then look at the *address* of the extern var
oconnor0 has quit [Ping timeout: 268 seconds]
qazo has joined #zig
qazo has quit [Ping timeout: 260 seconds]
qazo has joined #zig
<andrewrk> daurnimator, it's not a quick fix
<daurnimator> aw
<andrewrk> but it remains an open issue
<andrewrk> as soon as I gave up I thought of another idea
qazo has quit [Ping timeout: 240 seconds]
<diltsman> andrewrk, I figured out the extern part, but I never would have figured out to look at the address.
<andrewrk> diltsman, does it make sense now that you think about it?
<diltsman> I think so.
oconnor0 has joined #zig
<diltsman> How do I convert a begin/end pointer pair to a slice?
<andrewrk> begin[0..end - begin]
<andrewrk> did I not implement subtraction? if so then begin[0..@ptrToInt(end) - @ptrToInt(begin)]
<diltsman> So, given extern const _b:u8; and extern const _e:u8; (both linker constants, I need a slice that covers the range so that I can memcpy from flash to ram.
<andrewrk> I haven't updated this in a while, but here's what I did
<andrewrk> this code is missing alignment annotations, the variables should have `align(4096)` or whatever on them
<andrewrk> (which is just an optimization)
<andrewrk> I think it makes sense to use @memcpy in this case
<andrewrk> daurnimator, it's actually kinda tricky, because we have to notice that a function has no references in comptime constants that make it into the object
<andrewrk> consider if you pass a function pointer to a comptime arg, then store the value in a struct, which ends up a global const, referenced somewhere
<andrewrk> the function must be generated so that it can be called
<andrewrk> here even though we never call norm_zero case, we have to generate it, because we reference the NormalDist global constant, which has it as a field
<daurnimator> andrewrk: when that assignment happens you should mark the function as run-time implementation needed
<daurnimator> I'm not sure I understand the issue
<andrewrk> but that's not necessarily true. if we only used the return value of ZigTableGen at comptime, we wouldn't need to generate a runtime implementation
<daurnimator> though I can see how internal implementation details could make this a easy or hard problem
<andrewrk> anyway, putting it off for now. the comptime arg workaround I think is reasonable
<daurnimator> andrewrk: it does make things very verbose
<daurnimator> #define C2(x,y) C1(x,y) C1(x+1,y) --> fn C2(comptime x:i32,comptime y:i32) [2]u8 { return C1(x,y) ++ C1(x+1,y); }
<daurnimator> not to mention actually needed to know the [2] length instead of it being inferred
<daurnimator> andrewrk: I guess the only thing to say is: "keep working on things" :)
<daurnimator> andrewrk: seems like zig isn't *quite* at a point where I can use it yet.
<daurnimator> though I'm very happy with the direction it is going
<daurnimator> hopefully you get some time to play with my coroutine recommendations and integrate them in the next month or two
<andrewrk> that makes sense. despite keeping the language small it turns out to be quite a large project in terms of effort
<daurnimator> andrewrk: at where should the setEvalBranchQuota actually go?
<daurnimator> --> how can I attach that annotation to a function? "if this function is called at compile time make sure it has at least X quota"
qazo has joined #zig
<daurnimator> andrewrk: two related questions: can you declare functions in a comptime block? comptime { fn C2(x,y) [2]u8 { return C1(x,y) ++ C1(x+1,y); } }
<daurnimator> 2. What would it take to make ++ work a run-time? I suppose the issue is you also need an allocator.....
<hryx> You'd certainly need an allocator to use ++ on runtime values, which I'm sure means it wouldn't become a language feature
<hryx> daurnimator: Curious, what would be the expected result of declaring functions in a comptime block? Would they be only available at comptime? Would they only be in scope in that block?
<daurnimator> hryx: yes. they would only be available at comptime
<hryx> I've never tried that. Lemme see...
<daurnimator> hryx: in this case: because they cannot be implemented at runtime due to use of ++.
<hryx> looks like it isn't syntactically valid to define a fn in a comptime block, because fn is only a top-level decl (for now)
<daurnimator> hryx: okay.
<hryx> But I think in the future there will be a way to do what you want. I thought I saw an issue somewhere that implicitly wraps comptime around ++ operators (I can't find it right now)
<hryx> I thiiiink that would help with what you want to accomplish, when it's implemented
<hryx> sorry, operands, not operators
<daurnimator> hryx: the implicit comptime around ++ was which is in master now.
<hryx> that explains why I couldn't find it! :P
<daurnimator> hryx: are you Hejsil on github?
hio has joined #zig
<hryx> nope, I'm hryx on GitHub. And Hejsil = Hejsil here too
<daurnimator> thanks
<hio> how should we work with unicode in zig?
<hryx> hio: with a library, but I dunno if there is one yet. My guy that's stdlib material in the future
<daurnimator> hio: what do you want to do?
<hio> I looked quite a while for the best c libraries that could be used or copied from, Imo these are the only contenders: , ,
<daurnimator> hio: you want to validate utf8?
<hio> I would ideally like to get the same comfortable API surface that I get in c#, all these methods:
<hio> validating utf8 sounds to me like the prerequisite to any and all further utf8 functions
<daurnimator> hio: IMO indexing by codepoints is almost always the wrong thing to be doing
darithorn has quit [Quit: Leaving]
<hio> probably yeah, there has to be a general decision whether you go with a grapheme based approach or a codepoint approach
<hio> imo there should probably be both to be honest, just so you can see the difference and pick and choose exactly what you want
<daurnimator> hio: generally you should be treating strings pretty much as a sholw
<daurnimator> hio: there are very particular algorithms if you want to insert utf8; or wrap utf8; or get the width when printed. none of them require indexing
dtz has joined #zig
<daurnimator> however, useful utf8 operations are: validate_utf8(), convert_to_encoding(), convert_from_encoding(), normalize_utf8() with various normalization types as arguments, utf8_cells(), wrap_utf8()
<hio> right well, we can see that other comfortable languages offer all kinds of string operations on the same object. People (and I) have started to expect this level of comfort from new languages. Like String.substring() String.match(regex)
<daurnimator> hio: regex and substring are fine: they can work on bytes though :)
<hio> I have not found a single implementation of utf8 regex except I think in ICU4C but that library is huge and weird
<hio> daurnimator: anything works on bytes, that's not the point. I obviously want it to work on graphemes when I make a regex on an utf8 string
<daurnimator> hio: the only 'utf8' support you actually need in regex is the character classes. which is actually quite easy to add.
<daurnimator> I believe libPCRE includes them
<daurnimator> however outside of complicated email filters, I don't think I've actually seen any regexes in the wild that use them
<hio> 先秦兩漢.match(先) should work predictably
<daurnimator> hio: is..... that a substring there?
<daurnimator> hio: or are you assuming the regex would denormalise
<daurnimator> *normalise into decomposed form
<hio> uh I'm obviously(?) talking about some kind of string comparison and therefore things have to be normalized so they can be compared
<daurnimator> hio: normalization should never be automatic, it should always be explicit
<hio> says who?
<daurnimator> says my history in debugging :P
<daurnimator> but also from the zen of zig: "Communicate intent precisely."
<hio> since we are talking about a library feature, either way the library will denote how it needs to be used.
<daurnimator> also if such a thing makes it into the stdlib, make sure you accept a unicode standard as an argument! Many bugs have historically occured due to libraries/languages assuming there is only one "unicode"
qazo has quit [Read error: Connection reset by peer]
qazo has joined #zig
<hio> interesting, seems like Rust never bothered to implement graph cluster related operations in their std library either, but this explanation of utf8 in general and their context is great:
<hio> Their choice of not allowing single indexing but allowing slice based indexing seems really weird
porky11 has joined #zig
qazo has quit [Read error: Connection reset by peer]
qazo_ has joined #zig
qazo_ has quit [Read error: Connection reset by peer]
qazo has joined #zig
davr0s has joined #zig
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
davr0s has joined #zig
qazo has quit [Read error: Connection reset by peer]
qazo has joined #zig
SimonNa has quit [Remote host closed the connection]
qazo_ has joined #zig
qazo has quit [Read error: Connection reset by peer]
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
davr0s has joined #zig
<MajorLag> andrewrk: I've experimented with align() and I'm pretty sure align(4096) won't do anything. Even the documentation says that alignOf(T) is guaranteed to be < @sizeOf(T).
scriptnull has joined #zig
<MajorLag> <= rather
DutchGh0st has joined #zig
qazo_ has quit [Read error: Connection reset by peer]
qazo has joined #zig
<DutchGh0st> I build the compiler, and the selfhosted one
<DutchGh0st> do I now export the place of the binary to my path variable sooo vim knows where to find zig to format the code?
Hejsil has joined #zig
<DutchGh0st> Hejsil: , I build the selfhosted compiler, do I now add it to my path variable so the automatic format in vim knows where the compiler is?
<Hejsil> Ye, that's probably right
<DutchGh0st> but binary is the selfhosted? xD
<Hejsil> I don't use vim though, so I'm not sure how zig.vim works :)
<DutchGh0st> *but what
<Hejsil> build/stage2/bin/zig ?
<Hejsil> Idk where you have your build output
<DutchGh0st> oh there
<DutchGh0st> yeah I just literally followed the steps as described here:
oconnor0 has quit [Ping timeout: 244 seconds]
<DutchGh0st> so the stage2 compiler can do everything? I dont really know how all this works
<Hejsil> Nope, stage2 can only build hello world and do zig fmt
<Hejsil> I have zig1 and zig2 in my path, so I can compile with stage 1 and fmt with stage 2
<MajorLag> side note: you can get a certain amount of zigfmt functionality just shoveling the output of std.zig.parse into std.zig.render without compiling stage2.
scriptnull has quit [Remote host closed the connection]
<DutchGh0st> butt.....
<DutchGh0st> inside the build directory, there is a zig executable
<DutchGh0st> but in /build/bin there also is a zig executable..
<DutchGh0st> so what should I pick? o.O
<ltr_> probably they are the same
<hio> what is this syntax? assert(ptr.?.* == 1);
<DutchGh0st> its checking for an optianal pointer and the dereffing it
<DutchGh0st> *and then
<hio> ptr.?. is the check? why is each dot necessary, what does it mean?
<hio> what am I calling on ptr
<hio> ptr.
<DutchGh0st> ptr.? <-- ptr is of type `?*T`, so ptr.? is basically unwrapping the optional part
<DutchGh0st> after that you get something of type `*T`, which you can then dereference using `.*`
<ltr_> is calling the function ? on ptr, thats how i see it
<DutchGh0st> If you know, rust, it would be something like '*(ptr.unwrap())'
<ltr_> what happens if ptr is null? error?
<DutchGh0st> stacktrace I think?
<hio> what do you guys think of the new syntax with all these dots?
<DutchGh0st> I think putting the deref star in front of the pointer to dereference reads a little nicer
<DutchGh0st> and saves you writing a dot
<hio> what does this mean for example: array.*.append(valueToSet.*)
<DutchGh0st> but hey, Im not a designer :), pt.* doesn't bother me that much really
<hio> oh i guess it dereferences the array with the first *
<hio> i dont think this applies here ltr_
<hio> it would be like this then: append(array, valueToSet)
<hio> first param is the caller
<ltr_> if you see * as a function that dereferences it does, *(pointer) pointer.*
<ltr_> no?:S, i relearning zig btw this is new to me too
<ltr_> one of the benefits is that you can chain things
<ltr_> ie ptr.?.*
<DutchGh0st> how do I add a command to the path variable?...
<hio> you mean the linux environment PATH? you have to be a bit more specific
<hio> also #linux
<ltr_> export PATH=$PATH:/new/path
scriptnull has joined #zig
<ltr_> your executable should be in /new/path
<DutchGh0st> oh so you give the directory where the binary is in?
<DutchGh0st> allright
<DutchGh0st> should't I put it in /bin really?
<ltr_> yes
<ltr_> or /usr/bin/
<DutchGh0st> yeah
<DutchGh0st> okey
<hio> I always write new commands into my .bash_rc in $HOME
<hio> the path to its folder I mean
<hio> then on bash I > source .bashrc
<DutchGh0st> wait, doesn't zig need the lib directory also, with stdlib in it?
<hio> it will find it with relative path, I strongly assume
<ltr_> its looks somehwere in /usr/local
<DutchGh0st> also if the binary is in /usr/bin?
<ltr_> you can override the location too via cmd line
<ltr_> when you do a make install
<ltr_> it install the stdlib somewhere in the prefix_path chosen
<DutchGh0st> but I did not doo that xD
<ltr_> then you have to tell the compiler where it is
<DutchGh0st> ugh
<DutchGh0st> ill just never touch my /zig folder in ~/ again
<hio> echo "export PATH=$PATH:/my/path/to/zig/bin" >> ~/.bashrc && source ~/.bashrc
<hio> thats all you need to do!
<Hejsil> I just have a ~/.bin in my path, and then I just symlink things into this folder
<DutchGh0st> No such file or directory... mhh
<Hejsil> DutchGhost, you could also install zig in your usr/bin: bin/zig build --build-file ../build.zig --prefix /usr/ install
<DutchGh0st> and then stdlib will be installed in /usr/lib ?
<Hejsil> Yea
<Hejsil> I think
<Hejsil> My build/stage2 has a lib and bin folder, so I would assume so
<ltr_> $INSTALL_PREFIX/lib/zig
<ltr_> $INSTALL_PREFIX/lib/zig/std for zig's stdlib
<DutchGh0st> mh?
<DutchGh0st> I suppose that also needs sudo then Hejsil?
<ltr_> not if you specify CMAKE_INSTALL_PREFIX in the build process
<Hejsil> Yea, which is why I do ~/.bin in path trick instead
<DutchGh0st> mhh, not sure what version I picked then?
<Hejsil> Btw, stage2 cannot build anything real
<DutchGh0st> yeahh I did this: usr/bin: bin/zig build --build-file ../build.zig --prefix /usr/ install
<Hejsil> Yea, that's the stage 2 compiler you build and installed
<Hejsil> Did you only want stage 1 in your path?
<Hejsil> If so, my bad. I missunderstood
<DutchGh0st> I just want to run something like 'zig build-exe main.zig' , from anywere in my system
<Hejsil> Aaaah, right
<DutchGh0st> and then maybe like 'zigfmt fmt main.zig' to format
<DutchGh0st> I guess I now need to remove zig from both my /lib and /bin folders?
<ltr_> im getting a nasty SIGSEGV compiling the helloworld
<presiden> compiling? not running?
<DutchGh0st> why with the export path thingy, it can't find ./zig when executen from a different directory?
qazo has quit [Ping timeout: 240 seconds]
alehander42 has joined #zig
porky11 has quit [Ping timeout: 264 seconds]
<andrewrk> ltr_, I usually tell people to just unzip and run from there, rather than to try to do some global thing
<scriptnull> Hi, could someone tell me what does `pub` keyword do? (unable to find it on docs, did I miss it out somewhere?)
<andrewrk> scriptnull, it has to do with importing:
<andrewrk> scriptnull, I just filed an issue to create documentation for pub:
<scriptnull> I guess it is for publishing the variables/functions for importing in other zig file. Am I right? (much like export in ES6?)
<andrewrk> correct
DutchGh0st has quit [Quit: - A hand crafted IRC client]
<ltr_> uh oh
<ltr_> is the master branch working? : CommandLine Error: Option 'dump-thin-cg-sccs' registered more than once!
qazo has joined #zig
oconnor0 has joined #zig
<andrewrk> ltr_, yep it's working - if you look at, the master branch info is automatically generated, when the tests pass on every target
<andrewrk> you can see the most successful recent commit was ba361f31
<ltr_> my llvm libs are all messed out
<ltr_> ill build with a fresh env
scriptnull has quit [Remote host closed the connection]
DutchGh0st has joined #zig
Hejsil has quit [Quit: Page closed]
scriptnull has joined #zig
qazo has quit [Ping timeout: 264 seconds]
qazo has joined #zig
oconnor0 has quit [Ping timeout: 264 seconds]
oconnor0 has joined #zig
<DutchGh0st> there was something like a ' zig init' , right?
<DutchGh0st> init-exe :D
steveno_ has joined #zig
oconnor0 has quit [Ping timeout: 246 seconds]
oconnor0 has joined #zig
steveno has quit [Ping timeout: 264 seconds]
scriptnull has quit [Remote host closed the connection]
Sahnvour has joined #zig
<Sahnvour> hi andrewrk , I'm looking at zig's inline asm code, and wondered why in `ir_render_asm` when building the constraints buffer, non-return-outputs are marked with a supplementary '*' to make them _indirect_ ( ). do you remember this by any chance ?
<andrewrk> Sahnvour, I don't remember clearly. I can look at git blame to find a commit message that maybe would explain it
hio has quit [Quit: Connection closed for inactivity]
<DutchGh0st> what do you think of this colorscheme?
<Sahnvour> okay, I'll have a look too
<andrewrk> Sahnvour, it goes way back, to before even we had zig ir. I think it would be fair to start over in thinking how inline assembly should work
<Sahnvour> unfortunately I'm not competent enough on this subject, so I think I'm just going to fix the few bugs that bothered me for now
<Sahnvour> thanks
<andrewrk> did you find the llvm docs on the llvm inline asm syntax?
<andrewrk> good
<Sahnvour> I'm not clear on what the purpose of "return" asm outputs is
<Sahnvour> (zig-wise)
<andrewrk> it makes the asm expression have a result value
<andrewrk> e.g. you could do something like `return asm (...)` or `const x = asm (...)`
<andrewrk> this slightly helps the optimizer to omit 1 mov instruction
DutchGh0st has quit [Quit: - A hand crafted IRC client]
<Sahnvour> okay. and what about systematically using indirect outputs (keeping the variable address and storing into memory) when not returning then ?
<andrewrk> I have not tried that in a long time
<Sahnvour> I mean, this is what "=*..." is doing, and zig uses that on the most common case (non returning output)
<Sahnvour> if i understand correctly this would tend to add indirections
<andrewrk> oh right - that's so that you can capture output into a variable
<andrewrk> the * makes the variable address go into the assembly - that's needed if you want to populate the variable's memory
<Sahnvour> I'm missing something because then I don't see the point of omitting the *, why would one want an output variable that doesn't end up with a result value ?
<andrewrk> I was unable to understand that as well
<andrewrk> at some point here I will be taking a deep dive into inline assembly and doing another pass at it
oconnor0_ has joined #zig
<Sahnvour> rereading the doc, it seems that's only used for return values
scriptnull has joined #zig
<bheads> just checking out the stream for yesterday, andrewk: have you see unum?
<scriptnull> Hi, it is me again ( the newbie who just wrote Hello World in zig ) :D
<scriptnull> May I know why Zig is called Zig? :D
porky11 has joined #zig
wink_ has joined #zig
<andrewrk> scriptnull, random 3 letter word that has good internet search uniqueness
<scriptnull> cool!
voldyman has joined #zig
yellow_apple has joined #zig
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
davr0s has joined #zig
davr0s has quit [Client Quit]
<oconnor0_> What is `zig fmt` supposed to show up in the builds of master?
davr0s has joined #zig
<andrewrk> oconnor0, it would either be after the self hosted compiler is finished and we start shipping that, or if we do some special trick to make zig fmt available from stage1
<andrewrk> I'll consider including the trick in 0.4.0
scriptnull has quit [Remote host closed the connection]
<oconnor0_> andrewk, ah, got it; thank you. Are there Zig issues that detail what is needed for the self-hosted compiler? I see the project, but not specific issues connected.
<andrewrk> oconnor0, it's a huge project and only in the early stages. there is this:
<andrewrk> in summary, it's blocking on the coroutine rewrite which is blocking on copy elision which I'm working on now
<oconnor0_> Yeah, I saw that project. Wasn't sure if there was more detail on the to-dos.
<andrewrk> oconnor0, are you looking for somewhere to contribute?
<Sahnvour> andrewrk: I want to fix the crash occuring with comptime_int as asm input, and I think we just need to insert a cast when generating IR ; basically I want to write `IrInstruction *cast = ir_build_int_cast(irb, scope, node, ???, input_value);` but don't know what to do to get an instruction representing the type to cast to (regardles of how to choose that type)
<andrewrk> Sahnvour, I think that's right - you're looking for ir_implicit_cast
<andrewrk> which takes a ZigType* as the destination type
<voldyman> andrewrk: i am looking for somewhere to contribute (on stage2 of building the compiler rn)
<Sahnvour> ok, then this needs to be in the analyze phase right ? Is that OK to make modifications of IR during it ?
<andrewrk> voldyman, any interest in this?
<voldyman> andrewrk: it is interesting but i know very little about writing linkers. any low hanging fruits to get my feet wet?
<andrewrk> Sahnvour, yes it will be in the IR pass 2, I believe
<andrewrk> e.g. you will have an `IrAnalyze* ira` parameter
<andrewrk> in this phase the code is looking at pass 1 instructions and creating a new IrExecutable with pass 2 instructions
<andrewrk> so, instructions are not really modified; they are interpreted and new instructions are generated. does that make sense?
<Sahnvour> totally
<andrewrk> AST (parser.cpp) -> ir pass1 (ir.cpp) -> ir pass2 (ir.cpp) -> llvm ir (codegen.cpp)
errpr has joined #zig
<Sahnvour> this is the exact information I was looking for :)
<andrewrk> voldyman, I created this issue for your consideration:
<andrewrk> it's a bit of a large project, I can try to think of some other ideas for you if you like\
<voldyman> andrewrk: this looks interesting, let me read parser.cpp :)
<voldyman> thanks!
<andrewrk> Sahnvour, the pass1 stuff generally starts with "gen_" and has an IrBuilder * arg, while the pass2 stuff generally starts with or contains "analyze_" and has an IrAnalyze * arg
<andrewrk> some instructions are only meant for pass 1 and some instructions are only meant for pass 2; some are for both
<andrewrk> voldyman, ok :) let me know if you need help figuring out how to run the tests in a convenient way
<Sahnvour> how do we tell between pass 1^2 instructions ?
hio has joined #zig
<oconnor0_> andrewk, I am considering somewhere to contribute, though I am not able to build on Windows yet.
return0e has quit [Remote host closed the connection]
return0e has joined #zig
<andrewrk> oconnor0, happy to help. where along the instructions on did you get stuck?
<Sahnvour> thanks
wink_ has quit [Quit: - A hand crafted IRC client]
<errpr> how do I make a [*]T if it says 'does not support array initialization'?
<andrewrk> errpr, you need to create an array and then take the address of it. this will implicitly cast to [*]T, or you can slice it and get the pointer like this: array[0..].ptr
<oconnor0_> andrewk, never mind, looks like I missed the "Win64" in the CMake generator.
<oconnor0_> By the way, I really like that Zig prioritizes cross-platform builds and cross-compiling. Being on Windows often feels like a second-class citizen; so many languages and libraries kind of support it, but not really.
<andrewrk> oconnor0, indeed. there's more to do to improve the windows experience for zig, but it's certainly a main use case
<oconnor0_> andrewk, is there a list of simple or cleanup issues/bugs that I could take a look at? It wasn't obvious from the GitHub issues.
<andrewrk> oconnor0, you can look at the "help wanted" label
<andrewrk> also the "userland" label, which means you can write zig code to solve the issue
<oats> does zig support all targets that llvm supports?
<andrewrk> oats, that's not a yes or no question - here's the situation: zig supports all the architectures that LLVM supports. However, some language features require a small amount of additional code in the compiler, such as, what size should the c_long type be?
<andrewrk> and then there's the standard library which provides abstractions across architectures - this sometimes requires architecture-specific code
<oats> that makes sense
<andrewrk> but because of zig's lazy top level declaration analysis, if you don't depend on a given part of the std lib, it doesn't get analyzed
<andrewrk> so if your program has a small dependency on a particular OS or architecture, it will be a small effort to add compatibility
<andrewrk> for example if your program only does os.sleep(1), then all you have to do is implement the sleep syscall for the target os and architecture, and it will work
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
<errpr> does the parameter to a switch always have to be known at compile time?
<andrewrk> errpr, yes, the expressions before `=>` must be comptime known
<andrewrk> that reminds me of an issue I need to file...
<andrewrk> never mind, the thing I thought of is already implemented
<voldyman> it'll be nice to have something like the golang spec for zig (
<voldyman> it makes it easier to learn the language, are anonymous functions supported?
<voldyman> ah nice
<benjikun> good morning everyone
<voldyman> andrewrk: how do i run parser_test.zig against my modified parse.zig file?
<andrewrk> voldyman, I recommend this: make install && bin/zig test ../std/zig/parser_test.zig --test-filter "zig fmt"
<andrewrk> then you can make changes, then press up, enter, in your terminal to do it again
<voldyman> but doesn't this run the tests against the C++ parser?
<andrewrk> no this is testing std/zig/parse.zig
<voldyman> also, i started using ninja with cmake instead which makes the build much faster for me. just had to add `cmake -GNinja ..`
<voldyman> hmm, weird since i clearly broke the `State.StringLiteral` case but the tests are passing, maybe that case is not covered by the tests.
<andrewrk> yeah, replace `make install` with whatever is appropriate. you need that step though to copy the std lib files to the install dir
<andrewrk> it's quite possible and more test coverage would be wonderful
<andrewrk> it should be obvious from looking at parser_test.zig how to add more tests
<andrewrk> or you may have not done the ninja equivalent of `make install`
<voldyman> yup, you caught it. i was doing make install just for stage2 which wasn't enough. thanks!
<andrewrk> please note that you are of course welcome to do whatever workflow changes are convenient for you, but I only provide support for the officially documented way
<andrewrk> otherwise the combinations of possibilities explodes
davr0s has joined #zig
jmiven has quit [Remote host closed the connection]
jmiven has joined #zig
suirad has joined #zig
<suirad> how do i for loop over a range?
<suirad> im only finding examples of iterator for loops
<benjikun> not sure if there is a way to do something like `for (0..10) { }` directly
<benjikun> I normally just do `var i: i8 = 0; while (i < 10) : (i += 1) { }` in zig
<benjikun> suirad: Is that what you meant?
<suirad> Yea i was just wondering if there was a way to do it directly. I would have used the while loop as an alternative, but just wanted to check if there was a more consise way.
<suirad> I appreciate it
<benjikun> anytime :)
jmiven has quit [Quit: co'o]
jmiven has joined #zig
voldyman has quit [Quit: Connection closed for inactivity]
<oconnor0_> How is Zig's memory consumption compared to C (or Rust or whatever)? Maybe it's not a big deal, but "everything" seems to have a pointer to a memory allocator.
jmiven has quit [Quit: co'o]
jmiven has joined #zig
<andrewrk> oconnor0, zig's memory consumption is usually lower than C and Rust since it's difficult to accidentally allocate heap memory
<andrewrk> pointer arguments are passed in registers on most architectures
<benjikun> depends on how you use it ofc, but zig gives you the tools in hand to acquire C-or-lower memory consumption, that's the goal
<andrewrk> if you have a bunch of functions with the same arguments in the same order, a smart code generator will just leave the args in the registers for the respective parameters and there is then no cost whatsoever
<oconnor0_> andrewk, ok, would it be fair to say the explicitness of zig's memory management encourages somewhat different programming styles that end up using less memory?
<andrewrk> yes I think that would be fair to say
<MajorLag> suirad, benjikun: If you find yourself using such a patter frequently, theres a trick you can do: `pub fn zeroToN(comptime n: usize) [n]void { return ([n]void)(undefined); }` => `for(zeroToN(10)) |_,i| { warn("{}\n", i); }`
<oconnor0_> andrewk, interesting, thanks.
<benjikun> MajorLag: oh, nice. didn't think about making a comptime function for that
<MajorLag> benjikun: I think either Hejsil or thejoshwolfe came up with it originally.
<suirad> MajorLang: haha clever
<suirad> *MajorLag
jmiven has quit [Quit: co'o]
jmiven has joined #zig
hoppetosse has joined #zig
<oconnor0_> Is there a recommended place to post "gists" for discussion here instead of larger chunks of code?
<oconnor0_> MajorLag, benjikun, suirad: Here's another iterable range option: I have no idea what tradeoffs it exposes (like does that array stick around at runtime?).
<benjikun> oconnor0_: Andrew uses
<benjikun> the links are pretty short so that's nice
<suirad> i feel like with coroutines, we could probably make range generators
oconnor0__ has joined #zig
oconnor0_ has quit [Ping timeout: 256 seconds]
<oconnor0__> Anyway, I am quite glad that zig has a sane view of compile-time code generation; after half a decade of C++ I still have no idea how to make templates do what I want.
<suirad> wading through template errors after slowly compiling a large c++ project for just makes me want to quit entirely lol.
<benjikun> I'm getting pretty attached to zig already tbh