ChanServ changed the topic of #zig to: zig programming language | https://ziglang.org | be excellent to each other | channel logs: https://irclog.whitequark.org/zig/
<hryx> daurnimator: you mean like just calling this a whole bunch? https://github.com/ziglang/zig/blob/master/std/build.zig#L1189
<daurnimator> hryx: I guess :)
<daurnimator> I always forget the names of build methods
<hryx> triplefox: you probably already thought of this, but I assume the best resources are existing build.zig files like this https://github.com/andrewrk/tetris/blob/master/build.zig
<hryx> and that stdlib file I linked above
kristoff_it has joined #zig
<daurnimator> hryx: there's nothing in there to help someone compile a C project though
triplefox has quit [Remote host closed the connection]
triplefox has joined #zig
kristoff_it has quit [Ping timeout: 258 seconds]
<hryx> hm true. I guess start with a single file `hello_world.c` and try `exe_step.addCSourceFile()` as a first shot?
<andrewrk> triplefox, here's an example of building a simple C library: https://github.com/andrewrk/liblaxjson/blob/zig-build/build.zig
_whitelogger has joined #zig
<andrewrk> triplefox, detecting libc on windows should work fine. you can see what zig detects if you run `zig.exe libc`
<andrewrk> after https://github.com/ziglang/zig/issues/514 is implemented, zig will able to provide libc rather than having to detect it
<triplefox> andrewrk, it says Unable to determine vcruntime.h path. i forget what the state of my msvc installs is right now, but i've been using mingw
<andrewrk> on windows. this is already the case for linux
<triplefox> hmm i have "Visual Studio Build Tools 2017 (2)" installed
<triplefox> i don't know if that (2) is something i should worry about
<triplefox> it didn't have some c++ things checked, so hopefully that's it. downloading 4gb
<triplefox> okay, it can find libc -- but now i have to figure out dependency things i think?
<triplefox> oh, "windows.h" not found
<triplefox> wait a minute, i'm approaching this all wrong. my ultimate goal is a wasm build, not a windows build
<andrewrk> triplefox, ah, yes. if you tell zig to target wasm it does not look for a libc
<triplefox> what is the command to retarget in build.zig
<triplefox> or is that separate?
<triplefox> aha
<tgschultz> so andrewrk, does freestanding always dump an ELF? Even for microcontrollers? I would have though flat, non-relocatable code or something.
<andrewrk> tgschultz, currently yes but that is something we can talk about
<andrewrk> as a workaround right now you can use binutils to extract the raw executable binary
<andrewrk> somewhere around here I have a "todo: avoid dependency on objcopy"
<daurnimator> readme line 63 :)
<andrewrk> :) thanks
<daurnimator> Each target should have a "default" format, but it should be overridable
<daurnimator> e.g. freestanding should probably default to raw output; but might be swappable to ELF or even hex encoded?
lunamn has joined #zig
<daurnimator> linux could conceivably have both ELF and a.out
<daurnimator> windows could have PE and COM
<tgschultz> that's a place to start I suppose, thanks. It seems to me though that if DOS is actually going to be a target we'll need to be able to output an MZ exe.
<daurnimator> oh TIL: > The final deprecation of the a.out file format on Linux will take place with the release 5.1 of the Linux Kernel
<andrewrk> daurnimator, I agree
<andrewrk> huh, neat, actually a pretty coherent discussion on the youtube comments of my philly ete talk
<torque> most of the (gcc-based) microcontroller toolchains I've used generate an elf and then postprocess it
wilsonk has joined #zig
wilsonk|3 has quit [Ping timeout: 245 seconds]
<triplefox> hmm if i do wasm build libc is not found. or maybe i have the wrong target settings: exe.setTarget(builtin.Arch.wasm32, builtin.Os.wasi, builtin.Abi.none);
<andrewrk> triplefox, are you sure you want wasi?
<andrewrk> are you targeting the web browser or node.js? or are you targeting WASI?
<triplefox> i actually don't, but if i put it to none it also doesn't work
<triplefox> i am targeting a custom wasm environment
<andrewrk> you want freestanding for the os
<andrewrk> what output do you get that tells you you're getting libc not found?
<triplefox> it thinks the target is 'wasm32-unknown-unknown-unknown'
<triplefox> Zig is unable to provide a libc for the chosen target 'wasm32-unknown-unknown-unknown'.
<triplefox> The target is non-native, so Zig also cannot use the native libc installation.
<andrewrk> I can explain the unknown thing. That's accidentally printing LLVM's notion of a target, which thinks that "freestanding" is "unknown"
<andrewrk> triplefox, let me take a quick look, this is probably a trivial fix
<triplefox> ok. i might be ducking out but i'll check
<andrewrk> triplefox, can I see your build script?
<andrewrk> I don't see how you can get to that error message unless you are linking against libc
<andrewrk> triplefox, ok cool, this all makes sense and I can explain what's going on now
<daurnimator> triplefox: `exe.linkSystemLibrary("c");` <-- freestanding wasm doesn't have a libc.
<andrewrk> you're trying to build lua for wasm, which is a cool idea, and of course it depends on libc
<andrewrk> so it makes sense that you have exe.linkSystemLibrary("c");
<andrewrk> zig - so far - does not know how to provide libc for wasm32-freestanding-none
<andrewrk> but, it should! that's one of the targets which should be listed in https://github.com/ziglang/zig/issues/514
<andrewrk> triplefox, I want to help you with this experiment so I'll put aside some time tomorrow morning to start those changes
<triplefox> yeah, that kinda makes sense. i'll be available
<andrewrk> zig's std/special/builtin.zig is essentially the beginnings of a multi-target libc. I should rename it to std/special/libc.zig
<scientes> yep
<tgschultz> I think I'd feel icky importing package "libc"
<scientes> well @import("builtin") should continue to exist and be split off
<scientes> those exports should be linked by default (because llvm needs them), but with a differn't namespace
<scientes> it would be nice if glibc's libm no longer depended on libc
<scientes> or if it could be used on windows for example
<tgschultz> curious note: apparently someone out there has created a long-mode version of DPMI, so it is theoretically possible to run 64-bit code in DOS.
<scientes> libm doesn't have the problems that libc has
<scientes> well rand() is kinda dumb
<andrewrk> tgschultz, yeah that's another reason to rename it - it's not in any way related to @import("builtin")
<andrewrk> there's no splitting off to do, it's just a name collision
<tgschultz> well that's just confusing, so yeah.
<scientes> and its interface is defined by libc
<daurnimator> Can someone add a radix tree implementation to the standard library?
<scientes> daurnimator, or xarray
<daurnimator> scientes: no need for xarray; maple trees are where it's at :)
<scientes> its hard to google for maple trees however
<scientes> all you get is sweet things
<daurnimator> and yeah... I do have a tab open on one pf my laptops open called "zig-maple-tree"
<daurnimator> one mild blocker there was a zig userspace rcu library
<scientes> daurnimator, do you mean user-space as in zig, or user-space as in not kernel mode?
<daurnimator> scientes: both
<scientes> cause the code should be able to work in kernel mode if the locking API is done right
<scientes> aware that you can't disable preemption in user-mode
<scientes> so you can never use spin locks
<daurnimator> scientes: rcu needs to be done differently in kernelspace (C macros and assembly) vs userspace (magic and use of membarrier() syscall)
<scientes> daurnimator, yeah but it should have the same API
<daurnimator> yep.
<scientes> there is also transactional memory
<scientes> which x86 and ppc has
<daurnimator> and going further, the only non-kernelspace rcu implementation is 1. dependent on pthreads and 2. GPL-only
<daurnimator> --> we need a userspace (not kernel) implementation of rcu that the zig standard library can use
<scientes> I didn't know about this membarrier syscall
<scientes> so you can do it without futexes?
<daurnimator> yep
<daurnimator> and you only need to use membarrier in rare situations
<daurnimator> its *usually* syscall-less
<scientes> same with futexes
<scientes> hence the name
<daurnimator> scientes: if you've got a few mins, maybe you could send a PR to std/os/linux adding membarrier syscalls?
<scientes> just use linux.syscall2() until you have a patch
<scientes> that actually uses them
<scientes> daurnimator, i have enough pull request in the queue right now :)
<andrewrk> scientes, speaking of - I'm looking at #2240 right now, looks like you're still working on it?
<scientes> well there is a bug in the stage2 that I have no idea what it is
<scientes> and i can't break on it either, stage2_panic should send a signal so it breaks in gdb
<scientes> using raise
<andrewrk> it does
triplefox has quit [Ping timeout: 244 seconds]
<daurnimator> sigh.... why does everything get so intertwined
<daurnimator> I want to finish the allocator, but now I'm wanting to finish the maple tree implementation... so I can use it in the allocator; which means I need to write userspace rcu first... which itself is like a month long project
<scientes> if (@popCount(Limb, self.limbs[self.len - 1]) == 1) {
<scientes> this is crashing the compiler
<scientes> its not resolving the type of the second argument
<scientes> wait, it might be my problem, i'll look into it more
<daurnimator> andrewrk: how does one add to process or thread initialisation in zig?
<scientes> daurnimator, createThread
<scientes> what is your question?
<scientes> *spawnThread
<daurnimator> scientes: no... I mean e.g. imagine if our standard library LinkedList implementation needed the process to call membarrier(MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED) on startup.
<scientes> yeah, TLS already does something similar
<scientes> but do only do that when needed, that is a big project
<scientes> as it requires static analysis
scientes has quit [Ping timeout: 258 seconds]
Tetralux has quit [Ping timeout: 256 seconds]
qazo has quit [Read error: Connection reset by peer]
mikdusan has quit [Read error: Connection reset by peer]
very-mediocre has joined #zig
mikdusan has joined #zig
mikdusan1 has joined #zig
mikdusan has quit [Ping timeout: 246 seconds]
knebulae has quit [Read error: Connection reset by peer]
jevinskie has joined #zig
_whitelogger has joined #zig
hio has joined #zig
komu has joined #zig
<komu> Hi, should I treat all segmentation faults in zig as a complier bug that needs to be reported?
kristoff_it has joined #zig
<komu> submitted issue; https://github.com/ziglang/zig/issues/2495 for the segfault
<komu> In a semi-related question, anyone know why I can be able to print(std.debug.warn) a `std.Buffer` but I cannot print a `std.ArrayList` ?
<mikdusan1> komu if the compiler segfaults then it's considered a bug. but 2495 the compiler generates executable and then runtime segfaults.
<komu> mikdusan1 thanks
<kristoff_it> komu: I read your gist, it's the inverse in zig: std.debug.warn inspects the types you try to pass and decides what to do at comptime
avoidr has quit [Quit: leaving]
<komu> kristoff_it: thanks. but looking at; https://github.com/ziglang/zig/blob/057a5d4898f70c6a8169c99375fbb8631e539051/std/fmt.zig#L246 it seems like `std.fmt.format` should already have print-formatting for Arrays.
<komu> I could also be mis-reading something
BitPuffin has joined #zig
komu has quit [Ping timeout: 256 seconds]
<kristoff_it> komu: sorry I know only enough to point you in that direction, I don't know anything about the details, maybe when one of the core contributors wakes up they will be able to help you :)
<very-mediocre> std.Buffer uses ArrayList internally
<very-mediocre> you're able to use `std.debug.warn` on `some_buffer.list` just as you would on `some_arraylist.items`
<very-mediocre> correct -- `some_buffer.list.items`
<very-mediocre> correction*
rivten has joined #zig
<very-mediocre> komu: in your example, the std.Buffer contains a std.ArrayList(u8) while the second bit uses std.ArrayList(i32)
<very-mediocre> bytes are printable
<very-mediocre> what i'm saying is one of them working doesn't imply the other will work
<very-mediocre> whether the 2nd case is a bug is another question
<BitPuffin> can zig be debugged in lldb or gdb?
<rivten> hello BitPuffin ! yeah, I got my executable running and breaking in gdb with zig ;) do you have trouble doing so ?
<BitPuffin> Great to hear that!
<BitPuffin> No I'm just getting started looking at Zig, thinking I might wanna try using it for something as long as it checks all the boxes
<BitPuffin> pretty excited about what I'm seeing so far :)
<very-mediocre> is there a clean workaround for this issue currently? https://github.com/ziglang/zig/issues/764
<very-mediocre> I'd like to store a `std.io.InStream` as a struct member
<very-mediocre> but i'm obligated to specify an error type when defining the struct member; and making it `std.io.Instream(anyerror)` doesn't work
<very-mediocre> meaning I can't pass a `std.File.InStream` to be stored there
<very-mediocre> it gives me this error: error: expected type 'std.io.InStream(anyerror)', found 'std.io.InStream(error{OperationAborted,BrokenPipe,Unexpected,InputOutput,SystemResources,IsDir,})'
<very-mediocre> the only way I can think of is to use a function that returns the struct, and have the stream type as a comptime param, but that seems a bit ugly
<very-mediocre> I thought any error set would satisfy "anyerror"?
<tgschultz> very-mediocre: the type system doesn't work that way in this case. InStream(X) is a completely different type than InStream(Y). If you're only storing a File.InStream, you can should be able to store it as type File.InStream
<tgschultz> if you want to store a "any" InStream, there is no way to do that without making your struct generic as well, currently.
very-mediocre_ has joined #zig
<very-mediocre_> right, what i really want here is interfaces i guess
<very-mediocre_> i'm doing the function/generic workaround for now, just feels "wrong" in terms of my instincts
<tgschultz> InStream is an interface, but it isn't a generic one. That's the design flaw.
very-mediocre has quit [Ping timeout: 256 seconds]
<very-mediocre_> it's an interface by convention
<tgschultz> yeah, that's the design flaw, it isn't actually usable as one.
<very-mediocre_> it also seems all error sets satisfy `anyerror` for function return types
<very-mediocre_> i expected it to behave that way across the board
<very-mediocre_> as you said though InStream(anyerror) seems to create a unique type
<BitPuffin> just a noob question: when people wanna do printf style debugging they use warn?
<very-mediocre_> BitPuffin: yep, there's also @compileLog and @compileError for comptime stuff
<BitPuffin> awesome
<tgschultz> it's because of how the the InStream is constructed. ErrorUnions are understood by the compilerm but every call to InStream() generates a completely new type in userland code. That means that each one could potentially have a different layout and they can't be casted between even if the compiler understood that only the ErrorSet was different.
<BitPuffin> I was thinking while eating lunch. That it would kind of be nice to have a print function that's only allowed in debug builds. Because there has been so many times when I've used debug printing and forgot to remove it later on haha
<tgschultz> This is something I'm actuvely working on improving, but I've hit a few stumbling blocks.
<tgschultz> that'd be easy enough to create BitPuffin. you could have a function that wraps debug.warn in an if(builtin.mode == .Debug)
<BitPuffin> ah nice!
<very-mediocre_> the cool thing is since builtin.mode is a comptime-known constant the entire code branch would be omitted for release builds
<BitPuffin> I guess I could probably even check for some arbitrarily defined symbol like you'd do with -D in C+
<very-mediocre_> tgschultz: your suggestionf for `var<trait>` param type would fix everything, as would any kind of "native" interface functionality
<very-mediocre_> if any error set satisfies `anyerror` in return types that's like a hard-coded interface
<very-mediocre_> er, sorta.
<tgschultz> Unfortunately it wouldn't fix everything, because it's comptime dynamic. You still couldn't store interfaces in structs without abstracting them into generic versions of themselves.
<very-mediocre_> at the very least it's polymorphic
<tgschultz> and therefore losing all ErrorSet information.
<tgschultz> The first attempt I did at interface reform handled that, it verified that any errorsets it wrapped were subsets of the one definied in the interface.
scientes has joined #zig
<very-mediocre_> i'm not following you 100%
<tgschultz> on which part?
<very-mediocre_> storing interfaces in structs
<very-mediocre_> to me interfaces are useful for comptime validation
<very-mediocre_> no different than asserting that a param has certain fields
<very-mediocre_> (a struct passed in as a param)
<very-mediocre_> hm i think i get your point now
<very-mediocre_> but i'm unclear as to whether it's necessary to do much more than validation
<very-mediocre_> i guess what i'm saying is i want comptime polymorphism
<tgschultz> WEll, there's two flavors of "interface". One is as you described, a check that some type meets some specification. The problem with that is it is comptime variadic. As you discovered, because they have different types you can't store InStream(A) and InStream(B) in the same field. In order to do that, you have to lose all the ErrorSet information (abstract the interface, in my own terminology). That's also true of non-variadic
<tgschultz> functions that, say, are in a dll you've loaded.
<very-mediocre_> gotcha.
<tgschultz> Thus there is a difference between 'comptime interfaces' and 'runtime interfaces'. So what I'm trying to do is make both types of interface reasonable to create and use. You'll be able to take any InStream using `var` and have all the errorset information, but if you want to store it you'll either have to make the struct you store it in generic or `abstract` the interface and loose comptime information like error sets.
<tgschultz> I'm on my fourth attempt though, and I've had to give up changing Allocator for now because of `async`.
<very-mediocre_> currently you can use var params and assert that the fields you want are defined, and you can do that for fields using codegen (generic functions)
<tgschultz> my first attempt was here, if you want to see how things might look: https://github.com/tgschultz/zig/tree/stdlib-interface_reform/
<very-mediocre_> cool, i'll take a peek
<very-mediocre_> another possibly dumb thought: you can use a union for such fields
<very-mediocre_> although that probably sucks for alignment
<tgschultz> I believe I can do better than that though. My blockers right now are async (due for a rewrite) and that abstracted interfaces don't work at comptime (and I'm not sure they should anyway).
<tgschultz> You'd have to know every type to union ahead of time. There's no good way to do that in userland so you'd have to rely on the compiler working it out, and what InStreams are available in one compilation unit might not be the same as the other and how do you normalize that?
<very-mediocre_> if "comptime dynamic" becomes possible it's doable
kristoff_it has quit [Ping timeout: 255 seconds]
<tgschultz> comptime dynamic unions are already possible, actually. Well, kinda: http://zig.tgschultz.com/pseudo_struct.zig (related blog post: http://rants.tgschultz.com/A%20Brief%20Tour%20of%20the%20Comptime%20Pseudo-Struct.txt)
<very-mediocre_> cool
kristoff_it has joined #zig
<very-mediocre_> i thought of doing nested structs with 2 fields each
<tgschultz> that's basically how it works, yes
<very-mediocre_> thus storing unlimited types
<very-mediocre_> oh
<very-mediocre_> i hit a roadblock when doing it though
<very-mediocre_> that was ages ago and I can't remember why it failed
<very-mediocre_> rants.tgshultz.com is a hilarious subdomain :)
<BitPuffin> can I add to package path from the command line or do I have to use a builder
<tgschultz> compiler asserts are still quite common when you do things like this in comptime. I can change a single use of a variable in that code and assert the compiler.
<tgschultz> BitPuffin --pkg-begin "name" "path/to/package.zig" --pkg-end
<BitPuffin> aaaaaaahhh
<BitPuffin> now I understand what's meant by package stack
<BitPuffin> thank you
<tgschultz> oops, found a typo I missed in that blog post
<BitPuffin> tgschultz: I'm a bit confused by the .Debug syntax you used with the if(builtin.mode == .Debug) example. Can you do that type of .X on any expression?
<BitPuffin> if I do if(foo.bar == .A) is it the same as if(foo.bar == foo.bar.A) or something?
<tgschultz> It's a relatively new feature called "enum literals'. For anywhere you use an enum you can shorten it like that. builtin.mode is of type builtin.Mode, so when you compare it to the enum literal .Debug the compiler knows that .Debug should also be a builtin.Mode.
<tgschultz> you've got the right idea.
<BitPuffin> ah so I could also do like
<BitPuffin> const x: bar = .A;
<BitPuffin> and it will be the same as const x: bar = bar.A;
<tgschultz> yes
<BitPuffin> nice! ergonomic :)
<BitPuffin> and noise reducing
<tgschultz> there are a few cases where it doesn't work, but those are bugs right now.
<tgschultz> Yeah, it's super handy. builtin.TypeInfo.Pointer.Size.One can now usually just be written as .One
<very-mediocre_> another huge ergonomic thing would be not having to do SomeAllocator.allocator or SomeStream.stream
<very-mediocre_> also fixed by interfaces :}
<tgschultz> very-mediocre, actually that isn't, because interfaces contain convenience functions over the actual interface implementations (see: std.Allocator, which has like 20 functions that work on reallocFn and shrinkFn, the only things implemented by the implementer).
<tgschultz> allocator.alloc is actually implemented by Allocator interface, not the implementation.
<BitPuffin> do you have to define the tagged union tags enum separately all the time or is there shorthand syntax for that
<tgschultz> So at the very least you're still doing something like: some_allocator.allocator();
very-mediocre has joined #zig
<tgschultz> BitPuffin: you don't have to, no. Simply declaring it as union(enum) will automatically make an enum out of the field names
<BitPuffin> I'm relieved to hear that
<BitPuffin> ah oops that's acutally in the docs
<tgschultz> I believe you can also specify the size of the enum if you really want: union(enum(u8))
very-mediocre_ has quit [Ping timeout: 256 seconds]
<very-mediocre> tgschultz: i see. I keep disconnecting, I'd written that my suggestions are bordering on abstract class territory
<very-mediocre> but i'm aware inheritance is not in vogue at all lately
<very-mediocre> i think it's underrated
<tgschultz> Another advantage of enum literals is that they encourage the use of enums instead of booleans in a lot of cases: https://github.com/ziglang/zig/pull/2175/files#diff-508baec7a14da1b53407b5d1189fb396R1105
<very-mediocre> I think I'd prefer having an "abstract class" for things like streams and allocators since it's being used that way currently anyway, only more verbose
<tgschultz> abstract classes come with a lot of hidden things or they'd be this verbose anyway.
<very-mediocre> I'm not sure I agree with that
<tgschultz> well you need a vtable at the very least. For everything that could be abstracted.
<very-mediocre> again we're hitting that comptime vs runtime dichotomy
<tgschultz> which is of course what we do anyway in interface reform, but it is out in the open.
<very-mediocre> I'm personally only in it for the comptime benefits
<very-mediocre> ergonomics and validation
<very-mediocre> no vtable necessary for that
<tgschultz> it is unavoidable. If you have an interface you're going to want to store it.
<very-mediocre> i mean, take streams for example. Would you not prefer to pass a some_stream directly rather than having to pass some_stream.stream?
<tgschultz> and it will be unexpected if you go to store something that looks like one type (InStream) and is actually a bunch of different types. Now your struct is generic too.
<tgschultz> eh, that's minor.
<very-mediocre> and what i have in mind would just be validation that the correct fields exist
<very-mediocre> well that's the bit about ergonomics
<tgschultz> that would require every implementation to implement all functions though.
<very-mediocre> can you currently not access "static" functions?
<tgschultz> As noted previously, Allocator implements most of the functionality we use from the interface itself.
<very-mediocre> since structs double as namespaces
<tgschultz> `self` doesn't work on those
<very-mediocre> oh state is being stored
<very-mediocre> i'd inherit that state
<very-mediocre> right into the child struct that's implementing the interface
<tgschultz> I think it is A) a minor ergonimic thing and B) of some benefit to readability that you pass an interface as some_implementor_instance.interface().
<very-mediocre> I'm sorry, I disagree, I find it unnecessarily verbose
<very-mediocre> and it's annoying to follow when structs wrap other structs
<very-mediocre> i also find it easier to reason about the stream itself being a stream
<very-mediocre> i.e. having certain fields/functions
<very-mediocre> tbh i'd have the compiler codegen the required state for any inherited functions
<tgschultz> ok, but then ArrayList(u8) now has to be ArrayList(u8, AllocatorType), because it can't store arbitrary types in a field. Maybe that's the right way to go, but it does make things more complicated.
<very-mediocre> or i'd even just refactor the reused functions into a module
<very-mediocre> i'd use composition there, like a stream "has" a struct of those state variables
<very-mediocre> hmm
<very-mediocre> are you assuming runtime support?
<BitPuffin> tgschultz: that's really nice to show intent :)
<very-mediocre> scratch my last question.
<very-mediocre> also, apologies for my crappy timing with responses, experiencing lag
<very-mediocre> (it comes off like I'm trying to talk over people)
<very-mediocre> tgschultz: actually you just need a pointer to an allocator
<very-mediocre> so there should be no size/layout concern there
<very-mediocre> unless I'm misunderstanding something
<rivten> hello everyone ! so I'm back after investigating some weird parameters offset in string that makes me unable to load file on windows only (I wrote something about that a few days ago). I've understood what's going on but not what causes it. Where should I put the write-up ? Maybe not in here because it's pretty long and technical ?
<daurnimator> rivten: either an issue on github or the mailing list?
<rivten> hmmm ok. do you think there is any preference ? both a very fine for me
<BitPuffin> very-mediocre: didn't jai have some elegantish solution to the whole ah I don't wanna pass some_stream.stream without having to take it all the way to abstract classes
<daurnimator> rivten: a github issue if you need a fix to zig itself; the mailing list if it's an interesting puzzle that you don't know even *who* is wrong
<rivten> ok. mailing list it is then. What's the mail address ?
<rivten> ~andrewrk/ziglang@lists.sr.ht ?
<very-mediocre> BitPuffin: dunno, tbh I haven't looked at Jai seriously as its progress has been glacial and I'm not inspired by the idea of improving some of the things C++ does wrong. I prefer zig's idea of C being the kind of baseline.
<BitPuffin> Hmm well I get a C is the baseline feeling from it as well
<BitPuffin> and I haven't actually caught up with it in years
<BitPuffin> the polymorphism stuff was many years ago
<BitPuffin> but apparently they're probably releasing a public beta this year
<very-mediocre> my exposure to it was years ago and back then JB was saying it'd be a better C++
<BitPuffin> either way it's buried in some of the old vids :P
<very-mediocre> it'll be interesting to see :]
<BitPuffin> yeah and the approach he's taking to that is basically removing all the ++ and then thoughtfully addin things, Zig reminds me a lot about it, with the compile time stuff etc
<daurnimator> rivten: yes I think that's i
<daurnimator> *it
<rivten> thanks a lot daurnimator :) :)
scientes has quit [Quit: Leaving]
scientes has joined #zig
stratact has quit [Ping timeout: 246 seconds]
stratact has joined #zig
<tgschultz> very-mediocre: re: you just need a pointer to an allocator: what do I pass the pointer to? the function would depend on the type. Ok, so next you store the function pointer too... and now you've lost all error set information again.
<tgschultz> in fact, you have status quo interfaces
<tgschultz> rivten, I'd make a github issue about it. It doesn't really matter who's wrong. If it is LLVM and we need to upstream a fix we probably still want a record of it, and even if it is the OS or something we still need a workaround.
<rivten> tgschultz you are talking about my email ? you have already read it ? ^^"
<rivten> oh no sorry
<rivten> didn't really understand :p
<rivten> okok
<rivten> well it's too late as I've just sent the mail :/
<tgschultz> it is possible to do both. I haven't read the email yet, I just got to work and was catching up on IRC.
<very-mediocre> tgschultz: i'm clearly missing something fundamental, i have it so the error sets in the hypothetical zig-with-polymorphism would be known as the error types of any allocator function of an allocator implementing the allocator interface would be the same
<very-mediocre> I don't want to impose, if you gotta work we can defer this discussion or I'll review it later with a fresh mind :]
<very-mediocre> and attempt to figure it out
<tgschultz> that's true for Allocator, but it isn't at all true of Streams.
<very-mediocre> ohh, I see what you're getting at
<very-mediocre> fair enough, I kind of left that loose with a vague notion that they'd standardize that
kristoff_it has quit [Read error: Connection reset by peer]
<very-mediocre> as in, with the knowledge that interfaces are a thing, and that streams are meant to be consumed a certain way, you might have an interface-esque standardization of the error sets
<tgschultz> yeah. There's potentially an argument to be made that error sets are more problematic then they are worth, but for now I'm trying to work out how to preserve that information when possible.
meowray has quit [Ping timeout: 258 seconds]
<very-mediocre> my instinct is for the error set to be part of the interface
<very-mediocre> as in a stream can throw certain types of errors
<very-mediocre> i have not thought this part through though, i kind of relegated it to a secondary place in the discussion as i was drooling over interfaces :)
<companion_cube> this kind of things have been studied in academia, btw
<tgschultz> that could be done, but then a lot of the usefulness of error sets for IO go away.
<tgschultz> and maybe that's ultimately where we'll end up, but I don't want to give up just yet.
<very-mediocre> i appreciate uncompromisingness
<very-mediocre> if that's even a word
<very-mediocre> i guess you could support a superset of the errors defined in an interface
<tgschultz> english is flexible about these things
kristoff_it has joined #zig
<very-mediocre> like say you were to support an error set defined by the hypothetical IStream interface, that doesn't prevent you from returning other errors
<very-mediocre> all the interface does is guaranteeting a certain set exists
<tgschultz> Then it may as well be anyerror
\u has joined #zig
<tgschultz> because I'll still need an else prong to cover cases of unknown errors being thrown
<very-mediocre> hmmm, true
<very-mediocre> bold suggestion: i would ditch error sets
<tgschultz> which is what I do for runtime/abstracted Stream interfaces, but I thik that's acceptable if you need to abstract, but you don't always and in those cases you'd want to have the error sets.
<tgschultz> That has been suggested
<very-mediocre> and replace them with polymorphic error struct thingies
<tgschultz> ....isn't that just ErrorSets with a different name?
<very-mediocre> possibly, i have not thought this through deeply
<very-mediocre> actually you're right, that was silly of me
<very-mediocre> i was trying to mirror the dynamic that works for interfaces
<very-mediocre> actually it's different from anyerror
<very-mediocre> it'd contain the expanded set (errors guaranteed by interface compliance + other errors the interface implementor might return)
<very-mediocre> but that's still not the global error set
<very-mediocre> although you are right in the bigger picture, that this information has to be stored somehow
<very-mediocre> and i don't know how that'd work
<very-mediocre> and again you are right that in comptime this is a non-issue
<very-mediocre> the actual error set can be inferred if the interface implementor (with interface-defined errors + its own errors) is comptime-known
<very-mediocre> i'm slower than you but i've reached the same conclusion as you now :)
<very-mediocre> i would like this level of compiler validation for comptime known interface implementors, and runtime ought to be OK with anyerror
<kristoff_it> hi all, question: is it possible to have a tentative comptime execution and bail out of it in case it can't be solved? I'm thinking something like receiving a slice in input to a function and trying to test its length. If it's backed by static memory, if I understand correctly, .len is known at comptime. So I wanted to try and make it a comptime error to pass a slice with the wrong length, when possible.
<tgschultz> .len is known at comptime for arrays, slices explicitly are not known length at comptime. You could take a pointer to an array? I'm struggling to understand what you're trying to do here.
<tgschultz> rivten: unsure if it is related to your issue, but it is worth noting that on Windows DirectAllocator has state, but it doesn't on Linux. Issues involving DirectAllocator will show up in Windows and not Linux. I don't see an obvious way that DirectAllocator could be the cause here, but it is something to consider.
<rivten> tgschultz, thanks a lot for the heads up :) hmmm yeah, something to consider probably, I'll keep that in mind when I'll investigate further
<tgschultz> very-mediocre: I've been thinking about this problem for a long time now, so you're not necessarily slower.
<very-mediocre> the lack of ego is appreciated :}
\u is now known as meowray
<kristoff_it> tgshultz: I have the .init function for my filter struct that takes slices, sometimes the slice is backed by static memory, sometimes by dynamic memory. I was wondering if I could statically check its length at comptime for the former case. Anyway you told me the answer: it's not possible unless I start generalizing the function, which I'd like not to do, for now.
<kristoff_it> ehm sorry for butchering your name, tgschultz
<tgschultz> there are something like 7 different spellings of "schultz" in the world, I am not offended.
<daurnimator> kristoff_it: use tab completion :)
<tgschultz> yeah, to do what you want to do, you'd take `var` and use if (comptime std.meta.trait.isArray(@typeOf(param))) { //do the array thing } else { //do the slice thing }. The optimizer might do the right thing anyway.
<tgschultz> daurnimator: that assumes the IRC client has tab completion
<daurnimator> tgschultz: I haven't seen one that doesn't
<kristoff_it> tgschultz: daurnimator: it does have it, thanks, it's been a while since I last used IRC, I forgot too many things about the ecosystem
<tgschultz> or actually, if you took `var` you could just check param.len since both arrays and slices have it... assuming we got around to implementing `.len` on pointers to arrays...
<kristoff_it> I still remember downloading songs and tv shows from bots though :)
* daurnimator is trying to work on his pool allocator right now.... trying to finish my non-radixtree/non-mapletree version before I move on
<daurnimator> I feel like I'm going crazy trying to figure out how to implement zig's allocator contract for alignment
<daurnimator> The problem is that when I align the returned pointer.... I need to move all the allocation metadata with it!
<daurnimator> otherwise I can't recover the metadata from the pointer at free-time
<daurnimator> so I've ended up with a structure like: [-<>-align space-<>-|-<>-size of align space-<>-|-<>-bucket_len-<>-|-<>user's data<>-] where every member is variably sized, and the whole structure is aligned to pointer requirements
<daurnimator> so if you have the pointer to start of user's data, you first recover the bucket_len, then look up the bucket metadata, and use that to find out the size of the size of the align space, then use that to find the pointer to the start of the structure
<daurnimator> why is it all variable sized? so that metadata overhead is proportional to the size of the allocation. <128 byte allocation? => 2 bytes of metadata.
stratact has quit [Read error: Connection reset by peer]
stratact has joined #zig
<daurnimator> and infact, if the allocation is not aligned more than a pointer, then only 1 byte of metadata is required.
<scientes> daurnimator, Arena allocator doesn't need any metadata
<scientes> and is ideal for many use-cases
<daurnimator> scientes: I'm not sure what your point is... is that just a non-sequitur?
halosghost has joined #zig
<scientes> oh, yes it is, I didn't read the whole context
<scientes> also look at google tcmalloc()
<daurnimator> scientes: keep reading that context....
<daurnimator> > trying to finish my non-radixtree/non-mapletree version
<scientes> you could just give the user an allocation the size of the alignment
<scientes> and never smaller
<daurnimator> how would that help?
<scientes> then you wouldn't have to worry about alignment
<scientes> you just bump the size
<daurnimator> Howso? I could end up giving them a 4096 byte aligned to 4
<scientes> like if they ask for 2 aligned to 4, you give them 4 aligned to 4
<daurnimator> that's actually worst case for allocation efficiency
<scientes> otherwise you need specialized pools
<scientes> which is half 2 aligned 4 and half 2 aligned 2
<daurnimator> because when I need to store the metadata for a e.g. 4096 byte bucket, I would use 4 bytes for the metadata; then waste 4092 bytes for alignment :P
<scientes> but why do you need metadata, the caller has the pointer and the length
<daurnimator> metadata includes which bucket it came from; so that I know which freelist to add it to
<scientes> that can be determined by the pointer
<scientes> and a routing table of pools
<daurnimator> > trying to finish my non-radixtree/non-mapletree version
halosghost has quit [Quit: WeeChat 2.4]
<scientes> well, if you aren't going to optimize it then just leave it unoptimized
<scientes> premature optimization is the root of all evil
<daurnimator> it *is* optimized though
<scientes> I don't see why you wouldn
<scientes> wouldn't want a radix tree
<tgschultz> he's just using a different strategy
halosghost has joined #zig
<daurnimator> because the radix tree approach has terrible performance in certain multithreaded workloads
<daurnimator> I'm using the other main approach
<scientes> not if you look at tcmalloc, i believe
<scientes> and have thread-specific pools
<scientes> you can also have differn't pools for differn't data structures
<scientes> by specializing the allocator with a pool option
<daurnimator> now you can mitigate the radix tree overhead (as tcmalloc does). but that requires a huge amount of work; and hooks into thread creation+destruction
<daurnimator> now if you have pool allocators, you don't really want to be hooking thread create/destroy: as pools become no longer cheap
<scientes> it would also be cool if it could work with the MMU and page tables
<scientes> but i don't think that is reasonable
<daurnimator> the tcmalloc approach only really works well when it is the process wide allocator
<daurnimator> now... jemalloc has a few ways around that.. but that would probably be 5 years of work to replicate.
<scientes> daurnimator, you could also have a getcpu() function, and then have per-cpu pools
<scientes> that would make it more NUMA aware
<daurnimator> NUMA barely matters for this sort of thing, it's mainly about keeping things within a cache line
<scientes> I still think more use of arena allocators is a huge potential for improovement
<daurnimator> anyway, the approach I'm taking is a classic well-worn road in other languages/libraries
<scientes> as the best way to improove efficiency is to do LESS
<daurnimator> the trouble is that zig's allocator interface has alignment... no others do
<daurnimator> it really confounds the whole structure
<scientes> yes they do
<scientes> well, malloc max alignment is the max alignment requires by the ABI
<scientes> it can't go higher
<scientes> while zig's is suitable for circular buffers
<daurnimator> scientes: C malloc maxes out at long double alignment.
<daurnimator> which gives you a small upper bound
<daurnimator> which would be easy for me to take care of
<daurnimator> but.... zig's allocator interface doesn't have that
<scientes> again, I think you should just bump the size, except for an exception at common page sizes: 4K, 64K and 2M
<daurnimator> that's a huge waste that usurps the whole point of the design
<scientes> you can pool these metadatas
<daurnimator> you're going in loops here
<scientes> just take the pointer, subtract the mmap base of that alignment bucket, and then access it as a growing downwards array
<kristoff_it> oh no, why is this syntax not supported? https://gist.github.com/kristoff-it/3209b6c243643fbcdfbd25c3d38d79d3
<scientes> so the metadata grows the other direction as the pool
rappet has joined #zig
<very-mediocre> kristoff_it: this compiles https://godbolt.org/z/jPHeBa
<kristoff_it> that's interesting
<very-mediocre> just need curly braces for your second switch case
<very-mediocre> and also change `!void` to `void` because you're not returning any errors.
<kristoff_it> sure it was just a simplified example
<scientes> very-mediocre, you need the curly braces to have code in the switch
<scientes> just like with if and while, et cetera
<very-mediocre> indeed.
<scientes> it doesn't do the same-line thing that if and while does
<scientes> and for
<scientes> maybe it should
<very-mediocre> i'd like that because i'm lazy
<kristoff_it> I have some code that doesn't have those curly braces around .warn and that compiles
<kristoff_it> inside a catch |err| switch (err) ...
<scientes> that's cause you have a lvalue there
<kristoff_it> true
<kristoff_it> although I can't see all the implications of that difference
<tgschultz> this also works: https://godbolt.org/z/_ogR-G
<scientes> i think it should be supported for same-line
<very-mediocre> tgschultz: wellthereitis.gif
<very-mediocre> good catch, that's subtle
<scientes> ahhh yes i knew that
<very-mediocre> i just wrote code like that too... |:
<kristoff_it> tgschultz: ah nice thanks.
<kristoff_it> it's a bit confusing when the semicolon is required and when it's not. now I see that it was not needed, because it never is in a switch case, unless you open a nested block
<kristoff_it> but I got confused in the beginning
<tgschultz> error message could possibly be a little better in cases like that. Maybe ',' should be mandatory in such lists, even at the end. Then it would have said it expected ',' and got ';'
<kristoff_it> yeah true
<scientes> also needs a error message when you try to do math on a function pointer
<scientes> instead it just crashes
<tgschultz> yeah, that's a bug
<scientes> gcc/clang have a good error message for that
<tgschultz> though, one could argue that function pointers should be compatable with pointer arithmetic. I can't think of a usecase offhand though. Some kind of dispatch table?
<scientes> they can't because they require the linker to resolve the symbol
<tgschultz> only for relocatable code
<scientes> even with static linking
<tgschultz> what about with no linking?
<scientes> then llvm links it
<scientes> And I just proposed a llvm optimization that would definitely not work with such a thing
<scientes> but it still is linked
darithorn has joined #zig
darithorn_ has joined #zig
darithorn_ has quit [Client Quit]
darithorn has quit [Ping timeout: 255 seconds]
shollrollah951 has joined #zig
<kristoff_it> what's the equivalent of this line but without the zeroing? I can't figure out how to mix = undefined with align()
<kristoff_it> here's the line: var memory align(cuckoo.Filter8.Align) = []u8{0} ** memsize;
<andrewrk> var memory: [memsize]u8 align(8) = undefined;
<andrewrk> var memory align(8) = ([memsize]u8)(undefined);
<andrewrk> these are semantically equivalent
<andrewrk> that's a strange place to put the alignment annotation, probably it can move to after the `var` or `const`
<kristoff_it> oh dammit I tried every possible combination, except placing align at the end of the type
<kristoff_it> thanks
<kristoff_it> usually with slices is []align(N) u8, right?
<andrewrk> right for pointers & slices the align annotation is after the pointer sigil
<andrewrk> zig doesn't have syntax for alignment annotations on parameters yet, but that's another place they belong
<andrewrk> that will probably be before the parameter name
qazo has joined #zig
<kristoff_it> im very satisfied, I think I got a very good interface out of my cuckoo filter implementation, definitely much better than anything I would have been able to come up with if left alone in a room with C and the preprocessor.
<kristoff_it> thanks for helping me through the alignment stuff (tgschultz in primis)
<kristoff_it> a couple more features (e.g. a few exported functions for C usage) and I think it might be perfect software, at least from my point of view :)
<kristoff_it> looking forward to make a package out of it in the future
<andrewrk> sweet
<kristoff_it> also andrewrk: I'm looking forward to try to write a Redis client in Zig once the networking stuff is ready, I think hiredis (the C client) needs competition
<kristoff_it> I have great plans about automatically filling structs and various containers with data coming from redis using clever comptime reflection
<andrewrk> yeah! for sure the M:N threaded event-based I/O will be very competitive in terms of performance. as long as we can make data races / threaded issues not be footguns
<kristoff_it> cool, I'm also interested in blowing some minds. This is taken from the protocol specification, it's about Hash maps coming from redis:
<kristoff_it> `Client libraries should return Maps using the idiomatic dictionary type available. However low level languages like C will likely still return an array of items, but with type information so that the user can tell the reply is actually a dictionary.`
<kristoff_it> can't wait to see people make a weird face when I say that I can do both with one function definition :)
rivten has quit [Ping timeout: 256 seconds]
qazo has quit [Ping timeout: 246 seconds]
qazo has joined #zig
<donpdonp> i see std.json has a parser from json_string to ValueTree, but I dont see a json builder - is there one?
rivten has joined #zig
knebulae has joined #zig
qazo has quit [Read error: Connection reset by peer]
qazo has joined #zig
jjido has joined #zig
jjido has quit [Client Quit]
DutchGh0st has joined #zig
<DutchGh0st> I found another bug :3
jevinskie has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jevinskie has joined #zig
<tgschultz> me too, it's a new one for me, I've never encountered `assert(mem_len != SIZE_MAX);` before.
jevinskie has quit [Client Quit]
<DutchGh0st> did you alloc(@maxValue(usize)) ? :3
<DutchGh0st> or std.math.maxInt these days
<shollrollah951> Hi guys. I've been adding experimental support for zig in the geany-IDE. It's quite rough, but at this point it is possible to keep refining it: https://github.com/user00e00/geany4zig
<shollrollah951> Aside from that, what programming environments are people here using for zig?
avoidr has joined #zig
kristoff_it has quit [Ping timeout: 258 seconds]
<tgschultz> DutchGh0st it's a compiler assert trying to run tests
<tgschultz> tests I didn't even modify I might add
<DutchGh0st> mh?
<tgschultz> shollrollah951: I don't use an IDE personally.
<tgschultz> I think this is some kind of namespace loop, but it occurs even when using --override-std-dir
<tgschultz> interesting, has to do with the usage of @import("../std.zig") pattern, which I don't think is necessary anymore.
<tgschultz> it appears it is infinitely appending the directory
triplefox has joined #zig
<nrdmn> is it possible to write generators with zig's coroutines?
<andrewrk> currently no
<hoppetosse> shollrollah951: I use vscode in C mode, as the syntax highlighting is reasonable and you end up being able to use the gdb debugger integration to peek into variables and stuff
jjido has joined #zig
<shollrollah951> hoppetosse: Isn't there a zig plugin for vscode?
<hoppetosse> Yes, there is, but it doesn't work with the debugger
<shollrollah951> I see.
<hoppetosse> In c mode, you can literally use a graphical debugger, set breakpoints, watch vars =)
<hoppetosse> it pretty much just works
<shollrollah951> That's great.
<hoppetosse> it doesn't know about slices and stuff, but it usually decays to a pointer
<shollrollah951> You can't set breakpoints inside geany, but I think there is a plugin for it with gdb support.
<hoppetosse> geany was my fav editor for a long time
<hoppetosse> been a while since I've used it
<hoppetosse> is there a windows version?
<shollrollah951> I think there is.
<hoppetosse> yes there is!
<shollrollah951> If you wanna test geany with zig, you can just get the default version and then add the basic language support file I made.
<shollrollah951> "For lightweight support (syntax highlighting) for zig in a regular geany release: copy "/data/filetypes/filetypes.ZigBasicSupport.conf" from this repository into "$/.config/geany/filedefs"."
<shollrollah951> my forked geany version only has proof-of-concept support for zig really, so it might not be worth the trouble to compile it when just this one config file gets you basic support.
DutchGh0st has quit [Remote host closed the connection]
very-mediocre has quit [Ping timeout: 256 seconds]
NBonaparte has joined #zig
NBonaparte has quit [Client Quit]
<andrewrk> triplefox, ah, I just sent you an email
triplefox has quit [Ping timeout: 250 seconds]
triplefox has joined #zig
<triplefox> @andrewk i'm looking at that rn
shritesh has joined #zig
halosghost has quit [Quit: WeeChat 2.4]
<shritesh> andrewrk: Just saw your ping. I am between moving and vacations rn. Does the PR affect all wasm freestanding binaries or just those compiled with libc?
wootehfoot has joined #zig
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
rivten has quit [Remote host closed the connection]
shritesh has quit [Ping timeout: 256 seconds]
<andrewrk> shritesh, all wasm freestanding binaries. in summary you'll usually want to use build-lib instead of build-exe when targeting the browser
wootehfoot has quit [Quit: Leaving]
wootehfoot has joined #zig
wootehfoot has quit [Read error: Connection reset by peer]
shollrollah951 has quit [Quit: Leaving]
triplefox has quit [Remote host closed the connection]
triplefox has joined #zig
<tgschultz> so is it just the compiler being a dick to me, or does `Struct`sometimes magically become *const Struct after passing through a few functions, none of which ever take *const Struct?
<tgschultz> @compileLog even confirms it isn't *const
<tgschultz> immediately before the call where it complainst that it is *const
<tgschultz> `self.bytes(rand_bytes[0..]);` => 'derp, I'm magically *const!' => `@typeOf(self).bytes(self, rand_bytes[0..]);` no problems.
triplefox has quit [Ping timeout: 250 seconds]
<tgschultz> this is extremely annoying
triplefox has joined #zig
<tgschultz> ...and it defies minimization. That's great.
hio has quit [Quit: Connection closed for inactivity]
<mikdusan1> tgschultz: is it possible you have 2 definitions of bytes(), one inside struct, one outside?
<tgschultz> no
<tgschultz> if I put a compile log immediately before the statement that fails, it tells me @typeOf(self) is Struct, followed immediately by the compile error that it expected Struct and got *const Struct
<tgschultz> thus far I have been unable to reproduce it in a minimal test case. Also, Struct passed through about 5 other functions with no issue before mysteriously failing on this one.
<tgschultz> I really wanted this one to be my fault so I could fix it and move on, but as far as I can tell there's just something about this situation that causes the compiler to derp, so I'm blocked.
<tgschultz> more to your question: There are 2 occurances of the word 'bytes' in that file. One is the definition and the other is the call
<tgschultz> I'm also fairly confident this issue is unique to comptime evaluation
<mikdusan1> oh yeah sometimes running the comptime guantlet something comes up as const. i seem to recall something like that. and it was actually my own fault, just the compiler error didn't pinpoint it.
triplefox has quit [Ping timeout: 252 seconds]
<tgschultz> I'm fairly confident it isn't my fault this time
<tgschultz> I wish it were
<tgschultz> there's a call to a function taking *Struct. The call gets evaluated just fine, but the an assignment complains about it being const. Comptime is just randomly deciding things are const in the middle of evaluations it looks like.
<mikdusan1> `@typeOf(self).bytes(self, rand_bytes[0..]);` <-- what happens if you change to `@typeOf(self.*).bytes(self, rand_bytes[0..]);`