<v1zix>
From debugging with gdb it was showing the []const u8 passed to `buf.replaceContents` is being modified
<v1zix>
At the end the `buf` should be `foo`
<v1zix>
instead of `fo` with a null byte at the end
<hspak>
\
<hspak>
oops
<rjtobin>
Newbie question about inferred error sets: if I have a recursive function with return type "!void", I get an error of the form: "cannot resolve inferred error set ... function 'recursive_foobar' not fully analyzed yet". If I make the error explicit it works, but it's slightly painful. Is there a best-practice for this?
<fengb>
Zig can’t infer circular error sets yet so it’ll have to be explicit
<rjtobin>
Got it. Is inferring circular error sets planned? My use-cases are all pretty simple (my cycles are all self-loops, ie. f() calling itself)
<hryx>
According to that, the incompatibility with recursion may be overcome in a future version
<hryx>
but I don't think there's actually an issue to track it as a proposal. seems like it should either be a proposal (whether rejected or accepted) then documented
kristoff_it has joined #zig
<rjtobin>
hryx: yeah, fair enough. Still I'm just being lazy, it's not an important feature
<hryx>
rjtobin: don't sell yourself short. I think it will be important when we get around to making a real language specification
<rjtobin>
v1zix: I'm pretty ignorant, so take this with a grain of salt, but isn't val pointing to the same memory as the buffer's internal list? So you're trying to write to the thing you're copying from
<rjtobin>
hryx: Point taken. It's pretty incredible how fully-featured it is already with such a small dev team.
kristoff_it has quit [Ping timeout: 248 seconds]
<daurnimator>
v1zix: `" foo\n "` is an array. `buf.toSliceConst()` is a slice.
<v1zix>
rjtobin: Ah, that looks like that's the issue. For some reason I thought that would be a compiler error, but I'm still pretty new to Zig as well
<v1zix>
Thanks for the help!
<daurnimator>
oh right
<daurnimator>
v1zix: it could make sense to propose that `replaceContents` gets memmove semantics?
<daurnimator>
or just assert that the argument doesn't overlap...
<v1zix>
daurnimator: Yeah, that could help. I thought gdb was lying to me when it said `val` and `buf` were occupying the same memory, but it makes sense now
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 245 seconds]
<daurnimator>
v1zix: I think mem.copy is missing an assert... and the comment above it is wrong
<v1zix>
daurnimator: An assertion that the `dest` and `source` don't occupy the same memory?
<daurnimator>
v1zix: yep
<daurnimator>
and the comment above it says `dest.ptr must be <= src.ptr.` which isn't true: really if they *do* overlap, then dest.ptr must be < src.ptr
<daurnimator>
trying to add that assert I get failures building libuserland
<v1zix>
daurnimator: Sounds good, thanks for looking into that!
<daurnimator>
v1zix: you might want to throw a comment on there mentioning that it caused you a confusing issue due to usage via buffer.replaceContents.
<v1zix>
daurnimator: Sounds good, I added a comment with my sample code
<rjtobin>
hryx: Great, thanks!
kristoff_it has joined #zig
<daurnimator>
hryx: "based on the color of the giant spaghetti monster's mood ring" <-- I like that
<hryx>
:P
kristoff_it has quit [Ping timeout: 272 seconds]
<daurnimator>
btw, I had a thought about functions overnight... its sort of weird how we treat functions as function pointers, rather than an actual struct containing code.
laaron has joined #zig
laaron has quit [Client Quit]
laaron has joined #zig
laaron has quit [Remote host closed the connection]
<emekankurumeh[m]>
is there a way to prevent translate-c from producing all that "junk" code?
<emekankurumeh[m]>
translate-c on an empty header file produces a 300 line file
laaron has quit [Remote host closed the connection]
laaron has joined #zig
<emekankurumeh[m]>
also enums produces both zig enums and a bunch of constants
<daurnimator>
emekankurumeh[m]: not right now
<daurnimator>
I recall a proposal to make #include in a header file emit @cImport. but I can't find it now
<emekankurumeh[m]>
the "junk" being produced seems to be fixed in self-hosted
<daurnimator>
emekankurumeh[m]: is it the same stuff as if you run `clang -E -dM - <<< ''`
kristoff_it has joined #zig
ltriant has quit [Quit: leaving]
kristoff_it has quit [Ping timeout: 245 seconds]
v1zix has quit [Ping timeout: 260 seconds]
marijnfs has joined #zig
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 272 seconds]
<gonz_>
andrewrk: Have you seen https://vimeo.com/230142234 ? Do you think a clearer stating of core and less core values as well as values zig does not have would be helpful?
<gonz_>
It's easy to infer values from the zen of zig as well as the website, but it's also very easy to infer what's not really there.
kristoff_it has joined #zig
<daurnimator>
gonz_: interesting talk.
<gonz_>
It's a great talk, yeah. I had seen it 2 times previously but only recently started taking it into account in everyday life. It's easier to deal with stuff if you consider that values are underlining everything.
<gonz_>
It sounds trivial and obvious, but I don't think it actually is.
<daurnimator>
gonz_: makes me think I should go off and write out what my values are for various things
<daurnimator>
including zig.... and then compare notes to andrewrk :P
<gonz_>
I actually think it's a very useful exercise. The reason I came back to this recently was because I started questioning some of my values very intently and started re-evaluating things that I saw as truths.
<daurnimator>
Thinking out loud: the most important things to me for zig are: 1. be able to replace C in all reasonable(*) places that C is used. 2. It should be better(*) than C.
<daurnimator>
From those 2. I can infer further things; but also the (*)s there give lots of flexibility.
<gonz_>
I've built my career on expressivity and velocity for the most part, but as I became more and more obsessed with correctness and robustness most of my tools seemed bad. Lately I've started questioning expressivity as even a secondary value as well as came around to simplicity and predictability probably being more important.
<daurnimator>
I think "simplicity" is a bad word to use: it means different things to different people. and when you encounter a complex task.. the complexity has to live somewhere, but if everyone is trying to be simple then you end up shoving it in a corner -> that is where "Edge cases matter." from the zen of zig wins.
<gonz_>
You can do complex things with simple tools
<gonz_>
I think complexity lives better in the product than it does in the tool
<gonz_>
Yes, I've seen it
<gonz_>
It's a great talk and very thought provoking
<gonz_>
I don't think the takeaway should be to not use "simple" as a word
<gonz_>
Simplicity exists
<daurnimator>
gonz_: I think it's very telling that there *has* to be 30 minutes of the talk defining "simple".
<gonz_>
Well, it explains that people should say "easy" sometimes
<gonz_>
0 to blog in 60 minutes is likely the result of "easy", not "simple"
<daurnimator>
I'd rather you said e.g. "composable" if that's what you mean
<gonz_>
That's not really the same thing
<gonz_>
Haskell has more composable entities than OCaml does, but OCaml is undeniably simpler
<gonz_>
It's a smaller language that tries to do less
<daurnimator>
I'd say the definition of simple is that talk is 90% "composable"
<daurnimator>
s/is/in/
<gonz_>
Things that aren't intertwined with other things are more composable, yes, but I think it's just one point of many about simplicity
<daurnimator>
I could probably s/simple/composable/ in the transcript and have the same talk
<gonz_>
I think the bigger point in all of this is that without indications of core values and examples of those values being cited it's very hard for a burgeoning community with many different people in it to coalesce on a coherent idea.
<gonz_>
I think there are a lot of people with a lot of different values in zig and I think mine differ wildly from a lot of the more prominent contributors at the moment. It's helpful at some point to know if one belongs.
<gonz_>
In many ways it's the absence of stating a value that's important. I don't care about approachability as a core value, for example, and I don't know that I care about velocity when it comes to long-lived things either.
<gonz_>
If a small language is more approachable that's great, but it's not something I'd explicitly aim for. Learning about memory, etc., is clearly not super approachable and that's fine.
<mq32>
hey
<gonz_>
Guten tag
<mq32>
:)
<mq32>
gonz_, i think it's weird that basic memory stuff is actually simple (just a huge table), but not easy to explain (or at least i never found anyone who actually teached it well)
<gonz_>
Yeah, I think it's interesting that the resources I see from random people nowadays actually are better than anything I remember from back in the day. At this point I don't even remember how I learned any of it.
<mq32>
yeah, me too
<mq32>
i'm usually explaining all of the memory stuff (adress, word/byte access, pointers, …) in an excel sheet
<mq32>
and i noticed that it works great because it's a visual thing
<daurnimator>
I once explained it to my wife on a 20 min walk .... I think I did a good job cause she asked questions the next day :P
<daurnimator>
explained using a "list of things on lined paper" analogy
<daurnimator>
--> "you can only fit so much on a line" "if you want two lists on one piece of paper how do you know when they start/end?" "how can we reference one list from another"
<gonz_>
I wish some of these explanations were given to me when I was 14
<gonz_>
I was so bad at learning and on top of that I had so much to learn in C++
<daurnimator>
gonz_: so I had a go at using Cantrill's list of things and pick them out for my thoughts on zig. I got: Interoperability > Robustness > Composability > Debuggability
<gonz_>
Cool :)
<daurnimator>
I find it interesting that "maintainability" isn't in there... despite it being in the tag-line of the zig website
<gonz_>
I think this is actually a great thing, even as you noted for oneself
<gonz_>
For self-reflection
<gonz_>
It's useful to see other peoples' lists also because you end up reconsidering things
<daurnimator>
I ordered them too: e.g. I think that when you're trying to interoperate with *another* system that's not consistent, it's better to do the best you can than refuse to based on how it would impact your own robustness
<gonz_>
Yeah, you've actually given me food for thought
<daurnimator>
Another interesting choice of my own (I think) was debuggability over safety: I see zig's safety features as merely enablers of debugging; rather than the end goal itself.
avoidr has joined #zig
<SimonNa>
ls
<mq32>
.
<SimonNa>
Oh, hi
<mq32>
..
<SimonNa>
I looked at Zig a year ago, recently got annoyed with null references in D again and every time the desire grows to write something substantial in Zig
<daurnimator>
SimonNa: welcome back then :)
<SimonNa>
hnn :)
<daurnimator>
SimonNa: so what are you going to make?
<SimonNa>
Sorry, no project. I'm reading the 0.4.0 doc. Last time I dabbled in Zig, it was still 0.1.0.
<SimonNa>
Probably it'll be only quick helper tools for personal use
<SimonNa>
The urge is there though to use Zig for something more than 10-line example programs :)
<daurnimator>
SimonNa: probably better to look at master
<daurnimator>
there have been enough changes from 0.4.0 now....
<SimonNa>
Hmm, because of new features that or better docs?
<SimonNa>
All right, now I have version 0.4.0+c47b75312, happily reading the docs
<daurnimator>
SimonNa: re: AUR package being outdated; I meant due to changes in how zig builds that the PKGBUILD needed updating. But tiehuis already updated it in AUR.
<SimonNa>
Ah, okay. Yes, it built seamlessly the current master head.
<SimonNa>
Thanks, why is it "this as well", are there two different ArgIterator?
<daurnimator>
SimonNa: one it "I want a copy of the arguments all at once". one is "I want to iterate over args"
<SimonNa>
Hmm
<daurnimator>
and yes, that should probably get cleaned up
<SimonNa>
"Are you making a library? Let users pick your allocator" <3 <3
<SimonNa>
Fully encouraging choice of the strategy from the top down, even if it is painful
<SimonNa>
It's already annoying in other languages with exceptions when the app uses none (and want to declare nothrow wherever possible), but calls into libs that throw. Same for allocation.
<daurnimator>
indeed. and that seems to always end up in the situation where developers pretend that allocation never fails
<daurnimator>
that whole saga is why I left rust
<SimonNa>
Hmm
<SimonNa>
It rarely fails, and if it fails, crash the app. It's usually a good strategy, did you need more control?
<SimonNa>
Hmmm, if your application has an elaborate caching system, very interesting idea
<daurnimator>
SimonNa: or not even elaborate
<daurnimator>
SimonNa: there's also plenty of good memory models I'd like to support e.g. in a HTTP server, use a per-connection and per-request arena allocators
<SimonNa>
Hmm, to guard against any single peer taking all resources for itself :)
<daurnimator>
that 1. lets you drop a connection on the ground if low on memory for some important operation (e.g. admin command or config reload). but also 2. impose a e.g. 10MB limit on per-request memory usage.
<daurnimator>
--> how would you ever accomplish either of those if you just had a single global allocator where libraries panic on failure?
<SimonNa>
It's possible in other languages to do it, but that's the same argument that comes in the D forum very often: Use this elaborate template to get what you want, you don't need a langauge feature.
<SimonNa>
Hmm, even C++ without GC will use the C heap e.g. when std::vector allocates, and you don't want that; I remember one could supply custom allocators as template parameter but I've never tried that.
<daurnimator>
SimonNa: yeah C++ is probably the best language for it: you can pass an allocator as a template parameter.
<daurnimator>
SimonNa: however the code bases that rely on this sort of thing often end up reimplementing their own "standard library". e.g. look what EA made: https://www.youtube.com/watch?v=8KIvWJUYbDA
<daurnimator>
others (e.g. nginx) just end up demanding that everyone uses their allocation APIs instead of C's.
<SimonNa>
Nnn, that demand violates that the top-most code chooses the strategy >_>
<SimonNa>
"make it work with any buffer the user provides"
<SimonNa>
It also advocates making every library a plain C library with imperative usage, because that fits into most strategies
<SimonNa>
Anyway, "Choosing an Allocator", highly inspiring section in the manual. Even for video games where one would jump to conclude that one must reference count or manually free, it recommends the arena that frees once per loop.
kristoff_it has quit [Ping timeout: 268 seconds]
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 248 seconds]
marijnfs has quit [Ping timeout: 268 seconds]
marijnfs has joined #zig
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 244 seconds]
kristoff_it has joined #zig
kristoff_it has quit [Remote host closed the connection]
kristoff_it has joined #zig
avoidr has quit [Quit: leaving]
<scientes>
SimonNa, reference counting and mmanually freeing is slow
<scientes>
malloc/free is probably the slowest part of C
<scientes>
and, yes I just called C slow :)
<gonz_>
Treating everything as its own little thing that needs to be managed as a unit is slow
<mq32>
scientes, fun fact: you can write java programs that are faster than C programs, even with optimizations turned on
<mq32>
(assuming you use the same algorithm)
<l1x>
nice
<scientes>
only if your C program sucks ass
<mq32>
hrhr
<l1x>
not really
<mq32>
yeah, if you replace any "new" with "malloc"
<mq32>
but: a garbage collector beats free/malloc with thousands of small allocations
<scientes>
or if you are compiling your C program to CPUs from 2008
<scientes>
cause Java *is* slow
<scientes>
don't believe the hype
<scientes>
it also does extremely poorely with swap
<nrdmn>
mq32: doesn't that depend on the specific malloc implementation?
<fengb>
Yeah it doesn’t have to be slow. FixedBuffer or object pooling is blazing fast
<mq32>
nrdmn, yeah it does
<fengb>
Java can be faster because the JIT can inline things that are always indirect in C, like function pointers
<nrdmn>
there are better reasons why C could be faster than it is
<nrdmn>
its aliasing rules, for example. You can declare parameters as `restrict`, but who knows that?
<gonz_>
Predictability can be nicer than raw potential
<nrdmn>
I wouldn't call C predictable if you're not a language lawyer
<mq32>
it's crazy with modern CPUs
<fengb>
More predictable than a GC :People
<gonz_>
nrdmn: I wasn't referring to any one language, to be honest. There's also the elephant in the room in terms of compilers.
<mq32>
i wrote a "shitty" basic interpreter and it runs with 1.7 Mio Lines of Basic per second
lunamn has quit [Ping timeout: 244 seconds]
<gonz_>
Some of them are more predictable than others.
<gonz_>
Given the opportunity I think a language could carve out a nice niche out of predictability. The best case solution if you don't have that seems to be to rely on tools that at least let you know what the end result was.
<fgenesis>
SimonNa, daurnimator: re:allocators, my main gripe with C++ allocators in containers is that they are used as template args, ie. no swap() possible between containers using different allocators
laaron has joined #zig
<fgenesis>
my understand is that once you go into your allocator you go into DRAM anyway, so an allocator object with a virtual method or a simple allocator function pointer would be a lot more useful, because it's possible to change it at runtime, including swap(), etc
<fgenesis>
so perf is not an argument to baking allocators into the type
<nrdmn>
are there any languages yet that treat allocation as a side effect?
dimenus has joined #zig
dimenus has quit [Quit: Leaving]
<daurnimator>
nrdmn: what do you mean by "side effect"?
lunamn has joined #zig
<nrdmn>
daurnimator: "side effect" as in 1. anything that affects the outcome of a function that is not in its parameters, e.g. fetching the time, random bits, or keyboard inputs from the system, and 2. any state changes to the environment outside of the function, e.g. console output
<gonz_>
Haskell allows you to annotate essentially everything in the type system. For the most part imagination would be your limit there.
<nrdmn>
for example, haskell treats i/o, time and random as side effects and represents them in its type system but not memory allocation
<gonz_>
`createVector :: MonadAllocatingVector m => Int -> m (Vector ...)`
<gonz_>
The caveat being that allocation can't safely be avoided so you'd essentially have to change the tools you use internally
<gonz_>
Which is probably not a useful path to go down, considering
<gonz_>
ATS might be able to actually do it
<gonz_>
It's possible to use ATS unsafely, but it's also, as far as I understand it, very easy to create safe layers on top of raw `malloc` that require passing proofs of freeing around, etc.
<gonz_>
So in that sense allocation at least becomes something you *have* to deal with in the type system
halosghost has joined #zig
<nrdmn>
gonz_: you'd need an allocator for infinite lists, too
<nrdmn>
and any kind of recursion
<nrdmn>
I think that's just not feasible in haskell
<gonz_>
I agree
<fengb>
Wait, you're not allowed to agree on the internet
samtebbs has joined #zig
<nrdmn>
:)
<nrdmn>
daurnimator: I threw out most of my uefi PR because I'm not sure how to implement the std lib parts. I think it is mergeable for now, but for the missing parts (wrapper functions, abort, panic...) I'd wait for some feedback.
dazhbog has joined #zig
gamester has quit [Quit: Leaving]
<gonz_>
Ugh
<gonz_>
There are like 3 different proposals that basically amount to "private struct fields" from the same person
<fgenesis>
only let friends touch your privates, or what was the saying in C++...
<gonz_>
Something like that :D
<fgenesis>
i like the way that some languages do it, like prefix with _ to make private
<fgenesis>
but i like it even more not as a language feature rather than as a convention
<fgenesis>
don't touch stuff that starts with _, easy enough
<gonz_>
For the things where it makes sense I think opaque pointers mappable internally to actual data is fine
<gonz_>
You have to really want to create issues if you take it upon yourself to go in and do it manually in those cases
<gonz_>
Or am I just crazy?
<fgenesis>
pointering everything probably not a good thing
<fgenesis>
means extra allocations etc
<fgenesis>
and going via opaque pointers just to force a certain part of a struct to be inaccessible is just a road to disaster
<gonz_>
Not a bigger disaster than changing the language for this feature, IMO
<fgenesis>
yes ,so to both, the answer is don't do it
<fgenesis>
KISS and so on
<gonz_>
People are coming up with all kinds of insane ideas. Readonly but only for other packages, etc.
<fengb>
I'd only use opaque to reference literally unknown sized data
<fengb>
I don't like real private in general because you can't work around other people's limited assumptions
<nrdmn>
"but why would you want that?"
<fgenesis>
i've always thought that putting private stuff into headers was stupid
<fgenesis>
for one thing it's there and laughs at you because you can't access it, but it also means classes are larger than the public part by a known number of bytes, and everything is still part of the ABI/memory layout
<fgenesis>
so kinda worst of all worlds
<fgenesis>
(C++ ofc)
<fengb>
How else would you do private memory though? Stick it in a void pointer?
<fgenesis>
for things that always return a pointer: stick it at the end behind the struct
<halosghost>
mmmmmmmmmmmmmm void pointers
<fgenesis>
if the struct is public: add void *privmem;
<fgenesis>
or, for 1) if the user can control the location of the struct but the implementation needs private data
<fengb>
Now you have the possibility of copying the struct != copying private data
<fgenesis>
yes
<fgenesis>
it's really a case-by-case thing and there's no universal golden hammer
<nrdmn>
why would you want private fields?
<fengb>
Maintaining ABI compatibility is a good reason
<fengb>
Hiding fields for encapsulation purposes is a not-that-good reason
<fgenesis>
but if the private fields contain native OS stuff
<fgenesis>
my solution so far was to have some void*[N] array with N large enough for your typical OS
<fgenesis>
so the struct is public but the void*array is private and OS-defined, and copying a struct by-value is always passing it
<fengb>
But if I'm only on 1 OS, it's hiding things that I could have access to
<fgenesis>
if you're only on 1 OS you're doing it wrong :P
<nrdmn>
fgenesis: what's the reasoning for making that field private?
<fgenesis>
nrdmn: in my case it's sort of an mmap() wrapper that hides things like alignment requirements (on linux) and file mapping objects (on windows)
<fengb>
Your library shouldn't dictate how my code should function. I don't think it's good to depend on privates, but more often than not, there's no way other than forking
<fgenesis>
so depending on the OS those pointers contain different things (original, non-aligned pointer on linux and OS cruft on windows)
<nrdmn>
your structs contain executable data?
<fgenesis>
and no such thing as fork() on windows so good lucjk
<fgenesis>
lol, what, no
<fgenesis>
(to be clear, not talking about zig but struct design in general, which i assume we were doing anyway)
<fengb>
In Zig, we'd probably just comptime the differences away
<fengb>
Hmm... how will Zig handle ABI if the compiler is allowed to reorder struct fields?
laaron has quit [Remote host closed the connection]
<fgenesis>
extern struct for abi, normal/packed struct for internal-foo
<gonz_>
mq32: :D
<fgenesis>
mq32: lol
<mq32>
that was my immediate brainfart when i've seen your last messages :D
<nrdmn>
what would I use a packed struct for if not for an abi?
<mq32>
maybe memory mapped IO or similar
<mq32>
which could also be considered ABI
<fengb>
My expectation is: packed for guaranteeing exact memory layout and extern for guaranteeing stability
<fengb>
e.g. extern struct probably wouldn't convert bool to u1
<nrdmn>
what would it convert a bool to?
<halosghost>
following that logic mentioned, presumably a u8
<mq32>
yeah, probably u8
<fengb>
u8 is most flexible. u32/u64 might be "faster". u1 would be slow and kill any sibling fields that aren't aligned properly
<fengb>
Actually if it was (bool, u32) side-by-side, it'd most likely do (u32, u32)
<mq32>
i think it's actually ABI and platform dependent what "extern struct" is doing
<mq32>
in contrast to "packed struct" which is defined as "everything in ordner, no single bit padding"
<fengb>
Yeah, it's just the C ABI atm, which is implementation dependent
<fengb>
C is allowed to pad fields but not change the order
<scientes>
if we really want to be "safe" we could test that every pointer is reachable before assigning it
<scientes>
but that would be really slow
<scientes>
but if would catch segfaults at the store, rather than the load
<fengb>
Dereference on copy?
<scientes>
we would be checking that every point holds a reachable value, by keeping track of memory maps.
<scientes>
/proc/self/maps
<nrdmn>
on linux and only if you have access to /proc
<scientes>
nrdmn, no, we do every allocation so we can keep such information internally
<scientes>
on every OS
darithorn has joined #zig
<samtebbs>
packed structs are useful when the CPU expects an exact layout in memory, such as interrupt handler entries and page tables on x86
<fengb>
Unless we use the C allocator
<nrdmn>
or run on a platform that does allocation for us
<marijnfs>
is andrew in his cave?
<halosghost>
packed structs are useful for when I want to do all the alignment things myself
<mq32>
are also useful for platform-interop (eg. file storage, networking, …)
<nrdmn>
so, ABIs
<scientes>
<marijnfs> is andrew in his cave?
<scientes>
hehe
<scientes>
he's working on coroutines
<marijnfs>
is that like threads?
Akuli has joined #zig
<scientes>
sort of
laaron has quit [Remote host closed the connection]
<scientes>
except you don't have a scheduler
<mq32>
*except you are the scheduler ^^
laaron has joined #zig
laaron has quit [Client Quit]
laaron has joined #zig
laaron has quit [Remote host closed the connection]
ltr- has joined #zig
<SimonNa>
scientes: Yes, refcounting is slow, lots of small deallocs is also slow. I had known that one could call a language's GC every cycle, but the arena per cycle is even cleaner and likely faster. GC would scan the entire app. This speed has never been a problem in D, but others complain about the suboptimal D GC, yeah.
<SimonNa>
I have no opinion about the speed of Java, never wrote anything performant in Java :)
<fengb>
Modern GCs have separate arenas for different lifetimes
wilsonk_ has quit [Ping timeout: 245 seconds]
<halosghost>
I really wish we would leave GC alone
avoidr has joined #zig
<gonz_>
As in?
<gonz_>
I don't think anyone was necessarily criticizing GC in general, if that's what you mean.
<gonz_>
Most D users don't think that the D GC is all that great, though.
<gonz_>
If that's the bit you were remarking on
<SimonNa>
Yeah, the standard D GC; it's fine for everything I've done, but others would prefer finer control/not stop-the-world to scan entire app.
<halosghost>
gonz_: on the contrary: I'm criticizing it in general
<gonz_>
halosghost: Right, sorry for the misunderstanding.
<halosghost>
it's okay :)
wilsonk_ has joined #zig
marijnfs has quit [Ping timeout: 272 seconds]
<halosghost>
all I want is a type-safe memory allocator
<halosghost>
there's very limited need for a GC after that point
<halosghost>
well, that and defer
<halosghost>
:)
<halosghost>
zig has 1/2 already
<halosghost>
I'd be very happy to see the type-safe allocator get merged as well
<fgenesis>
tape-safe? memory is memory
<halosghost>
fgenesis: a type-safe memory allocator essentially does two things: when a bit of memory is allocated for a particular type, it tags that bit of memory with the type it was allocated for
<halosghost>
fgenesis: if ever that bit of memory is allocated again (e.g., it was freed and is now going to be allocated again), it will only allow that bit of memory to be allocated for the same type it was allocated for originally
<halosghost>
fgenesis: that alone is enough to turn the vast majority of memory-safety bugs from security vulnerabilities to logic errors
<fgenesis>
why would anyone even want that
<halosghost>
cf. my last comment :)
<halosghost>
tada: memory-safety
<fgenesis>
yeah no
<halosghost>
no need for GC, no need for lifetimes
<halosghost>
fgenesis: okay :)
<fgenesis>
that's kinda not how it could ever work
<halosghost>
what makes you say that?
<fgenesis>
also you wouldn't catch type aliasing issues at runtime, only at allocation time, which is way too late and too coarse
<fgenesis>
so effectively to be type-safe you'd have to check types on every access if you're serious about it
<halosghost>
that's not my understanding, but okay
<fgenesis>
also doesn't save you from not freeing and accidentally re-using as something else
<halosghost>
use-after-free wouldn't be a vulnerability though, just a logic bug
<fgenesis>
also it's easy to write what you described, just alloc some more plus alignment, stick a magic uint32 in front of the allocation, fix the alignment, and use the rest as the actual object. tada, type annotations that you can keep even thru free()s
<halosghost>
indeed
<halosghost>
though, having language-support for it would be lovely
<fgenesis>
plus some sort of pre-init an area to already contain the type every xx bytes, assuming all of your objects are of the same size
<halosghost>
ideally, in the case of zig, via a special allocator
<fgenesis>
it's nothing that needs language support
<fgenesis>
no, you want an allocator, you provide it, and if you want that behavior, it's up to you
<halosghost>
I can't tell if you like this idea or hate it since you went from “this is stupid, it can't work that way” to “it would be so easy to write this yourself and have it work”
<halosghost>
fgenesis: no kidding
<fgenesis>
this doesn't need any kind of language support because whatever you do, this can't be safe, and this can't save you from an attacker
<halosghost>
okay
<halosghost>
have a great day :)
<fgenesis>
giving false impression of safety is not what anyone would like
<fgenesis>
like "file-system shredder" tool to delete files safely on SSDs
<fgenesis>
great, file is gone, but if you desolder read out flash chips
<fgenesis>
ah dan
<fgenesis>
if you desolder and read out chips then wear leveling still has original data
<fgenesis>
that's what i mean with false impression of safety
* fgenesis
drops mic and leaves stage
<tgschultz>
I wrote something like what's being described, but it worked differently. It used different pools of memory for each type. It isn't an 'Allocator' though, since it doesn't implement the allocator interface.
<halosghost>
anyway, gc seems to be impossible to have with predictable and reasonable performance
<halosghost>
tgschultz: interesting
wootehfoot has joined #zig
fsateler has joined #zig
<SimonNa>
Are there reference webpages for the Zig standard library? Or is the source the documentation?
<scientes>
if you have too much documentation it gets harder to change
<scientes>
the focus should be on increasing the quality over writing documentation
<Sahnvour>
I hope stdlib's quality improves faster than documentation which is basically nonexistent
<SimonNa>
Autogenerated docs go a long way, even if it's only the signatures
<scientes>
yes, progress on autogenerated docs would be great
<scientes>
something like ruby's documentation
<scientes>
but actually writing documentation, meh
<scientes>
too much other stuff to do
<SimonNa>
Yeah, any documentation that's not autogenerated from the source file would get stale fast, agree.
<SimonNa>
Heh, it's all good, I don't mind looking at the source. I merely would have preferred bells-and-whistles docs had they existed.
<scientes>
SimonNa, do it! it would be a great way to learn zig
<scientes>
actions speak louder than words
<SimonNa>
Hah, I took an hour today to write the program that takes cmdline args and prints them to stdout :) If I stick with Zig, I'll certainly consider to look at easy issues.
omglasers[m] has joined #zig
<scientes>
well yeah, maybe do some easier stuff first
<scientes>
an hour isn't bad however
<scientes>
and the cmdline arg handling in zig is...meh
<SimonNa>
Yeah, day-one Zig feels like procuding code with hammer and chisel.
<scientes>
I actually re-wrote it
<scientes>
but didn't have the energy to seel a differn't way of doing it
<SimonNa>
Hmm, I stuck with std.process.argsAlloc, I've seen that there are iterator solutions.
<SimonNa>
Hoh, didn't know that argv can be so big
<SimonNa>
Also, Zig coding style. E.g., I want to write a function that takes an allocator. Since I didn't know the type *std.mem.Allocator, I was tempted to write a generic function and let the compiler figure out the types. But I'd guess that explicit types are favored?
<andrewrk>
SimonNa, one trick you can do is to use the wrong type (e.g. i32) and look at the compile error
<SimonNa>
Heh
<SimonNa>
Yeah, nice idea, the compiler is happy telling the tyeps
<fengb>
Improve your zig code with one neat trick!
<SimonNa>
I already used std.debug.warn(@typeName(stuff)), but just writing wrong type is easier, no need to get everything to compile first
<Akuli>
:D
<andrewrk>
you can use @compileLog instead of std.debug.warn for that
<SimonNa>
Hmmm, thanks :)
<SimonNa>
yeah, common D hack is pragma(msg, typename(typeof(a)), this is the exact equivalent, nice
<andrewrk>
there are a bunch of things that D & Zig independently came up with
<andrewrk>
another example is errdefer / scopeexit(error)
<SimonNa>
Right, where Go only has one defer, Zig has both
<andrewrk>
sorry, it's scope(failure)
<SimonNa>
yep, and the third is scope (success) but that's practically never required
<SimonNa>
The strong non-nullability guarantees are my reason to follow Zig, happy to spend a day on it again after so long.
gamester has joined #zig
<SimonNa>
Assume I have err: anyerror. I can print its name with std.debug.warn("{}\n", @errorName(err)); but std.debug.warn(@errorName(err)); fails -- why does it fail with "Unable to evaluate constant expression" when the {} worked with the same expression?
<andrewrk>
SimonNa, the format string parameter of std.debug.warn is marked comptime
<andrewrk>
so that parameter must be compile-time known
<SimonNa>
Ah, makes sense. Thanks :)
<Akuli>
std::web_view wtf
<Akuli>
c++ still calls itself a "programming language"?
<scientes>
leaky kitchen sink more like it
Tetralux__ has joined #zig
<fgenesis>
as a c++ person i facepalm hard and scream for help. someone please apply sanity
<gonz_>
I'm planning on trying to map out some relevant parts of `user32` for win32 stuff and I'm underway with the basics at the moment. How do people feel, should it land in a library or be PRd into std?
Akuli has quit [Quit: Leaving]
* scientes
has no idea about win32
Tetralux_ has quit [Ping timeout: 245 seconds]
dazhbog has quit [Ping timeout: 260 seconds]
<scientes>
Is there a good reason you can't do binary arithmatic on bools?
<scientes>
return true ^ true;
<scientes>
this isn't seem right
<fgenesis>
scientes: != is xor for bools
<scientes>
yeah but why can't you also use ^?
<mq32>
gonz_: Sounds more reasonable to make a user32 library
<scientes>
../src/ir.cpp:16841:58: note: did you mean to use logical not (‘!’)?
wootehfoot has quit [Read error: Connection reset by peer]
kristoff_it has quit [Ping timeout: 246 seconds]
kristoff_it has joined #zig
<hryx>
dumb question about sr.ht... to reply to a message and keep it in the thread, does one have to click the user's name in the browser? The docs don't say anything about simple reply/reply-all in e.g. Gmail https://man.sr.ht/lists.sr.ht/
<scientes>
I found a bug that only happens at run-time if you enable comptime
<scientes>
so we arn't checking comptime right somewhere
<scientes>
codegen needs to assert that it isn't generating code for comptime stuff
kristoff_it has quit [Ping timeout: 245 seconds]
<scientes>
hryx, do you think if (!~(a == b)) is better than if ((a == b).any()) ?
bheads_ has joined #zig
<hryx>
scientes: what would those do?
<scientes>
I guess we could also have a "ifany", but then not any would become if (!(ifany(a == b) true else false)), which is horrendus
<scientes>
hryx, comparisons of vectors return vectors of bools
<scientes>
so you have to do wave-form scheduling, when you branch if *any* of the bools are true
bheads has quit [Ping timeout: 248 seconds]
bheads_ is now known as bheads
<mq32>
scientes, i prefer either the method-version or the free function version
<hryx>
on interesting. I'm generally not into new sigils unless it's broadly applicable in everyday code TBH
<scientes>
there are basically three ways to cast these vectors of bools to bools
<mq32>
if(std.vector.all(a == b)) { }
<scientes>
all, any, none, and notany
<scientes>
hryx, well yeah, that's why i realized that !~(a == b) could do it
<scientes>
with an implicit any() cast to bool
<scientes>
**implicit all() cast to bool, sorry
<scientes>
mq32, so you don't like if (!~(a == b)) ?
<scientes>
its kinda funky but it doesn't have to add new syntax
<scientes>
and std.vector.all is way too verbose
<scientes>
hryx, well for me this vector stuff is everyday
<hryx>
I gotcha. I'd have to look at it later (a little busy at the moment) and understand its use a little better
<hryx>
without me totally understanding: what about a @builtin?
<scientes>
I prefer a build-in method to a whole new built-in intrinsic
<scientes>
or even the method as mq32 pointed out, std.vector.all() which can be done
<scientes>
actually std.vector.any()
<hryx>
that sounds solid
<scientes>
any() is the weird (and most useful) one
<mq32>
scientes: i don't like the operator overloaded one
<mq32>
it isn't understandible at all
<scientes>
mq32, its not overloaded
<scientes>
its well defined, but it is confusing
<scientes>
english is better
<scientes>
any()
<mq32>
also we can import stuff into global namespace, so any/all/… can be global symbols if you want
<scientes>
mq32, well yeah, its like .is_signed and .bit_count
<scientes>
I actually can't even add the () until after the anon function stuff lands
<scientes>
I already have the any() implemented, but I second-guessed it
<mq32>
scientes, take a look at how GLSL does vector comparisons
<andrewrk>
with perhaps one or two exceptions, an operation which works on a primitive type also works on vectors (or is planned to work). the documentation has not been updated for SIMD/vectors yet
<andrewrk>
e.g. float ops work on vectors of floats; pointer ops work on vectors of pointers
<scientes>
I've implemented a bunch of them
<scientes>
so ! can return a vector of bools?
<scientes>
i'd kind of rather have it enforce bool-ness, and then use ~
<scientes>
I mean, we could even have == and != always return bool, and force vector uses to use ^ and then >
<scientes>
^ and then > 0
<scientes>
but that seems a little weird
<andrewrk>
! on a vector of bools will return a vector of bools with ! applied to all of them
<scientes>
but don't you see the consistancy I am talking about, where ! != and == always return bool?
<scientes>
considering that they all have bitwise equilivents: ~ and ^
<scientes>
yeah either way however
<scientes>
Its all the same too me
<scientes>
andrewrk, because the consistancy of the operator is ruined by the lack of consistancy in the return type
<scientes>
so ! != and == would then be illegal on vector of types other than bool
<scientes>
*on vectors
<andrewrk>
I don't see what you're talking about - it seems like you want set operations but you want to repurpose !, ==, != to be those set operations
<scientes>
while it would require learning, the error message would be good, and it would make the code easier to read
<scientes>
andrewrk, no, I just rejected doing any overloading or implicit casting from vectors to non-vectors
<scientes>
the point is that ! != and == will always return the same type
<andrewrk>
I don't see why that is inherently valuable
<andrewrk>
int + int always returns an int
<andrewrk>
bool == bool always returns a bool
<Sahnvour>
andrewrk: just rebased my PR
<andrewrk>
thanks Sahnvour
<scientes>
oh, wait, its borked because it would work for floats
<scientes>
particularly NaN
<scientes>
ok, that is settled
<gonz_>
Is there no actual proposal with some set ideas for these things?
<scientes>
only ! could be done that way
<gonz_>
This seems awfully unstructured
<scientes>
and if it was just one operator it would be confusing
<andrewrk>
scientes has some pull requests open which I have not reviewed yet
<scientes>
the SIMD one really isn't ready, but I'm happy with the reception I've gotten
<scientes>
I'm pushing towards a MVP for replicating the paid work I did for IBM on non-portable SIMD
<Tetralux__>
What's a good example of the use of .format interface?
Tetralux__ is now known as Tetralux
<andrewrk>
Sahnvour, good stuff.
<andrewrk>
it's probably better to avoid adding default struct field values of `undefined`
<scientes>
oh yeah, doing this in user-space is going to run into the undefined issue....
<scientes>
sometimes use of an undefined behavior is defined
<scientes>
*undefined value
<andrewrk>
Sahnvour, unless the intention is to let the API user directly initialize structs
<andrewrk>
but if it's the initializer's responsibility to make sure the fields are eventually defined, having them explicitly initialize to undefined at the initialization site is a good way to make people remember to do it
<scientes>
what about allowing ^ & ~ and | on bools?
<Sahnvour>
thanks, I assume you're talking about MsfStream ? In this case this is not really a type I expect the user to instanciate directly, and the ones created with default values *do* represent invalid streams
<Sahnvour>
but I didn't think about this too much (small oversight), no problem in changing it
<gonz_>
What's a MsfStream?
kristoff_it has joined #zig
kristoff_it has quit [Ping timeout: 244 seconds]
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jjido has joined #zig
<Sahnvour>
gonz_: MSF is a file format that can contain multiple interlaced streams of data, that's what you find inside .pdb for windowws debug symbols. I was replying to andrew about default undefined struct members
<gonz_>
Yeah, I was just wondering what it represented
<gonz_>
Cool
<Sahnvour>
I don't know if it's used in other things, probably stands for microsoft stream file or something like that but there aren't many references outside .pdbs
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
lunamn has quit [Ping timeout: 272 seconds]
lunamn has joined #zig
dazhbog has joined #zig
<dazhbog>
hi, is there a way to make zig compiler handle -framework option on macos?
<scientes>
dazhbog, you can always word around such things by using build-obj
<scientes>
and then manually calling the linker
ltriant has joined #zig
<dazhbog>
scientes, thanks, I'll look into that. What worries me though is that the frameworks move around with macos versions so I can't assume paths to stay the same..
<andrewrk>
scientes, dazhbog, there are better options to explore before resorting to build-obj and using the system linker
<andrewrk>
there is an option to add paths for the linker to look in for frameworks
<dazhbog>
andrewrk: that sounds like the right tool for the job :)
<dazhbog>
andrewrk: I managed to build and run the tetris-example on macos but I'd like to do it the right way
<andrewrk>
dazhbog, what changes did you have to make?
<dazhbog>
andrewrk: in the end the only problem was that OpenGL/gl.h cannot be found (because it's hidden behind a framework)
<dazhbog>
so I had to .. persuade the build system to find it
<dazhbog>
but that was it.. it built and ran happily. I was pleasantly surprised :)