<zags>
andrewrk: one GPA for the entire app? This is a long-running server app. I was initially thinking of serving up arenas per request, but not sure what's best.
<zags>
A single GPA can presumably get fragmented over time
<andrewrk>
an arena per request is almost certainly in order
<zags>
and each of those backed by a shared GPA?
<andrewrk>
first I would try a single GPA for everything since it's simpler, but could be interesting to try a pool of GPAs that you would use per request as well
<zags>
alright
<andrewrk>
depending on how you have things set up, you may be able to avoid using locks on the per-request GPA
<zags>
requests will be handled from a thread pool, so I'd need locks for the shared gpa case, which is why having a pool of those sounds like a good suggestion (maybe tie it to the request pool)
<marler8997>
I like that you're tracking the revision notes
<marler8997>
missing close paren: " // NEW: propagate error (equivalent to OLD `return error.Bad`"
<marler8997>
the first `afunc` in example.zig is demonstrating the new code with a very uncommon use case, namely, a function that returns an error without triggering a throw
<marler8997>
It might give people a bad impression when they see "return error.bad" and realize it's not triggering an actual error
<marler8997>
we could change afunc to return !void, then show that "return error.Bad" would result in a compile error
<marler8997>
then further down show how you can use errors as values also
<marler8997>
I think you're missing an item in the initial list of changes
<mikdusan>
i think that's the only place where I show that means "return an error _value" . the other cases are "return value-error-union"
<marler8997>
I don't see the new "catch EXPR" being mentioned there
<mikdusan>
`var d = catch doit();`
<marler8997>
I mean in the initial list that currently has 4 items
<marler8997>
after "Primary to this proposal to elevate error flow-control to lexical distinction from regular flow-control:"
<marler8997>
looking at this now, I actually think the whole "catch EXPR" is an optional part of the proposal
<mikdusan>
yes I should add it in the 1-6 list somewhere.
<marler8997>
it might be completely orthogonal to everything else
jukan has joined #zig
<mikdusan>
well if catch isn't there, not sure how to handle cases where that is currently done in code. ie: can't allow `const x = doit();`
<marler8997>
without the "catch EXPR", wouldn't "const x = doit()" just work like today, where "x" is just an error-union?
<mikdusan>
today we have `const x = doit()` which has 2 cases. the common case: error, you want `const x = try doit()`. the rare case: `const x = doit()` <-- both in context of zig status-quo
<mikdusan>
it works today but I don't want it to work:
<mikdusan>
/ NEW: do not let an error-union _easily_ become a value. compile-error: unhandled error
jukan_ has quit [Ping timeout: 264 seconds]
<marler8997>
right I understand the justification, I'm just saying I think it's orthogonal to the other changes
<marler8997>
I mean, you could do everything else in the proposal and not do that, its still an improvement and everything still works
<marler8997>
unless I'm missing something
<marler8997>
if that's the case, we may want to make the separate proposals
<mikdusan>
I did state this but it might not be rich enough "elevate error flow-control to lexical distinction from regular flow-control"
<marler8997>
yeah, it still falls under that umbrella
<marler8997>
so that's a good argument to keep it under this proposal
<mikdusan>
the point infinite monkeys (myself) typing in `const x = doit();` compile. then use x. then get fat error and scratch head. then learn oh that error... need `try doit()`
<marler8997>
right, that's definitely a footgun
<marler8997>
let's make sure we include that footgun somewhere in there, is it in there?
<mikdusan>
i wrote a stage1 mod to trace everytime an error-union is stuffed into a decl. 16 times. for all of zig CI test code on macos platform.
<marler8997>
very nice, that's great data, you immediately catch 16 existing bugs!
<marler8997>
"catch" more bugs with "catch", now we have a slogan! :)
<mikdusan>
they're not bugs. at least the ones I looked over. it's intended usage. but for sure they'd need conversion to `const x = catch doit()`
<marler8997>
do you think we want to mention this as a path forward to solve #2647 in related proposals?
<mikdusan>
that one I've not fully groked yet. mainly because I'm thinking why aren't people balking... doesn't #2647 mean the error-union is sum-type as fat as the largest subtype? I get that it can get pruned as the errorset coerces down... but it is fat until so
<mikdusan>
I'll give it a better read tonight and see about referencing it. do you have initial thoughts on how 7812 might help 2647 ?
<marler8997>
yeah true, it would have to coerce down properly to be reasonable
<marler8997>
it helps because it provide a lexical way to throw an error without it being an error value
<mikdusan>
I suppose too because result-location-semantics fat is relgated to the stack, and not return-copied-to-stack so there is that
<mikdusan>
it's funny how 1 tiny feature (RLS) opens the door to many things
<mikdusan>
tiny written in italics :P
<marler8997>
if we want to mention it, I would say something like "because this proposal provides a lexical way to throw errors, it could be used to solve #2647"
<marler8997>
I think that's a sign of a great proposal, that is solve many issues
<mikdusan>
ah ok are you referring to `return error{ .InvalidChar = index }` that _could_ become w/ #7812, `throw .{ .InvalidChar = index }` ?
<mikdusan>
(just a hot take)
<marler8997>
yup, you got it
<mikdusan>
ok so they are saying it removes need for extra syntax. but it's actually overloading error{} syntax because today it's just error{Thing0,Thing1} like enums. not like anon struct initializers
<mikdusan>
yeah 7812 could help. because `return .{ .field = value };` is totally cleared up too
<mikdusan>
the gist suffers from other things too... like a #1923 issue ref won't resolv until it's an issue comment. the gist isn't associated with a repo like issues are.
<marler8997>
this is what I would say:
<marler8997>
We found multiple cases where a programmer may want to clear the error stack at different places or even not at all. By providing this builtin the programmer is able to have full control of when and to clear the error stack if at all. Note that this builtin does not prevent other features from also being implemented to clear the error stack such as https://github.com/ziglang/zig/issues/1923#issuecomment-461530246
<stilbruch>
would this be the palce to ask basic zig questions? I do alot of development with c, and tonight I am giving zig a try
<daurnimator>
stilbruch: sure
<marler8997>
typo "...programmer is able to have full control of when to clear the error stack if at all"
<stilbruch>
okay just making sure. I am creating an init function for a struct that takes in a file. I want to some integers and arrays from a file into integers and arrays in the struct. Zig is not letting me instantiate the struct and then fill in the values later. What would be the idiomatic way to do this?
<marler8997>
stilbruch, can you provide a link to the code?
<mikdusan>
got the paragraph in.
<marler8997>
*a block of code is worth a thousand words* :)
<stilbruch>
Sure let me put it in pastebin or something
<marler8997>
var cartridge : Cartridge = undefined
<g-w1>
or provide default struct values
<marler8997>
another option is adding default values to your fields
<marler8997>
an yet another option is partial initialization: var cartridge = Cartridge { .magic = undefined, .prg_blocks = 0 };
<marler8997>
in your case, I would set .magic as a default value
<g-w1>
especially if magic is constant, you can just put it in the struct definition itself
<marler8997>
magic: [4]u8 = "\x4e\x45\x53\x1a",
<stilbruch>
Well it's not constant, it can be anything. It just _should_ be the value in the comment. if not it's an error
zags has quit [Ping timeout: 264 seconds]
<g-w1>
then undefined should work the best imo
<marler8997>
^
<stilbruch>
file.read isn't playing nice with my magic array either. Says it needs []u8, not [4]u8. Any way I can cast my array or something?
<marler8997>
prefix with &
<marler8997>
&cartridge.magic
<g-w1>
even in c it would need to be a pointer, but in zig it needs to be a slice (pointer + len)
<marler8997>
yeah, and pointers to arrays (which are "values" in zig) implicitly convert to slices
<stilbruch>
so in c terms magic would be an array (pointer). and file.read wants a slice (pointer to array), which would be like a uint8_t** in c?
<stilbruch>
just making sure I understand
<marler8997>
no
<stilbruch>
well a slice has a length too, so better than uint8_t**
<daurnimator>
stilbruch: C doesn't really have arrays (except for when it does)
<marler8997>
in c terms, a Zig array of 4 bytes is equivalent to struct { char _0; char _1; char _2; char _3};
<marler8997>
a slice is not a pointer to an array
<daurnimator>
stilbruch: btw though, you probably want `file.reader().readBytesNoEof`
<marler8997>
its like a struct like this "struct { char *ptr; size_t len }"
<marler8997>
where ptr is pointing to an "array"
plumm_ has quit [Quit: My Mac Pro has gone to sleep. ZZZzzz…]
<marler8997>
I quoted "array" because I've overloaded the term here
<mikdusan>
marler8997: added binary table (just after code example)
<mikdusan>
oh bad copy. one moment.
<mikdusan>
k I think it's correct now. note the permutations are same for try/throw
<marler8997>
good, I was about to say something :)
<stilbruch>
okay so i'm reading the magic bytes now. If I want to read a u8 from a file, how would I do that? Is there a good way to cast a u8 to a slice, or pass a pointer like I would in c?
<marler8997>
you should put the try/throw case in the same box, on different lines
<daurnimator>
stilbruch: I'm not sure what you mean by "cast a u8 to a slice"
<stilbruch>
uh I'm bad with the terminology. like in c I would just use "read(fd, &cartridge.prg_blocks, 1)"
<marler8997>
self correction, replace
<marler8997>
"By providing this builtin the programmer is able to have full control of when and to clear the error stack if at all."
<marler8997>
with "By providing this builtin, the programmer has full control over when to clear the error stack, if at all."
<marler8997>
The first sentence "Primary to this proposal..." doesn't sound grammatically correct to me
<marler8997>
what about this? "The primary goal of this proposal is to distinguish error control flow lexically rather than have it be triggerd by values at runtime."
<marler8997>
with this proposal, "return x" never triggers error flow control no matter what the value of x is
<mikdusan>
the first part "at runtime" doesn't sound right
<marler8997>
yeah
zags_ has quit [Ping timeout: 256 seconds]
<marler8997>
triggered by runtime values?
<mikdusan>
(btw it was supposed to be "primary to this proposal _is_ to elevate")
<mikdusan>
the big thing is ambiguity. by making it lexically distinct, it removes "what does `return doit();` mean. what does `return try doit();` mean and why do they both work and do exactly the same kind of thing. but not just limited to those cases.
<marler8997>
right, now "return x" always returns, never triggers error flow. Error flow now required either "try" or "throw"
<mikdusan>
the the first part. before:
<mikdusan>
Primary to this proposal is to elevate error flow-control to lexical distinction from regular flow-control:
<mikdusan>
now:
<mikdusan>
The primary goal of this proposal is to distinguish error control-flow from regular flow-control:
<marler8997>
sure
<marler8997>
better
<marler8997>
I think we should include that second sentence to.
<marler8997>
Maybe "With this proposal, "return x" is always regular control flow." ??
<mikdusan>
as part of item #1 or before it
<marler8997>
this definitely makes Zig adhere more to its tenant of "no hidden control flow"
<marler8997>
because before, you wouldn't necessarily know whether "return x" executes errdefers or trigger the caller's catch block
<marler8997>
I dunno, it should be somewhere though :)
<marler8997>
actually ignore me on that
<marler8997>
that's your first bullet
<marler8997>
`return` no longer triggers error flow-control
<mikdusan>
i'm really glad fengb pointed out #2562; while not directly addressing it, #7812's emergent behavior covered that issue. love it when that happens.
<marler8997>
yeah, that one's been bugging me too
<marler8997>
for bullet 2, maybe say "only try and throw trigger error control flow" ??
a_chou has joined #zig
<marler8997>
or "error flow may now only be triggered by 'try' or 'throw'"?
<mikdusan>
2. only `try` and `throw` effect error flow-control
<marler8997>
ok
<mikdusan>
ah but not entirely true. builtin.
<marler8997>
oh right
<marler8997>
so this bullet is really just introducing "throw" to replace the old "return error"
<marler8997>
"introduce the 'throw' operator to trigger error flow control"
<mikdusan>
s/require/use/ ; and `use throw instead of return when pushing....`
<marler8997>
or we could say "replace the current 'return ERROR' mechanism with 'throw ERROR'"?
<marler8997>
mikdusam that works
<mikdusan>
a slight prob is while i get exactly that point, `return <error>` meaning type `error`, the usage of `return` idiomatically includes `return doit();` which now becomes `return try doit();`
<mikdusan>
2. replace current `return error.BadValue;` with `throw error.BadValue;` when pushing an error onto error-stack and leaving function
<mikdusan>
that's pretty clear?
<marler8997>
sure, I don't think you need to explain what it's doing, but probably doesn't hurt
<mikdusan>
ah yup
<marler8997>
actually if you're going to explain, I would also say it's triggering error flow-control
<stilbruch>
ah okay that makes sense. thanks for the help, I appreciate it
<mikdusan>
marler8997: updated
<marler8997>
reading
<mikdusan>
maybe I should move related-proposals to bottom of doc, but before changelog.
cole-h has joined #zig
<marler8997>
I think the examples you added at least should be moved to bottom
<marler8997>
maybe we should move bullet 5 to secondary?
<mikdusan>
yup done
<marler8997>
in regards to the first question about using "try error.Foo"
<mikdusan>
ah so for gist I changed the primary "doc" out to be a simple 1-liner. and have been using the comment for iterating this doc. The reason was because the primary in gist is too big a font and irks me. but I think that's where you can make line-comments. lol
<marler8997>
huh?
<marler8997>
is there a new link?
<mikdusan>
no no earlier you mentioned something about not being able to comment on lines
<mikdusan>
and I chalked it up to no feature support in github. It's because gists have like "files" but I put this doc into a comment
<mikdusan>
and it's the files that show diffs
<marler8997>
oh
<mikdusan>
I'll do it the right way next round :P
<marler8997>
got it
<marler8997>
ok, in regards to the first QA question
<marler8997>
let's assume we never added the "throw keyword"
<marler8997>
then I believe that "try error.Foo" would still work the same way, it's not actually an overloaded use of try, is that correct?
<mikdusan>
hmm no I just tried master and it errors out with `expecting error-union got error` or somesuch
<marler8997>
oh wait not, try expects an error union, it doesn't work with just an error value
<marler8997>
I would also mention another point about that
<marler8997>
if we overloaded "try", then it looks like an error may or may not be thrown, you'd have to know the value to know for sure
<marler8997>
by using a different keyword, you immediately know that an error is always being thrown, no matter what the value is
<mikdusan>
oh right. try specifically means maybe throw
<marler8997>
exactly
<mikdusan>
#define MAYBE_THROW try
<mikdusan>
oh busted
<marler8997>
I think that's the main argument for not overloading try
<marler8997>
lol
<mikdusan>
The `try` keyword means "maybe throw" and overloading it to accept expressions of type `error` would change that use meaning to `always throw`.
<mikdusan>
A. The `try` keyword means "maybe throw" and overloading it to accept expressions of type `error` would change that use to mean `always throw`.
<marler8997>
... This means the semantics of try would depend on the value of the expression after it, its no longer clear what "try x" will do
<noam>
andrewrk: On a more positive note, I think I have an idea on how you can reduce memory usage by at least another five bytes per node.
<noam>
I'm still experimenting with the idea for myself, but basically: instead of lhs/rhs and extra_data, you store an (untagged!) union of nodes and indices
<noam>
every entry contains, instead of lhs and rhs, the number of children nodes. Then, that number of entries following it are indices
<noam>
With n=0, that's 4 fewer bytes (no lhs, no rhs). With n=1, it's the same size. With n=2, you're four bytes higher - but with n=3+, you drop the lhs, start, end, and index into extra_data, and replace it with nkids plus args
<noam>
With a few other changes, the added overhead actually gets dropped, and you get it so that you save bytes for all values of n
<noam>
(changes which are unblocked by this)
<mikdusan>
marler8997: ok updated - MOVED to top of gist (the file). reload gist
<mikdusan>
and now the Q.A. is rendering different. what the.
<mikdusan>
fixed.
<noam>
Writing up proposal now :)
<marler8997>
very nice, one more comment
<marler8997>
bullet 3
<marler8997>
overloading catch isn't really the point, more the mechanism we chose
<marler8997>
the point is more about inadvertently missing errors
<mikdusan>
ah yeah it currently reads as a changelog lool
<mikdusan>
here is how i commented that code:
<mikdusan>
/ NEW: do not let an error-union _easily_ become a value. compile-error: unhandled error
<marler8997>
require explicit syntax to capture an error-union as a value?
<mikdusan>
i did want to shy away from "capture" because of the postfix idiom `|err|`
<mikdusan>
but it is qualified as error-union so it is correct
<marler8997>
require error-union values to be caught explicitly?
<mikdusan>
i like your first better
<marler8997>
what case is bullet 4 for?
<marler8997>
is that for "return doit()" must now be "return try doit()"?
<mikdusan>
/ NEW: do not let an error-union _easily_ become a value. compile-error: unhandled error
<mikdusan>
`var c = doit();`
<mikdusan>
it's the counterpart to prefix-catch
<marler8997>
so it's saying the same thing, just in a different way? do we need it then?
<mikdusan>
yeah now replace that statement with `_ = try foo();`
<mikdusan>
so if you don't ignore it, the answer is: it's a throw
<marler8997>
hmm, that's weird
<marler8997>
it also means there's no way to actually return a value from this function
<mikdusan>
if you ignore it ala `_ =` you get a funky error maybe appearing because it wants attention but for no other good reason :P
<mikdusan>
yes unless you wrap/box it in a struct or something
<marler8997>
yeah it's a really weird mix between how Zig handles error vs values
<marler8997>
I think the stronger issue this solves is that currently you can't tell lexically whether error flow-control is triggered "return x" may or may not
wfchandler has joined #zig
<marler8997>
that's a more general description of the error.Bad example we just looked at
semarie has quit [Ping timeout: 240 seconds]
<marler8997>
for the exact same reason we though it was better not to overload try, we are moving the "return" overload
<mikdusan>
"maybe" control-flow
<mikdusan>
err-control-flow
<mikdusan>
so yeah return is currently "maybe error control-flow or regular control-flow"
<marler8997>
with proposal: try = "maybe throw", return = "no throw", throw = "throw"
<marler8997>
So maybe in the proposal we say something like. "In Zig the "return" statement is overloaded to return both values and errors with error flow-control. This proposal simplifies "return" to only handle values, and adds a new "throw" keyword to handle errors. This has the advantage that one can always immediately tell whether a return/throw statement will return a value or trigger an error."
semarie has joined #zig
<marler8997>
Wording could probably be improved, but something like that maybe
wfchandler has quit [Quit: leaving]
<mikdusan>
on that, note #2 can probably be nuked. the 2 big parts are #1 and #3. #2 is a detail of _how_ we accomplish #1
falseblah has joined #zig
<marler8997>
yeah, but it's an important detail, maybe important enough to be included in it's own bullet (or mentioned in the first bullet)?
<mikdusan>
either way works for me.
jukan has quit [Ping timeout: 264 seconds]
waleee-cl has quit [Quit: Connection closed for inactivity]
philtor has quit [Ping timeout: 246 seconds]
<andrewrk>
noam, n=3+ is very rare, it's better to optimize for n=2
mmohammadi9812 has joined #zig
decentpenguin has quit [Read error: Connection reset by peer]
decentpenguin has joined #zig
cole-h has quit [Ping timeout: 272 seconds]
jukan has joined #zig
jukan has quit [Ping timeout: 256 seconds]
osa1 has joined #zig
jukan has joined #zig
semarie has quit [Quit: WeeChat 3.0]
jukan has quit [Ping timeout: 256 seconds]
mmohammadi9812 has quit [Ping timeout: 265 seconds]
semarie has joined #zig
Stephanie has joined #zig
Stephie has quit [Ping timeout: 258 seconds]
kragacles has quit [Ping timeout: 258 seconds]
ex_nihilo has joined #zig
kragacles has joined #zig
kameliya[m] has quit [*.net *.split]
Nypsie[m] has quit [*.net *.split]
larme has quit [*.net *.split]
CommunistWolf has quit [*.net *.split]
decentpenguin has quit [*.net *.split]
gazler has quit [*.net *.split]
sebonirc has quit [*.net *.split]
noam has quit [*.net *.split]
sawzall has quit [*.net *.split]
[RMS] has quit [*.net *.split]
techtirade has quit [*.net *.split]
mmurd has quit [*.net *.split]
Amun_Ra has quit [*.net *.split]
hspak has quit [*.net *.split]
neptunepunk has quit [*.net *.split]
blueberrypie has quit [*.net *.split]
rinfo has quit [*.net *.split]
Snektron has quit [*.net *.split]
ky0ko has quit [*.net *.split]
texno has quit [*.net *.split]
eddyb[legacy] has quit [*.net *.split]
lohengrin has quit [*.net *.split]
dreda has quit [*.net *.split]
teratorn has quit [*.net *.split]
Ekho has quit [*.net *.split]
procnto has quit [*.net *.split]
nikki93 has quit [*.net *.split]
mschwaig has quit [*.net *.split]
Flaminator has quit [*.net *.split]
albertito has quit [*.net *.split]
Gliptic has quit [*.net *.split]
bens has quit [*.net *.split]
bitmapper has quit [*.net *.split]
vazub[m] has quit [*.net *.split]
adsr has quit [*.net *.split]
pjz has quit [*.net *.split]
viashimo has quit [*.net *.split]
lemmi has quit [*.net *.split]
KoljaKube has quit [*.net *.split]
jaredmm has quit [*.net *.split]
johnLate has quit [*.net *.split]
kameliya[m] has joined #zig
larme has joined #zig
Nypsie[m] has joined #zig
CommunistWolf has joined #zig
ky0ko has joined #zig
mschwaig has joined #zig
texno has joined #zig
dreda has joined #zig
teratorn has joined #zig
bens has joined #zig
lohengrin has joined #zig
Gliptic has joined #zig
albertito has joined #zig
eddyb[legacy] has joined #zig
procnto has joined #zig
Flaminator has joined #zig
nikki93 has joined #zig
Ekho has joined #zig
decentpenguin has joined #zig
sebonirc has joined #zig
gazler has joined #zig
sawzall has joined #zig
noam has joined #zig
mmurd has joined #zig
[RMS] has joined #zig
hspak has joined #zig
Amun_Ra has joined #zig
techtirade has joined #zig
neptunepunk has joined #zig
rinfo has joined #zig
blueberrypie has joined #zig
hamoko[m] has quit [Ping timeout: 268 seconds]
pafmaf[m] has quit [Ping timeout: 268 seconds]
kameliya[m] has quit [Ping timeout: 258 seconds]
Nypsie[m] has quit [Ping timeout: 258 seconds]
siraben has quit [Ping timeout: 265 seconds]
ugla has quit [Ping timeout: 265 seconds]
josias has quit [Ping timeout: 265 seconds]
Ekho has quit [Max SendQ exceeded]
euantorano has quit [Ping timeout: 264 seconds]
mtiljeset[m] has quit [Ping timeout: 240 seconds]
BitPuffin has quit [Ping timeout: 268 seconds]
fengb has quit [Ping timeout: 268 seconds]
ifreund_ has quit [Ping timeout: 268 seconds]
euantorano has joined #zig
Ekho has joined #zig
johnLate has joined #zig
lemmi has joined #zig
bitmapper has joined #zig
adsr has joined #zig
viashimo has joined #zig
KoljaKube has joined #zig
pjz has joined #zig
jaredmm has joined #zig
ugla has joined #zig
pafmaf[m] has joined #zig
vazub[m] has joined #zig
mtiljeset[m] has joined #zig
fengb has joined #zig
hamoko[m] has joined #zig
kameliya[m] has joined #zig
Nypsie[m] has joined #zig
ifreund_ has joined #zig
ugla has quit [Ping timeout: 268 seconds]
fengb has quit [Ping timeout: 240 seconds]
pafmaf[m] has quit [Ping timeout: 240 seconds]
ifreund_ has quit [Ping timeout: 265 seconds]
vazub[m] has quit [Ping timeout: 244 seconds]
mtiljeset[m] has quit [Ping timeout: 268 seconds]
sord937 has joined #zig
hamoko[m] has quit [Ping timeout: 240 seconds]
Nypsie[m] has quit [Ping timeout: 258 seconds]
kameliya[m] has quit [Ping timeout: 265 seconds]
sord937 has quit [Remote host closed the connection]
sord937 has joined #zig
wilsonk__ has joined #zig
sord937 has quit [Quit: sord937]
hnOsmium0001 has quit [Quit: Connection closed for inactivity]
a_chou has quit [Remote host closed the connection]
jukan has joined #zig
xackus has joined #zig
Snektron has joined #zig
BitPuffin has joined #zig
sord937 has joined #zig
siraben has joined #zig
sord937 has quit [Client Quit]
jukan has quit [Ping timeout: 240 seconds]
ifreund_ has joined #zig
ugla has joined #zig
fengb has joined #zig
pafmaf[m] has joined #zig
vazub[m] has joined #zig
dddddd has quit [Ping timeout: 256 seconds]
dddddd has joined #zig
mtiljeset[m] has joined #zig
dddddd has quit [Ping timeout: 256 seconds]
hamoko[m] has joined #zig
Nypsie[m] has joined #zig
<ky0ko>
i've been thinking the past few days about how i would write a forth implementation in zig, and have come to the conclusion that i have absolutely no clue what that would look like in the slightest. which is a sign to me that i should try and write one
kameliya[m] has joined #zig
emptee has joined #zig
tane has joined #zig
dddddd has joined #zig
dddddd has quit [Excess Flood]
dddddd has joined #zig
xackus has quit [Read error: Connection reset by peer]
xackus_ has joined #zig
dddddd has quit [Ping timeout: 256 seconds]
dddddd has joined #zig
dddddd has quit [Ping timeout: 256 seconds]
dddddd has joined #zig
zags has joined #zig
knebulae has quit [Quit: Leaving]
zags has quit [Ping timeout: 240 seconds]
leon-p has joined #zig
dddddd has quit [Ping timeout: 256 seconds]
vegai has joined #zig
knebulae has joined #zig
zags has joined #zig
jukan has joined #zig
<ifreund>
hmm, you can't use multline string literals with extern, this seems inconsistent
<ifreund>
noam: I think it's cool that you can do that. I don't know it if would yield better performance in the end though. I think andrew's probably right about n=2 being the most common
<ifreund>
someone should totatally collect some actual data on that though, using e.g the std as an example codebase
jukan has quit [Ping timeout: 240 seconds]
xackus_ has quit [Ping timeout: 240 seconds]
jokoon has joined #zig
dddddd has joined #zig
dyeplexer has joined #zig
tjammer has joined #zig
<tane>
ok it seems like `shrink` => `shrinkAndFree` was done at a lot of places due to do rename, but `shrinkRetainingCapacity` would be the right choice most of the time
xackus_ has joined #zig
<tane>
some of these are up to discussion though, like json.Parser.reset, currently freeing the buffer completely. I'd argue that retaining the capacity would be fine here, because otherwise one could just init a new parser instead of resetting it.
dddddd has quit [Ping timeout: 256 seconds]
jukan has joined #zig
dddddd has joined #zig
zags has quit [Ping timeout: 256 seconds]
zags has joined #zig
zags has quit [Ping timeout: 272 seconds]
tjammer[m] has joined #zig
tjammer has quit [Quit: terminated!]
jukan has quit [Ping timeout: 240 seconds]
midgard has quit [Read error: Connection reset by peer]
midgard has joined #zig
leon-p has quit [Ping timeout: 264 seconds]
leon-p has joined #zig
xackus_ has quit [Ping timeout: 264 seconds]
cole-h has joined #zig
ex_nihilo has quit [Quit: Leaving]
<noam>
ifreund: I didn't contest that tehy're the most common - they have to be more than just more common for it to not be a net gain, they have to be an order of *magnitude* more common
<noam>
Note also that it optimizes for n in [0,1] more, as well
mmohammadi9812 has joined #zig
xackus_ has joined #zig
zags has joined #zig
<ifreund>
noam: I think this needs science
<noam>
For sure!
<noam>
I will note that the more extreme variant I'm using actually wins even at n=2
<noam>
But I also don't think that's a good fit for stage2, so /shrug
<noam>
(It makes use of relative indices, which means you add the index at which the index of a child is found to said index to find the index of the child... that came out more confusing than it really is)
<ifreund>
and so you are limited to math.maxInt(u16) children right?
<ifreund>
we're already limiting file size to math.maxInt(u32) bytes...
rowbee\ has quit [Remote host closed the connection]
jukan has joined #zig
rowbee has joined #zig
<noam>
No, I have a way around that :P
<noam>
I'm using an *i16*, and it's *relative* - the limitation is that when referring to a node further than 32K nodes away (which is a *lot*), you need an extra six bytes
<noam>
So mine is affected by node locality instead of node children count
<ifreund>
that does sound funky... I though your compiler was supposed to be simpler :P
<noam>
It is :)
<justin_smith>
ky0ko left, but there are some excellent examples on line of "forth in only N bytes of assembly", surely the zig code would be smaller
<noam>
Then handwritten asm?
<noam>
I doubt it.
<justin_smith>
noam: the code base itself, not the executable size, sorry
<noam>
Ohhhh, okay, no that's my bad
<noam>
I don't think that's a good way to go about it though
<noam>
Porting asm to Zig won't result in high-quality Zig; idiomatic asm and idiomatic zig are diametrically opposed.
<justin_smith>
noam: the reason I suggested it was that it's shocking how small a full forth impl is in assembly (if you are used to what "normal" assembly looks like), but yeah, I wouldn't neccessarly translate it line for line...
<justin_smith>
that's a fair point
<noam>
Yeah, forth is awesoem
<noam>
awesome*
<justin_smith>
it's hard to beat when your main concern is as few bytes in RAM as possible
<noam>
ifreund: you do have a point though, but not for the reason you think -I do think my way remains simpler than stage2, but I think I can make it even simpler in exchange for a relatively minor hit to performacne...
<noam>
Plus, without hard numbers indicating that this is faster, it's entirely reasonable to assume that the arithmetic on lookups would counteract the saved memory vs the 8+4N scheme
<noam>
if the goal was more about CPU than RAM, that would be enough reason on its own
n0tekky has joined #zig
<noam>
ifreund: yeah, I'm probably going to use the 8+4N one instead
<noam>
Even if Andrew is right that it ends up being worse due to a preponderance of n=2 nodes, it's definitely simpler both than the 6+2N scheme and the extra_data scheme
<noam>
Thanks!
<ifreund>
your welcome :D
<ifreund>
*you're
<ifreund>
noam: ok here are some very rough numbers: { 766932, 89277, 264456, 123193 }
<ifreund>
that is n=0,1,2,>2
cole-h has quit [Ping timeout: 272 seconds]
<zags>
bleargh, how do I debug tests? The test crashes, but if I convert it to main it no longer crashes so I can't debug it haha
<ifreund>
for parsing all of lib/std with the currently ast-memory-layout branch
<ifreund>
zags: when the test crashes it should log the command that was run
<ifreund>
copy and paste that command to your gdb invocation
<zags>
oh i see it logged - no gdb in sight, but i'll do the same with lldb
<zags>
thanks
<zags>
a stable test exe would be nice so I can put it into vscode's task file
<ifreund>
not sure if there's an easy way to do that, maybe -femit-bin=foo works with zig test
<zags>
oh yeah, that solves it!
<ifreund>
andrewrk: looks like we've got ~3x as many n=0 nodes as n=2 nodes... I think noam's proposal is worth considering
<ifreund>
I may have made minor errors in the Node.Tag => n mapping, I did it pretty fast
karrick has joined #zig
xackus_ has quit [Ping timeout: 240 seconds]
jukan has quit [Ping timeout: 240 seconds]
plumm has joined #zig
<zags>
Had a hard-to-track-down bug which I partially blame on Zigs nameing of struct declarations :) var counter: u64 = 0; makes it look like it's per instance. I know it's not, but it's kinda easy to mix up. I think a static keyword would make sense.
<zags>
unless of course this is the first time you hear of such a bug haha
<marler8997>
zags, if nothing else changed, that would mean putting static on literally everything because files are also structs
<zags>
implicit structs, so they could be implicitly static?
<zags>
anyway, "var' makes it look like per-instance data
<marler8997>
there was a proposal for that, it got rejected maybe I can find it
<zags>
it totally tripped me up when I was learning zig because the docs do a bad job pointing it out, then i learned it, and i still made a bug
<zags>
not a problem if you're doing zig 100% of the time, but certainly a footgun when jumping between langauges
<zags>
and footguns should be pink :)
<marler8997>
in your case, how did this become a footgun?
<marler8997>
since you access instance/global variables differently, how did you mistake it for an instance variable?
<zags>
marler8997: because the update happens behind accessors
<marler8997>
zags, using Shared.x is an interesting idea
<marler8997>
but maybe that is just moving the problem?
<marler8997>
because accessing Shared has the same issue?
<zags>
marler8997: you mean not using self. two places? That's an obvious risk when you write the two functions at the same time. If you make the mistake in the first function, you're likely to make it in the next.
<zags>
Look at the example. var x makes it look like an instance variable due to naming
<marler8997>
I mean, you have to both mistakenly declare the variable as a global instead of a field, and also forget to access it through "self.foo"
<zags>
then you write x +=1 and return x
<caolanm>
ugla: sorry, that's a bit too easy. have you got anything more difficult?
<caolanm>
:P
<ugla>
:D
<marler8997>
so that's 2 mistakes that have to work in concert simultaneously
<zags>
the second mistake easily follows
<marler8997>
sure I can see that opinion, my point was just that it's harder than having to make just one mistake
<zags>
look, if you're in the frame of mind that "var x" makes an instance variable, then I'm kinda making only one mistake
<zags>
I think you can see that
<marler8997>
of course
<marler8997>
that's the first mistake
ismaell has left #zig [#zig]
<zags>
a total non-issue if I was doing zig all day long haha
<marler8997>
yeah I can see how this would be an issue if you're working with other language
<zags>
I see how i'm making two mistakes, but I'm also interned that var means not using self, so ugh
<marler8997>
you're more likely to make both mistakes
<zags>
yeah, and "var" makes it easier to do so
<zags>
marler8997: could you elaborate on why Shared.x moves the problem? If you HAD to use self.x or Shared.x, for fields and decls respectively
<marler8997>
could you make the same mistake with Shared?
<marler8997>
I suppose you would say no because it is "const" instead of "var"? Is that right?
<zags>
not sure, if i'm forced to write TypeName.decl, I won't mistake it for an instance variable
<zags>
hm, it's not const
<marler8997>
But could TypeName also be an instance variable?
<marler8997>
you see what I'm saying, TypeName is also inside struct, everything in Zig is inside a struct
<zags>
That's the enclosing type
<zags>
const Shared = struct { ... Shared.x }
<zags>
My point is, if I'm forced to access decl via enclosing type name, I won't make the mistake
<zags>
I'm not nearly confident in the language to write a proposal yet, feel free :D
<zags>
How do you access the global from within a struct function?
<zags>
since @This refers to the innermost type
<marler8997>
not sure what you mean by "struct function"
<marler8997>
oh
<marler8997>
a nested function
<marler8997>
You would have to declare const Self = @This(); at the top of your file
<noam>
ifreund: note also that even just the last two numbers are enough.
<noam>
264456 vs 123193
<zags>
marler8997: that works, love it
<noam>
My proposal saves *13 bytes* per n>2 node.
<zags>
explicit and overall awesome and removes my footgun :D
<noam>
and it costs *1* per n=2 node.
<noam>
123193 * 13 - 264456
<noam>
That's already >1.3MB
waleee-cl has joined #zig
<marler8997>
I don't remember seeing this proposal before, but it's possible it has been proposed, anyone that's lurking know?
<noam>
Hm?
<noam>
Toss in the n=0 and n=1 nodes and that's probably at least 3MB
<noam>
at n=0, we save five bytes - oh yeah, that's 3.5MB just from the terminal nodes.
<noam>
at n=1, we save 3 bytes - that's another 240KB
<noam>
we then lose 300KB to binary nodes
<noam>
and gain another 1.6MB or so from >2-ary node
<noam>
So a rough estimate of 5MB saved?
<zags>
marler8997: Shared.x already works, so I'll use that as an idiom for now, would be nice to have it enforced for sure
<marler8997>
ok, I'm working on a simple proposal
<zags>
awesome, thank you so much
<justin_smith>
in case anyone finds it useful, I made a small function that takes the same args as debug.print, but uses the resulting string to do a formatted failure message (for unit tests I always want to know what the unexpected values actually were) http://ix.io/2Pjc
dyeplexer has quit [Remote host closed the connection]
<noam>
andrewrk: can we get RAM usage numbers for the AST rework, as well, not just CPU? Seems like those would be useful, given that it's gaining performance by lowering RAM
<marler8997>
justin_smith, isn't that what std.debug.panic does?
<zags>
marler8997: https://github.com/ziglang/zig/issues/2859 looks similar, but no realworld footgun motivation so it was rejected. Doesn't seem to preclude opening a new proposal.
<justin_smith>
marler8997: d'oh, of course that already existed
<marler8997>
lol
<noam>
Ah whoops, my calculation there was a bit off; I was still thinking in terms of the smaller scheme
<noam>
Posting actual numbers in the PR
<justin_smith>
marler8997: OK, it was worth checking out that namespace, std.debug.dumpCurrentStackTrace(@returnAddress()) lets me create a dump that makes my editor jump to the failed test instead of the test failure code
<justin_smith>
huge quality of life improvement there
Akuli has joined #zig
<noam>
Huh, that estimate was actually pretty accurate ;P
<noam>
We actually lose 0.8MB to binary nodes, not 0.3, and we only gain 90KB from unaries, not 240 - but it's actually 3.8 saved on terminals, not 3.5, and I was rounding anyways :P
<ifreund>
marler8997: I think it needs to affect const decls as well, a const pointer to mutable data is not at all uncommon
<ifreund>
would also be much more consistent
<noam>
ifreund: in theory, I could separate children from nodes?
<noam>
But there's no really good way to that
<noam>
do
<marler8997>
ifreund, yeah that's a good point, but, that would be a much bigger change
<noam>
ifreund: also, even with this, we're still wasting 4N bytes, technically...
<marler8997>
having to us a type qualifier for every single constant...not so sure about the tradeoff on that one
<ifreund>
marler8997: I don't think the proposal is worth it without applying to const decls as well
<noam>
(because we're storing indices)
<noam>
Clever solutions can definitely reduce it further, but I personally don't want to use them
<marler8997>
Maybe there's a way to tell if a variable has any mutabaility?
<ifreund>
marler8997: even if there was, that sounds too complex IMO
<noam>
ifreund: mind pulling up numbers for zls as the one last test? I think it's probably one of the most widely used zig projects, so it should also be a useful number
<ifreund>
noam: { 10859, 7329, 8338, 2321 }
<noam>
Thansk!
<noam>
Thanks*
<marler8997>
ifreund, I've added a "Varition" section to describe that
<marler8997>
and ifreund, in your variation, what kind of consts do you think should be qualified?
<marler8997>
obviously const Types would not be correct?
<ifreund>
hrm, yeah you're right that does get ugly too
decentpe- has joined #zig
decentpenguin has quit [Ping timeout: 240 seconds]
decentpe- is now known as decentpenguin
<marler8997>
well, I suppose at some point something has to be unqualified
<marler8997>
technically @This() at the top level is still just a type
jukan has joined #zig
<ifreund>
yeah
karrick has quit [Quit: Connection closed for inactivity]
mmohammadi9812 has joined #zig
mmohammadi_9812 has quit [Ping timeout: 256 seconds]
<zags>
weird, my type has a deinit() which in turn calls arraylist.deinit(), but that fails because when ArrayList calls free->shrinkBytes, resizeFn is suddenly a null pointer
mmohammadi9812 has quit [Max SendQ exceeded]
mmohammadi9812 has joined #zig
plumm has joined #zig
<ifreund>
zags: sounds like you copied your allocator interface out of it's parent struct
<zags>
hm, can't say I see where I'm doing the copy, everything is passed by ptr
ur5us_ has quit [Ping timeout: 264 seconds]
<ifreund>
noam: I don't see how you get 8+4n. there's tag (1) main_token (4) num_children (4) in the SoA and then in the []u32 one index in to the SoA (4) + n child indexes (4n)
<ifreund>
that's 13+4n, so what am I missing?
<noam>
For stage2, you mean?
<ifreund>
yeah
* noam
repops open issue
<noam>
Just from your comment: it drops the "one index"
<zags>
allocator gets copied, &instance.arena.allocator points to something teared off
<zags>
right?
<ifreund>
zags: yep
<noam>
ifreund: Hmm, I think my proposal only works if you stop using a SoA, so it might not be wanted by Zig. /shrug
<zags>
ifreund: dang, so what's the workaround here?
<noam>
There might be a way to match it, but I've already spent enough time thinking about this
<noam>
Though 13+4N is still an improvement over what you have now, to be clear
<noam>
:(
<noam>
Not nearly as big of one, though
<noam>
ifreund: note my original proposal in that thread does say to remove the SoA
<ifreund>
ok, how does that help though?
<noam>
Without the SoA, if you have one giant array of nodes ([]u32, some entries are nodes, some are indices), you don't need an index of the first child
<noam>
The indices are stored immediately after the node
<ifreund>
zags: in that case specifically, I'd just use ArrayListUnmanaged probably
<ifreund>
you could also make the signature fn init(self: *@This(), ally: *Allocator) void {}
<noam>
and so on
<zags>
ifreund: yeah, that makes the call sites weird though
<ifreund>
noam: but how you get from child_1 to the tag of child one?
<noam>
ifreund: it's part of it
<noam>
child_1 is the node
<noam>
it's 8 bytes
<ifreund>
so it's not a []u32 then I guess
<noam>
I'm using a u16 for tag, and a u16 for kid_count, with a u32 for token index
<noam>
It is
<noam>
Well, it's u32-aligned, and it's a single contiguous block of memory
<noam>
Entries are either 64-bit nodes, or 32-bit indices
<ifreund>
ok yeah
<noam>
You could keep u8 tag and have u24 for kid_count
<noam>
Though I find it unlikely it would make a practical difference either way
<zags>
ifreund: what's the "Unmanaged" in ArrayListUnmanaged?
<ifreund>
zags: it doesn't store an allocator pointer
<zags>
oh i see, gotcha, gotta pass it
<noam>
Why have both managed and unmanaged?
<zags>
in this case, to avoid the friggin unpinning footgun
<ifreund>
noam: managed can be more convient in some cases, but I'm starting to think that the "unmanaged" api should be the default
karrick has joined #zig
<mikdusan>
yeah do-less == default
<ifreund>
the static init is quite nice, and it's certainly the better choice in nested data structures
<ifreund>
noam: 13 + 4n is worse than what have currently, which is just straight 13 for n <=2
<noam>
ifreund: sure, but 13 + 4n still saves 8 bytes for n>2
<noam>
But... no.
<noam>
Yeah, the binary nodes then match the n>2 nodes, and the terminal ones no longer help
* noam
shrugs
<noam>
You can probably figure out a way to improve it further still, at least
<noam>
*If* you ditch the SoA, you can get 8 + 4N. That remains true.
<noam>
The question is whether you want to
<ifreund>
I just want what's faster, which is a much harder question to answer
<zags>
ifreund: ArrayListUnmanaged solved all my sorrows, thanks a bunch, you saved me a lot of time
<ifreund>
zags: no problem!
<noam>
I might actually use a SoA just for tokens
<noam>
That'll let me get those down to five bytes while maintaining 8+4N nodes
<noam>
But that also means 8-bit tags instead of 16-bit... meh, it's good enough now
<zags>
ifreund: quick follow-up on https://pastebin.com/raw/zjhct5EE if and when you have time. I thought the problem was that "instance" got copied because it returns a value. But doesn't Zig guarantee that no copy occurs here? The caller allocates. So how come the &instance.arena.allocator pointer gets invalidated?
<ifreund>
zags: zig currently only guarentees that there is no copy if you return the struct literal directly (i.e. return Foo{ .a = 42 }; )
<zags>
interesting
<zags>
subtlety increased by 95%
<ifreund>
I think there's an accepted proposal to allow getting a pointer to the result location or something like that
<zags>
noice
kenran has joined #zig
kenran has quit [Client Quit]
kenran has joined #zig
<daurnimator>
ifreund: I thought it guarnteed no copy in other circumstances too
<ifreund>
daurnimator: thanks for the link, that's not implemented yet though afaik
<daurnimator>
ifreund: true
plumm has quit [Quit: My Mac Pro has gone to sleep. ZZZzzz…]
plumm has joined #zig
g-w1 has quit [Quit: WeeChat 2.7.1]
jacob3 has joined #zig
jacob3 is now known as g-w1
craigo has quit [Ping timeout: 272 seconds]
mmohammadi9812 has quit [Read error: Connection reset by peer]
<andrewrk>
ifreund, thanks for crunching the numbers, this is useful data
<andrewrk>
noam, your math is wrong for n=3+. it's 13 + 4*(n - 1) e.g. 9 + 4n
<noam>
Hm? You have lhs for one child, rhs as index, then start and end, and all the other children
<noam>
9 + 12 (index,start,end) + 4N
<andrewrk>
I see, you are talking about ranges
<noam>
So index into extra_data, plus two indices in extra_data
<noam>
Yeah
<noam>
You could make the extra_data entries slices, effectively
<noam>
Instead of start and end, just have length followed immediately be entries
<noam>
That's 4 bytes shaved off per n>2 node
<noam>
by*
<noam>
That'd still be nearly 500K saved for stdlib full, and 60K for stage2
hnOsmium0001 has joined #zig
zags has quit [Ping timeout: 240 seconds]
plumm has quit [Quit: My Mac Pro has gone to sleep. ZZZzzz…]
<ifreund>
that's a neat trick that wouldn't be as invasive of a change
<andrewrk>
I originally looked into having the children just be directly after the parents in the node array, but that was too hard to implement in the parser
<andrewrk>
if there's a middle ground that is reasonable to implement in the parser, I'm for it
<andrewrk>
as for the other proposal, if I understand correctly, it is to remove 4 bytes from node data, and merge it with extra_data
<noam>
andrewrk: actually, it's not
<noam>
It's to remove 8 bytes from extra_data in favor of a different four
<noam>
Currently, you specify start and end. Instead, the start *is* the rhs from the node, and you specify *length*. Then, the children follow the *length* in *extra_data*
<noam>
andrewrk: you said you tried having children immediately follow parents in the node array - do you mean indices, or the children themselves?
<andrewrk>
the children themselves
<noam>
Oh okay
<noam>
I'm doing indices, so I was about to ask what the issue was
<noam>
Having the children follow... yeah that sounds awful to implement
<Gliptic>
I've been trying to get that working in other parsers, but seems it always requires either designing the language for it or reparsing things
<noam>
Impossible for me, actually, since my tree is actually able to be cyclic
<noam>
My tree allows a child to have multiple parents, effectively, so that's not at all an option for me
<noam>
There's also the case of, for instance, nested expressions
<noam>
((a) + (b * 3))
<noam>
The 3 there should follow the b - but if that's the case, then the "b*3" cannot properly follow the *a*
<ifreund>
andrewrk: noam's suggestion to replace SubRange is good I think and not very invasive, I think I'll try it tomorrow
<noam>
...in less confusing terms, you can't have a child's nodes follow the child or they'll be mistaken as its siblings
<noam>
:)
<andrewrk>
ifreund, sounds good
<noam>
I'm using 6-byte tokens now, with 8+4N byte nodes :)
<noam>
I like how our ideas are feeding into each other :)
<ifreund>
Here's a (possibly dumb) idea: we could get rid of all the nodes that have no children and a single token by making lhs/rhs and extra_data use i32s, with postive refering to nodes and negative refering to tokens
<andrewrk>
essentially what we're doing here is using a u31 for the index and a bit to determine whether it is token or node index
<ifreund>
yeah
<andrewrk>
given that we have extremely consistent 8:1 source byte to token ratio, and 2:1 token to AST node ratio, I think we can afford that bit
<ifreund>
and I think u31 is fine for the supportted max source bytes juding by the 8:1 bytes:tokens ratio described in parse()
<ifreund>
jinx :P
<andrewrk>
ha!
<andrewrk>
if we want to be really paranoid we could even put a check in after tokenizing to make sure len fits in u31
<ifreund>
yeah, though I don't think that should ever happen in practice
<noam>
Just use a u31?
<ifreund>
the downside to this would be more branchy code
<andrewrk>
I'm interested in bringing this branch to fruition
<andrewrk>
uhh git branch I mean, sorry
<ifreund>
the upside would be potentially large savings on the total number of nodes
<ifreund>
yeah it would be good to have it done, we can always iterate more on the design later
<andrewrk>
even this lhs,rhs thing is progress from master branch
<andrewrk>
I think future improvements will be slightly less invasive for a few reasons
zags has joined #zig
jukan has joined #zig
karrick has quit [Quit: Connection closed for inactivity]
emptee has quit [Quit: Konversation terminated!]
<marler8997>
andrewrk, what can I do to help make progress on issue #6044 and/or my PR #7664
<marler8997>
one thing I think I've realized since is I think #7664 isn't correct because it requires all paths to be resolved to absolute paths first, and I don't think it's doing that
<g-w1>
while we are on the topic of optimising memory use in stage2, a while ago i realized that the src: usize only needed to be src: u32 since the max file size is 2gb or 2**31. is this a good way to save memory in stage2? i feel like if there are a lot if ir.Insts this might help a lot
<noam>
True - that would be 4 bytes per inst
jukan has quit [Ping timeout: 246 seconds]
<ifreund>
g-w1: I think that will likely be done when the same approach in #7920 is applied to the ZIR/TZIR
<g-w1>
ok, when that time arises ill leave a comment if i remember
xackus has joined #zig
Akuli has quit [Quit: Leaving]
xackus_ has quit [Ping timeout: 264 seconds]
kenran has quit [Remote host closed the connection]
xackus_ has joined #zig
reductum has quit [Quit: WeeChat 3.0]
xackus has quit [Ping timeout: 240 seconds]
nycex- has quit [Ping timeout: 268 seconds]
<andrewrk>
g
<andrewrk>
g-w1, I have some other ideas too such as only emitting the source for statements and other special cases
philtor has joined #zig
<andrewrk>
often many instructions in a row will have the same source location
<g-w1>
awesome!
<andrewrk>
marler8997, I'll have another look, thanks for the ping