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/
_Vi has quit [Ping timeout: 260 seconds]
<adamkowalski> do we have an absolute function which works on both ints and floats?
<adamkowalski> I'm seeing a std.math.absInt, std.math.absFloat but no std.math.abs?
<scientes> adamkowalski, write it!
<scientes> pretty simple
<scientes> and absInt doesn't really need to exist
<scientes> and absFloat really should just be private
<adamkowalski> I just wrote it, I thik it does need to exist, it can actually error out, but the float version can't
<adamkowalski> absInt might overflow
<daurnimator> terinjokes: please do send a PR for it :) it should contain: 1. wrappers in os/linux.zig that mainly just provide correct types around the syscall 2. an extern definition in std.c somewhere. 3. a wrapper in std/os.zig that converts the errno-style result to a zig error.
<terinjokes> daurnimator: i'll try to do that tonight
return0e has quit []
return0e has joined #zig
return0e has quit [Client Quit]
adamkowalski has quit [Remote host closed the connection]
ltriant has quit [Ping timeout: 240 seconds]
<Snektron> daurnimator, are you still on that mixin proposal
<Snektron> I was thinking, you could strike a balance between that and the current vtable solution
<Snektron> Basically, instead of the interface calling virtual functions defined by the parent type, it would just call them via @field
<Snektron> It would look similar to the current implementation, except without the virtual methods
<Snektron> One drawback though is that it makes renaming harder
ltriant has joined #zig
tdeo has quit [Quit: Quit]
ltriant has quit [Ping timeout: 260 seconds]
tdeo has joined #zig
<via> andrewrk: thanks for the detailed writeup. i still have a few questions, but i don't think i'll be able to look much more until the weekend again
ltriant has joined #zig
adamkowalski has joined #zig
ltriant has quit [Ping timeout: 268 seconds]
ltriant has joined #zig
ltriant has quit [Ping timeout: 260 seconds]
dddddd has quit [Remote host closed the connection]
swoogan has joined #zig
adamkowalski has quit [Remote host closed the connection]
<daurnimator> Snektron: the first mixin PR got rejected. I haven't thought of a good rebuttal
mahmudov has quit [Remote host closed the connection]
ltriant has joined #zig
ltriant has quit [Ping timeout: 265 seconds]
ltriant has joined #zig
<pixelherodev> I'm converting from a C single-header array library to Zig (creating an interface for use with C code)
<pixelherodev> Like many C libraries, it stores integers before the array for size/capacity
ltriant_ has joined #zig
<pixelherodev> It uses `((int *) (ptr) - 2)`, where ptr is of the correct type (e.g. `char*`) to get to those values
<pixelherodev> e.g. ((int*) (ptr) - 2)[1] to get size
<pixelherodev> Is this correct Zig wise? `@intToPtr([*]c_int, @ptrToInt(self.ptr) - 2 * @sizeOf(T))[1]`?
ltriant has quit [Ping timeout: 265 seconds]
ltriant_ has quit [Ping timeout: 240 seconds]
<pixelherodev> Ah, nope; should be using @sizeOf(c_int) not @sizeOf(T)
<pixelherodev> It works now, yay!
<pixelherodev> Wrote a working Zig interface to the stb stretchy_buffer
<pixelherodev> `sb.of(type).from(ptr)` gives a structure with some useful methods; `count()`, `push()`, `free()`, etc... but also `toSlice()` and some more Ziggy ones
<daurnimator> pixelherodev: zigacious :D
<pixelherodev> Yeah, pretty neat
<pixelherodev> Right now, I'm using `for (sb.of(string).from(up).toSlice()) |t| ` to iterate over a sb of strings
<pixelherodev> (where string is a custom C string type I wrote to make things a bit faster, which I plan on replacing with rapidstring when I have time)
<daurnimator> I was thinking yesterday how we should have a proper string type in zig: I'd like string literals to be of the type... but have the methods etc in the std lib.
<daurnimator> Probably the only thing like it (in that the compiler assumes it exists?) is the panic function?
<daurnimator> It's a sort of weird situation where the language depends on the standard library (but should be overrideable)
<pixelherodev> I think that if such a thing is implemented, literals shouldn't automatically be that type
<pixelherodev> They should be able to decay into that type though
<pixelherodev> Just as they do to e.g. c strings and slices
<pixelherodev> That would mean that existing code would be unaffected
<pixelherodev> If a struct member function takes a *This(), and you set that to null, then e.g. `a.free()` would result in a becoming null, correct? (with most details being implicit here)
<pixelherodev> Rather, with e.g. `fn free(self: ?*@This()) {self.* = null;}`
traviss has joined #zig
<pixelherodev> then `a.?.free()` should set a to null, correct?
<pmwhite> daurnimator: What's the benefit you have in mind for a proper string type? More safety due to distinguishing between slices and strings?
<daurnimator> pmwhite: essentially yes: at the moment e.g. std.fmt treats arrays of u8 specially and prints as a string instead of like it does arrays of other things.
<daurnimator> pmwhite: would also be able to have string methods that don't make sense on arrays.
<pixelherodev> Ooh, better yet: can convert stretchy buffers directly to Zig array lists
<daurnimator> pmwhite: and going further: perhaps the string type could e.g. guarantee valid utf8
<traviss> can anyone spot what's wrong with: https://clbin.com/Wk2P0 ? I'm getting lld errors similar to the one shown at the top of this file.
<daurnimator> traviss: uh.... is there reason to assume the error message is incorrect?
<daurnimator> traviss: it looks like mpz_init was never defined...
ltriant has joined #zig
<traviss> no reason to think its incorrect. i figured i was forgetting to to pass some linker flag.
<daurnimator> traviss: well does your libgmp.a have a mpz_init function?
<traviss> i'm verifying that now
discipulus has joined #zig
<pmwhite> I assume you would have to include the header that it's defined in too.
<daurnimator> pmwhite: no hes done that manually in that snippet
<pmwhite> oh, makes sense.
ltriant has quit [Ping timeout: 265 seconds]
<pixelherodev> What's the correct way to pass a function pointer to C?
<pixelherodev> error: expected type '[*c]extern fn() void', found 'extern fn() void'
<pixelherodev> Taking the address results in a weird casting error
<daurnimator> pixelherodev: yeah you just pass in the function; don't take an address
<pixelherodev> That results in the error I posted
<daurnimator> pixelherodev: there was a comment on a related issue this morning
<traviss> ah, the symbol is actually `__gmpz_init`. thanks guys
<pixelherodev> `const func: [*c]extern fn() void = load_tag;` gives the same error
<daurnimator> pixelherodev: https://github.com/ziglang/zig/issues/4124 is what I was thinking of...
<daurnimator> pixelherodev: WSAOVERLAPPED_COMPLETION_ROUTINE (via WSARecv) is where I ran into it before
<pixelherodev> Any workaround?
<pixelherodev> Or do I have to wait until translate-c is fixed?
<daurnimator> traviss: translate-c/@cImport should handle that for you?
<daurnimator> pixelherodev: not sure.. I'd have to actually play around myself
<daurnimator> traviss: sprunge.us/3EOkbC
<pixelherodev> `widget_t *button_create(const char *label, void(*handler)());` is translated into `pub extern fn button_create(label: [*c]const u8, handler: [*c]extern fn () void) ?*widget_t;`
<pixelherodev> Is that wrong?
<pixelherodev> If necessary, I can manually declare it for now or something
<pixelherodev> What type *should* be expected?
<daurnimator> pixelherodev: I think get rid of the [*c]
<daurnimator> (before extern)
<pixelherodev> And of course it's not as easy as editing the cimport.zig...
<traviss> thanks daurnimator. yes it does except for this get_ui which i need: `pub const __gmpz_get_ui = @compileError("function __gmpz_get_ui parameter has no name");`
discipulus has left #zig ["WeeChat 2.7"]
<pixelherodev> Temporary workaround: @intToPtr([*c]extern fn() void, @ptrToInt(load_tag)))
<traviss> so i'm just messing around trying to learn how to link these in and work around when i can't use translate-c
swoogan has quit [Ping timeout: 260 seconds]
<daurnimator> traviss: get_ui actually has an implementation in the header file
<daurnimator> traviss: seems like there are defines to only optionally have the header-version?
<daurnimator> traviss: probably worth opening an issue against zig to support them (if there isn't already an issue)
ur5us has quit [Ping timeout: 260 seconds]
ltriant has joined #zig
<pixelherodev> Do the formatting functions zero-terminate?
<pixelherodev> Because I'm getting behavior that seems to indicate otherwise
<daurnimator> pixelherodev: no
<pixelherodev> That's what I figured
<pixelherodev> Thanks!
<pixelherodev> If I manually zero terminate it works as expected (`{c}`, 0 in tuple), which is more than good enough
<daurnimator> yep :)
ur5us has joined #zig
<andrewrk> pixelherodev, you can also put \
<andrewrk> pixelherodev, you can also put \x00 in the format string
<pixelherodev> Right
ltriant has quit [Ping timeout: 268 seconds]
ur5us has quit [Ping timeout: 260 seconds]
ltriant has joined #zig
wootehfoot has quit [Read error: Connection reset by peer]
<traviss> daurnimator, this works for using __gmpz_get_ui https://clbin.com/CYG07 . i'll work on making an issue for this
ltriant has quit [Ping timeout: 240 seconds]
cota has joined #zig
ltriant has joined #zig
ltriant has quit [Ping timeout: 258 seconds]
<traviss> here is the issue daurnimator: https://github.com/ziglang/zig/issues/4130
<pixelherodev> What's the "canonical" way to convert a [*c]u8 to []u8?
<pixelherodev> std.mem.toSlice?
ltriant has joined #zig
ltriant has quit [Ping timeout: 258 seconds]
<traviss> i know this works for [*] if you know the length, ptr[0..len] but not certain about [*c]
watzon[m] has joined #zig
<pixelherodev> Right, but the length *isn't* known :P
<pixelherodev> It's coming from C code which could be asking for anything
<pixelherodev> It's the plugin's "do you support this feature" function
<pixelherodev> Takes a string and returns a boolean
<pixelherodev> 99% sure toSlice is what I wanted anyways
<pixelherodev> It has the intended behavior, but I wasn't sure what the idiomatic method was
<pixelherodev> But it's in zag so it probably counts
<pixelherodev> I'm passing a function pointer to C, which points to a function which takes a pointer as an argument
<pixelherodev> If I know that pointer will never be null, is there a way to override translate-c's assumption that the function pointer's parameter needs to be optional?
<pixelherodev> Alternately, why do function pointers passed to C need to be exported?
<pixelherodev> Ah, they don't; translate-c *thinks* they do
<pixelherodev> `@ptrToInt(struct {fn func() void {} }.func)` works, interestingly
<pixelherodev> But only for functions that take no parameters? That's... odd
<daurnimator> pixelherodev: toSlice is when the length is "whatever strlen returns"
<pixelherodev> Right
<pixelherodev> aka a C stringf
<pixelherodev> s/f//
SimonNa has quit [Quit: Leaving]
_Vi has joined #zig
ltriant has joined #zig
ltriant has quit [Ping timeout: 260 seconds]
bheads has quit [Quit: bheads]
_Vi has quit [Ping timeout: 248 seconds]
Snetry has quit [Ping timeout: 268 seconds]
ltriant has joined #zig
ltriant has quit [Ping timeout: 268 seconds]
ltriant has joined #zig
ltriant has quit [Ping timeout: 268 seconds]
return0e has joined #zig
dddddd has joined #zig
Astronothing has joined #zig
schme245 has joined #zig
<mq32> pixelherodev, can you export function pointers in structs to C?
<mq32> it didn't work for me yesterday :(
ltriant has joined #zig
ltriant has quit [Ping timeout: 258 seconds]
_Vi has joined #zig
<scientes> what is the status on anonymous functions?
<scientes> I run into situations where i could really use them
ltriant has joined #zig
<scientes> ahh figured it out
<scientes> by using a (manual) closure
ltriant has quit [Ping timeout: 260 seconds]
doublex has quit [Ping timeout: 260 seconds]
doublex has joined #zig
Astronothing has quit [Remote host closed the connection]
dimenus has joined #zig
traviss has quit [Ping timeout: 260 seconds]
<mq32> hey, can someone tell me how to use zig translate-c richt now?
<mq32> i'm using "zig translate-c sdk/adll.h", which does not output any errors, but otherwise doesn't do anything
<frmdstryr> Add --verbose-cc
<mq32> hm, it outputs me a clang call
<frmdstryr> Now run that
<mq32> oh :D
<mq32> fatal error: too many errors emitted, stopping now [-ferror-limit=]
<mq32> thanks, will try to get it to work
<daurnimator> Hrm. no zig support in highlight.js :(
<daurnimator> https://highlightjs.readthedocs.io/en/latest/language-requests.html <== where should we advertise/track such a task for zig?
<mq32> thanks frmdstryr!
ltriant has joined #zig
ltriant has quit [Ping timeout: 268 seconds]
dimenus has quit [Remote host closed the connection]
dimenus has joined #zig
dimenus has quit [Remote host closed the connection]
marmotini_ has joined #zig
dimenus has joined #zig
<mq32> hmm
<mq32> is there any good pattern for "custom" integer types?
<mq32> i have a library that uses a 22/10 fixed point type
<daurnimator> mq32: not really.., not as if you can overload operators
<mq32> yeah i know, that's a bit of my problem right now :(
<mq32> i don't want to use C++ for this, but it's not a pleasant experience with zig to work with this without any language support
<mikdusan> maybe an explicit sigil to indicate overloading: `var r = foo #+ bar;`. I admit it looks odd
<fengb> foo.@“+”(bar)
<mikdusan> for that matter, would `var r = foo .+ bar;` work? the space could be optional
bheads has joined #zig
Astronothing has joined #zig
<mq32> mikdusan, i don't think "operator overloading" as in general is required to solve my problem
<mq32> i would prefer to have an option to define one's own arithmetic types
<mq32> because that's the only valid use case for operator overloading anyways in my opinion
<fengb> What, you don't like << for output?
<mq32> please, i want + and - for booleans!
<mq32> bool b;
<mq32> +b; // set to true
<mq32> -b; // set to false
<mq32> and yes, there are libraries that do something like this :D
<mikdusan> ah so you're aiming for clarity
Akuli has joined #zig
<mikdusan> mq32: is the idea `arithmetic` is special to the compiler and add/mul/etc have documented mappings to arith operators?
<mq32> yeah that's the idea
<mq32> and you can later use fixed_22_10 like i32 or similar types
<mq32> altough we still have the problem of hidden function calls then
<Astronothing> is this a proof of concept for operator overloading?
<leeward> daurnimator: That patch you made for the logging_allocator bug, and I either never knew or forgot that Zig had multiline strings.
<mikdusan> mq32: I like that operator overloading isn't required and operators keep doing what is expected of them
<scientes> ahhhhh
<scientes> if you want operator overloading, just use methods instead of operators
<scientes> simple
<scientes> and avoids all the problems of operator overloading
<mikdusan> ()()()()
<scientes> if that is a problem, then the solution is to write allow to generate zig syntax trees at comptime, and then you can write a comptime interpreter
<scientes> to create DSLs
<fengb> Let’s all switch to s-exprs
<fengb> No more bickering!
<scientes> hungarian notation
<mq32> scientes, that doesn't solve my problem
marmotini_ has quit [Remote host closed the connection]
<scientes> yeah but what the hell is 22/10?
adamkowalski has joined #zig
<scientes> i get its fixed point
<scientes> but where is the point?
<scientes> i see the 1024, so 2 ^ 10
<mq32> 22/10 is 22 bit integer, 10 bit decimals
<mq32> so 32 bit type with 10 bit "precision"
<scientes> you mean 10 bits after the decimal point
<mq32> yeah
<scientes> so your function is actually wrong, you have to divide by (1024 * 1024)
<scientes> ohhhhh, I see
<scientes> confusing
<mq32> no, i don't
<mq32> if i multiply two values, they have 20 bit precision, so i have to right-shift by 10
<scientes> yeah I get it
<scientes> but that would give the number
<mikdusan> mq32: fwiw I have limited arithmetic needs, but I think your idea has promise. Lots of people have come-and-gone because it's a deal breaker for them to not have some kind of operator support for atypes
<mikdusan> s/atypes/userland atypes/
<scientes> fixed point is simple enough that it could just be supported with a new type attribute
<mq32> yeah, but there are more complex types
<scientes> however there is both binary and decimal fixed point
<mq32> like a floating point rational type
<scientes> mq32, that isn't floating point
<scientes> that is just a rational type
<scientes> floating point *is* rational, with a base two demoninator
<scientes> *exponent of two
<mq32> scientes, yeah, right
<mq32> i'm talking about the type iq described here: https://www.iquilezles.org/www/articles/floatingbar/floatingbar.htm
<mq32> it's a floating rational (which means nominator, denominator are variable width)
<mq32> scientes, my idea with the "arithmetic types" is to support somethin like the library i use
<companion_cube> overloadiiiiing
<mq32> it has 1800 API points where it expects the fixed-point-type
<mq32> ignoring all struct parameters that use that type too
<scientes> but seriously, overloading is a bad idea
<scientes> I presented two alternatives
<scientes> 1) just use methods
<mq32> "not using zig but c++ for more readable code"
<scientes> 2) create a DSL
<scientes> or 3) extend zig
<fengb> const c = magicMath("{} + {}", .{a, b})
<fengb> I think we could expose the format parser better and have that be reusable somehow
<scientes> doing a DSL in zig with an comptime interpreter->AST would be a great use case to explore
ltriant has joined #zig
<scientes> but comptime really needs a beef up for fancy stuff
<mq32> but it would not solve my problem, sadly :(
<mq32> or it would bloat my code by probably size 3 to 4
<scientes> hell, if we did it right you could write a plugin in zig, just by wrapping
<scientes> but I don't really want to think about that
<scientes> mq32, seriously, you are going to spend most of the time thinking about the algorithms and data structures
<scientes> as always, if you focus on the data structures, everything else will solve itsself
<mq32> no, as i'm writing a game
<mq32> so something like
<mq32> mx.x += 1;
<mq32> will be
<scientes> get it written, and then try to make it look better
<mq32> my.x = fp22_10_add(my.x, to_fp22_10(1));
<mq32> and pretty much ALL code looks like this
<scientes> well, as i said, fixed point might belong in the language
<scientes> it is not an unreasonable thing
<mq32> yeah
<mq32> but right now i'm goign to drop that project for beeing completly undoable in zig
<fengb> But which fixed point? There's not 1 golden standard
<mq32> at least when it comes to coding
<scientes> fengb, at least all binary and decimal fixed point
ltriant has quit [Ping timeout: 268 seconds]
<fengb> ... so I think you could write a parser that can bind comptime strings to functions and have it work
<scientes> it is all so similar you can just support it all
<fengb> My `magicFunc("{} + {} * {}")` might be possible to write generically. I don't think the guts would be pretty but it'd offer something for mq32
<scientes> and support multiplication and division between them (although i'm not sure what the return type should be)
<mq32> fengb, i don't think that would help much
<fengb> `my.x = magicFunc("{} + 1", .{my.x});`
<mq32> as i would still have to write at least twice the code than just do the fp-math everywhere manually
<scientes> mq32, that is what we have been saying
<scientes> you *think* you want operator overloading, but you really don't
<mq32> that's the point
<mq32> i don't want generic operator overloading, but more/custom arithmetic types
<mq32> because zig will never be able to handle all use cases of them
<mikdusan> I guess it still is operator overloading, but restricted to arithmetic operators
<mq32> scientes: with manually i mean "my.x += 1024 * 1;"
<Astronothing> @mq32 so you can't finish the game because you cant use fixed floating point with 10 bits of precision?
<mq32> Astronothing: i would like to code a game with zig and that engine
<Astronothing> what engine? what's wrong with floating point?
<mq32> but not having an arithmetic type, i have to do *every* arithmetic that interacts with the engine types (which is pretty much 95%) with function calls instead of +
<mq32> Astronothing, it's gamestudio a8
<mq32> it does not have floating point, but fixed point arithmetic
<mq32> i cannot change that, so i'm bound to that type
<Astronothing> ouch.
<mq32> i would LOVE to see that engine with f32 instead of fp22_10
<mq32> the C api actually exports that type as "long"
<mq32> and you have to do everything manually
<mq32> for C++ there is a wrapper class for the "var" type (that's how it's called in the engine)
<via> you could just wrap any literals in a function that multiples by 2^10, and then use normal arithmetic operations
<mq32> via: not for multiplication/division
<via> another function that multiplies/divides by 2^20 instead :p
<mq32> :P
<via> i guess you'd have to deal with overflow
<mq32> yeah but that bloats the code and pretty much hides all actual game logic
<via> native fixed point would be cool
<mq32> and makes the code unreadable
rageoholic has joined #zig
<fengb> Just port the game engine to Zig :troll:
<fengb> This isn't Slack
<mq32> fengb, i would love to, but it's closed source
<rageoholic> Hello! Been a while since I used IRC so sorry for any ettiquete breaches! I've been learning zig and having a lot of fun
<tgschultz> some kind of native support for fixed point might be generally useful for embedded dev too
<mq32> yeah that would solve my problem as well :D
<mikdusan> welcome rageoholic
<tgschultz> I'm still hopeful that zig can someday be used on retro hardware as well, where fixed could come in handy.
<fengb> Tangential, how should Zig work on Intel 8080 / Z80 when it comes to usize? u8 to match registers, or u16 to match memory
<tgschultz> usize is the size of a pointer, so 16.
<mq32> that's a question i want to make as a issue some time
<tgschultz> though segments would make that kinda....
<mq32> how to handle something like 8086 with 2 different kind of "usize" types
<mq32> where you have sizeof(uintptr)=3 and sizeof(size_t)=2
<mikdusan> is it 20 bits for addr?
<mq32> yeah :D
<mq32> that's why there is a differnece in C between uintptr_t (a type that can store a pointer uniquely/comparable) and size_t (the maximum size of an object in basic units)
<mikdusan> but explain why the naming is inconsistent: should be usize_t :)
<mq32> yeah :D
<mq32> also on AVR we get even more crazyness
<mikdusan> (ssize_t is just bad)
<mq32> 8 bit register size, 16 bit data bus size, 24 bit code bus size
<BaroqueLarouche> tgschultz: yes me too, I'd love to use Zig for Sega Genesis and Neo Geo projects
<tgschultz> well, the model will just never quite fit archs that aren't similar to the currently predominant model I guess.
<fengb> There's also some old 36-bit architectures :P
<tgschultz> same as zig will probably not ever work on esoteric arcs with non-po2 alignments
<mq32> there are a lo of crazy architectures
<mq32> 19 bit? go for it!
schme245 has quit [Remote host closed the connection]
schme245 has joined #zig
<tgschultz> For a project I'll probably now never get around to, I designed a 12-trit balanced ternary architecture.
<fengb> ... I didn't know PDP-7 was 18 bits
<mikdusan> (I can't resist) why use "tr" for the prefix instead of "t"
<tgschultz> for the obvious reasons
<fengb> Because it'd be ambiguous with thirteen?
<mikdusan> pretty sure zig will support PDP-7 when LLVM does
<fengb> Hey if we want to replace C, we need to retroactively remove it from history too
<rageoholic> Could always write an x86_64 to PDP-7 transpiler
<rageoholic> Actually wait didn't they do that for like the commodore 64?
<mq32> rageoholic, yeah but that doesn't work really well
<rageoholic> It's a fair cop
schme245 has quit [Ping timeout: 268 seconds]
<mq32> pretty much only for the showcase he did with it
<mq32> you cannot really model a one-register-arch with a many-register-arch
<rageoholic> Yeah that whole talk felt artificial as all hell
<fengb> Wow only 1 register? So math was directly from memory?
<mikdusan> accumulator
<mq32> fengb, yeah 6502 is an accumulator mcahine
<mq32> so you operate with memory all the time
<mq32> so "add addrX to ACC"
<tgschultz> 6502 assembly is pretty nice
<BaroqueLarouche> yes but not very suited for C style languages
<tgschultz> there's a reason the arch is still widely used
<tgschultz> that's true
<fengb> Back when memory wasn't balls slow :P
<BaroqueLarouche> the 65816 has stack-relative adressing for some opcodes
marmotini_ has joined #zig
<tgschultz> it's not that memory is so slow, it's just that processors are so ludicrously fast
<tgschultz> if you designed a more modern 6502, it would operate from an on-die cache primarily and you'd use a different opcode to populate the cache from bus memory.
<tgschultz> I love Spaceballs
<scientes> "light speed is too slow"
<rageoholic> This but unironically
<mikdusan> rip John Candy
schme245 has joined #zig
<tgschultz> I find it interesting and somewhat hope-inspiring that more people seem to be questioning long-held ways of doing things in computing. Jon Blow recently asked the same question I did a while ago about if we should really still be doing primarily pre-emptive multitasking in the age of multicore.
<scientes> tgschultz, what do your guys means by that?
<scientes> seL4 just implemented mixed-cricality real-time/non-real-time scheduling
<scientes> but still pre-emptive of course
<scientes> it is not like everyone has a 128-thread AMD chip
<tgschultz> well, it used to be that cooperative multitasking had the problem of one program freezing and stopping the universe. With multicore, you can ensure that at worst it only freezes other programs on the same core and the OS can terminate it, or move programs to other cores to accomodate.
<companion_cube> but why would cooperative multitasking be better?
<tgschultz> it's much simpler
<companion_cube> if you're not implementing a server that has to handle millions of connections
<companion_cube> is it, though?
<tgschultz> yes
<rageoholic> cooperative multitasking is more efficient but less reliable
<tgschultz> right, but we can mitigate the reliability problem now
<companion_cube> I find it a lot more complicated, it even requires language support to be ergonomic…
<rageoholic> In that if you don't yield you're starving out other tasks
<scientes> tgschultz, people are already doing that. CPU pinning is very common in big data to overcome limitations in the scheduler
schme245 has quit [Ping timeout: 260 seconds]
<scientes> including reserving those CPUs so that the kernel doesn't schedule there
<rageoholic> I would say losing a core for... let's put the timeout at 15 seconds.... is a huge deal
<tgschultz> yeah, but I'm wondering if that shouldn't be more the norm
<scientes> tgschultz, it has a DoS problem, if you don't stack with pre-emptive
<scientes> just like locking memory
<rageoholic> Within a process I would agree cooperative would be better
<scientes> its breaks the abstraction of pretending that a machine has infinite resources
<tgschultz> I can make computers unusable by abusing resources today too
<mikdusan> adaptive scheduler. if it learns there is a thread that doesn't yield, put it in the doghouse
<scientes> which is a very useful abstraction
<rageoholic> But between processes I still want a preemptive scheduler
<tgschultz> I question if it is a useful abstraction
<tgschultz> certainly zig doesn't seem to think that pretending there is infinite heap is a good idea
<scientes> I am kinda of the mind that it should just implement an infinite heap
<scientes> which is quite possible on 64-bit systems
<scientes> with swap
<scientes> *infinite stack
<tgschultz> I'm certainly not saying it is for sure a good idea, but I'm happy to see people questioning it. I think it is healthy to revisit old ideas and question your assumptions.
<scientes> tgschultz, well in places like seL4 all this stuff has to be not only thought about, but proven
<companion_cube> if you go full cooperative, at least do it in a clean way, like erlang
<companion_cube> (where it looks like it's preemptive!)
<scientes> companion_cube, yeah but if you are on top of an OS you still have the problems of preemptive
<scientes> at least if you want to target Linux (and who doesn't)
<companion_cube> such is life
<fengb> Let’s write our own OS. With blackjack and hookers
<companion_cube> at some point you'll be preempted, that's inevitable, be it by interrupts or by an angry user
<companion_cube> fengb: in fact, forget about the blackjack
<tgschultz> Been thinking about it. But today writing an OS is a fools errand unless you're targeting a very limited set of hardware (and even then, good luck trying to keep up with GPU).
<mikdusan> serial I/O. 115,200 baud.
<rageoholic> I s2g hardware vendors have been trying to ensure it's impossible to write an os
<tgschultz> So instead I've been thinking of trying to build a new userspace on Linux instead. Not ideal, but at least get drivers for free.
<fengb> Yeah, drivers can still barely work in Linux. Good luck getting a 4th party :P
<tgschultz> well, I'm still hopeful that if you build something people want to use, they'll want to develop for it too.
<tgschultz> and I think that wouldn't be too hard (for certain scales of hard), because the big three modern OSs are garbage fires in my opinion.
<fengb> What about one of the BSDs?
<tgschultz> I don't like certain aspects of BSD philosophy, similar to how I don't like some aspects of UNIX philosophy in general. Particularly, BSD has no stable ABI at all. At least Linux has that.
<scientes> tgschultz, if you tried to do it you would also end up with garbage
<scientes> its called making it work
<scientes> the "lets remake it to make it simpler and easier to understand" line has problems
<fengb> Ah that's the secret. To keep my OS great, I can't make it work 🙃
<tgschultz> possibly, but maybe it could be a lot less garbage, at least for the personal desktop computer usecase.
<mikdusan> I like how the millcpu team revisted things a bit and came up with a single-address-space model for their design
<scientes> mikdusan, the belt is super cool
<mikdusan> indeed
<scientes> except that writing a register allocator for it is kinda difficult....
<scientes> and it hasn't gone far in the last 8 years
<scientes> still vapor wear
<rageoholic> Single address space? Like no registers or no virtual memory
<rageoholic> Because virtual memory is a really good thing to have in a modern OS
<mikdusan> it can still swap but all "processes" share a 60-bit address space.
<scientes> what? that isn't true, mill cpus also have MMUs
marmotini_ has quit [Read error: Connection reset by peer]
<rageoholic> Having an MMU doesn't preclude having a flat address space
<pixelherodev> That's definitely true
<scientes> i still don't see what you are talking about
<rageoholic> But having a shared address space sounds..... eugh. I like my apps not being able to step on each other
<scientes> isn't x86_64 flat these days?
<tgschultz> Is there an argument against flat memory space other than ASLR?
<scientes> segmented was just a stupid idea
<rageoholic> I meant shared, not flat
Snetry has joined #zig
<mikdusan> rageoholic: they have an extensive protection model to adress threads/processes stepping on eachother
<rageoholic> Fair enough
<scientes> but MMU is the opposite of a shared address space.....????
<mikdusan> it's quite neat. I'd love to see it materialize into real hardware
<rageoholic> MMU just means that physical memory doesn't map to memory as seen by processors
<rageoholic> /s/processors/processes
<scientes> whatever, I'm pretty sure mikdusan is just talking about the very low end version without MMU
<mikdusan> afaik their entire line/architecture is based on SAS model
<scientes> mikdusan, there are also scratch registers
<scientes> but SAS is the fastest part
Snetry has quit [Ping timeout: 265 seconds]
<mikdusan> the scratchpad is a neat idea. I guess there are instructions and code indicates importance to cache a value which means no guessing by hardware
<scientes> SAS is way better because it can be reasoned about in a pipeline
<scientes> while registers really do not work well with pipelines
<scientes> as they requires gazillions of rename registers
<scientes> and complicated dependency analysis
<scientes> because of SAS, the mill does not need to be OOO
<mikdusan> that's a repeated message from mill: "rename registers" are bloat
<scientes> yeah, it doesn't have to be OOO to get similar performance
_Vi has quit [Ping timeout: 245 seconds]
<scientes> which means way less transistors
betawaffle has joined #zig
Snetry has joined #zig
<pixelherodev> Link?
<pixelherodev> I'm really interested suddenly
<mikdusan> from a '2013 talk by Goddard (mill computing) he mentions Haswell architecture they blow 50% of the power/circuit budget for (I think) rename-registers
mahmudov has joined #zig
adamkowalski has quit [Remote host closed the connection]
ltriant has joined #zig
return0e has quit [Ping timeout: 260 seconds]
ltriant has quit [Ping timeout: 260 seconds]
<pixelherodev> That's... that sounds implausible
<pixelherodev> But then again
<pixelherodev> This is Intel.
Astronothing has quit [Ping timeout: 240 seconds]
<mikdusan> to be fair I think this was not including the cache circuitry. basically everything between what he called "sources" and "sinks"
<andrewrk> fengb, usize is defined to match pointer size
<pixelherodev> Thinking about it, a static analyzer (like cppcheck) that identifies ways to optimize code for a specific architecture would be really really neat
<rageoholic> THe thing is if you can statically recognize how to optimize the code why not just go ahead and put that pattern into the optimizer
<pixelherodev> Obviously, compilers already do a looot on that end (at least with `-march=native`esque options
<pixelherodev> But I'm more interested in a program that goes into *why*
<rageoholic> Fair enough, I do wish optimizers were more... transparent with what they did and why
<tgschultz> well, it might not be a wise idea for the compiler to optimize things in such a way that it nolonger works how you think it does.
<rageoholic> True, although please tell the C++ compiler writers that
<pixelherodev> Nah, I disagree
<pixelherodev> As long as the *results* match for all valid code, it's fine
<pixelherodev> see e.g. -O3 on gcc
<pixelherodev> *If* your code is valid, -O3 is completely safe
<pixelherodev> If your code *isn't*, -O3 will make different assumptions about your code than you do
<pixelherodev> Hence I only ever use it with `-pedantic -Wall -Wextra -Werror`
<pixelherodev> When using those with -O3, I've yet to have a single issue where the compiler messed up
<pixelherodev> Not one
<pixelherodev> Anyways, I wasn't really talking for optimization purposes
<pixelherodev> I'm interested in a tool that goes into architectural details and explains *why* a pattern is more / less fast
<scientes> -O3 isn't that bad on llvm either
<scientes> gcc's -O3 is insane
<scientes> the vectorizer will mash your code into a nasty mess that isn't any faster
<scientes> pixelherodev, the compiler has such notes if you bother to read the code
<aperezdc> fun trivia: when targeting some small (for 2020) 32-bit ARM systems the code generated with -Os can sometimes be faster at runtime than -O2/-O3
<pixelherodev> aperezdc, Not surprised
<aperezdc> because less loop unrolling and more compact code reduces instruction cache pressure
<companion_cube> knowing if your code is valid is hard, though
<scientes> companion_cube, zig helps alot
<pixelherodev> scientes, right, but that's not convenient to look through if your goal is learning about the architecture and not the compiler
<aperezdc> and the branch prediction still does a decent job at keeping the i-cache well filled
<companion_cube> oh for sure, I was thinking about C and C++
<pixelherodev> companion_cube, like I said, `-Wall -Wextra -Werror -pedantic`
<pixelherodev> I've enabled those on code I'd thought was valid and fixed dozens of latent bugs in a matter of hours
<aperezdc> yeah, good code will be fine with any -Ox
<companion_cube> pixelherodev: does it tell you about all the places it assumes a pointer is null? :p
<pixelherodev> ?
<companion_cube> I'd rather have a language that isn't full of footguns
<aperezdc> the hard part is knowing well all the pitfalls of C (and undefined behaviors)
<pixelherodev> Sure, but *when working with C*, those are pretty good
<companion_cube> sure, that's still a very terrible experience :)
<pixelherodev> You know what would be neat? One of those learning site thingies that specifically tests you on language-specific footguns
<pixelherodev> Also, I disagree
<pixelherodev> It's not as nice as Zig
<pixelherodev> But it's better than most languages I've used
<companion_cube> in my taste, C is the worst (of the at least vaguely typed langs)
<pixelherodev> That's because it all comes down to personal preferences
<pixelherodev> The parts you hate and the parts I like can very possibly be the same, and that's completely okay :)
* shakesoda rather likes c
<shakesoda> zig happens to offer many of the things i like about c and fixes many of the things i hate, how nice :)
* pixelherodev does as well
<pixelherodev> Precisely!
<shakesoda> tentatively, i intend to move many of my projects to zig in the future
<shakesoda> i've only used it for toy projects so far
<andrewrk> makes sense given the instability
<shakesoda> yeah, language instability and translate c is a bit rough in cases i need still
<andrewrk> the recent self-hosting of translate-c was a major win though
<andrewrk> it's exciting that contributions to translate-c are now benefiting both stage1 and self-hosted
Astronothing has joined #zig
rageoholic has left #zig ["ERC (IRC client for Emacs 26.2)"]
<watzon[m]> Can I just say how happy it makes me that the zig documentation is dark?
<andrewrk> watzon[m], it's not always dark, it's respecting your preferences :)
<watzon[m]> Oh nice 😂 well thank you Firefox then
<watzon[m]> I've been away from front end dev too long I guess. I didn't know that media query existed.
<andrewrk> yes thank you firefox for implementing prefers-color-scheme correctly, and thank me for bothering to make both light and dark themes
<Astronothing> andrewrk I don't know how many sites implement it, but thank you for it!
<andrewrk> I'm happy with this css thing, it's finally something that makes sense and is good for users
<mikdusan> github are you listening? :)
<andrewrk> allowing users to express their preferences in one canonical location, and then allowing software to respect it. this is how it should be
<watzon[m]> Yes thank you very much andrewrk for the color scheme and everything else. Didn't realize you'd be active in here.
<watzon[m]> And I wholeheartedly agree
<terinjokes> one day I'll figure out how to enable it in Chrome on Linux
<companion_cube> I didn't find it in firefox :(
<terinjokes> fortunately, there's a toggle in the developer tools to temporarily enabling it for testing
<terinjokes> i added support for dark mode my zig project site earlier in the week
ltriant has joined #zig
return0e has joined #zig
ltriant has quit [Ping timeout: 265 seconds]
Snetry has quit [Read error: Connection reset by peer]
Snetry has joined #zig
<watzon[m]> I'm watching the stream from last week with the TranslateC tests. Cool feature to have in Zig.
<watzon[m]> I'm sad I missed yesterday's stream. Decided to get started with Zig too late.
Astronothing has quit [Ping timeout: 260 seconds]
<andrewrk> watzon[m], actually didn't do a stream yesterday, might do one today if I can get to a nice checkpoint with this branch I'm working on
Astronothing has joined #zig
<terinjokes> adding a function to os.zig, is there a recommended practice for what to do if the numbers of parameters differ across OSes?
<watzon[m]> Oh nice, so I didn't miss it! Well if you do one today I'll definitely tune in.
<andrewrk> terinjokes, what function is this?
<terinjokes> sendfile, i have a PR open for adding it on Linux (takes 4 parameters), but if I were to extend it for FreeBSD it takes 7
<Astronothing> andrewrk where are the streams announced? where do I join?
<terinjokes> (and 6 on macOS)
<andrewrk> Astronothing, if you subscribe to https://www.twitch.tv/andrewrok/ you can get an email when the stream starts. I usually start it 5-10 minutes early so people can join. they're also recorded and uploaded to youtube, so you can watch later if you miss it
<Astronothing> thank you!
doublex has quit [Ping timeout: 260 seconds]
<andrewrk> terinjokes, glancing at the freebsd man page, it looks possible to define an os.zig function API that is compatible with all the OS's
<andrewrk> e.g. you could code a shim for the hdtr arg on non-bsd systems, and document on which systems the headers/trailers are written atomically
<terinjokes> so accept the wider numbers of options drop the unused options based on builtin.os?
<andrewrk> not necessarily drop the unused options; e.g. I'm suggesting to make the headers/trailers work on all systems
<andrewrk> the flags argument is unused on freebsd and macos, looks like you can simply omit that parameter
<terinjokes> that makes sense, I can probably call out to writev on linux
<andrewrk> yes and then document on what systems the headers/trailers are atomic with the body
<terinjokes> the freebsd man page suggests flags is used, but I'm not currently looking at the source
<andrewrk> oh where do you see that?
<andrewrk> on http://nixdoc.net/man-pages/FreeBSD/man2/sendfile.2.html I see " The flags argument is currently undefined and should be specified as 0."
<andrewrk> ah that is a better authority
<terinjokes> which has four flags defined. the macOS man page does have the "must be 0" language though
<andrewrk> ok, yeah so take a flags parameter then, and rely on the caller to supply the correct value
<terinjokes> I can leave my PR for linux open in the meantime, I probably won't have a chance to extend it until this evening
<andrewrk> if someone accidentally uses a freebsd flag on macos, they will get error: struct 'std.os' has no member 'SF_NODISKIO'
<andrewrk> that SF_SYNC flag looks rather important
<andrewrk> I wonder if that is the default behavior of other operating systems
doublex has joined #zig
<terinjokes> interesting, I'll have to look and find out
adamkowalski has joined #zig
<watzon[m]> So structs can have default values for properties, but functions cannot currently, correct?
ltriant has joined #zig
ltriant has quit [Ping timeout: 265 seconds]
schme245 has joined #zig
<mikdusan> watzon[m]: yes, fn params cannot have defaults
<hryx> watzon: there was a (rejected) proposal https://github.com/ziglang/zig/issues/484
mahmudov has quit [Remote host closed the connection]
mahmudov has joined #zig
<watzon[m]> Hmm interesting. I understand the reason for not having default arguments, but it would be nice to have something similar. I know that structs can be used and provided as values to somewhat imitate that functionality, but in my opinion that doesn't make for very friendly APIs, nor does having multiple functions with different names that take differing numbers of arguments but all do the same thing
mahmudov has quit [Remote host closed the connection]
<watzon[m]> Having a well defined overload syntax could solve the same problem but maybe in a more friendly manner
mahmudov has joined #zig
<mikdusan> andrewrk: do you happen to remember which Visual Studio compiler version was used to produce: https://ziglang.org/deps/llvm/clang-9.0.0-win64-msvc-mt.tar.xz
ltriant has joined #zig
ltriant has quit [Ping timeout: 258 seconds]
<adamkowalski> watzon[m]: If you want default parameters you can simulate them quite easily
<adamkowalski> Just pass a struct to the function instead, give the struct field a default value
<adamkowalski> instead of overloading, you can accept a parameter by var and use reflection to determine features about it and then do something different for the different scenarios
<fengb> With anon functions, you can get almost keywords + almost defaults: `foo(.{ .arg = 1})`
<adamkowalski> I came from C++ so I loved overloading/template specialization, default parameter values, variadics. But Zig taught me that you don't need them, and you can write code which is easier to understand because of it
<adamkowalski> If you have a function name and you know what module it came from, you can go to the definition and you KNOW that will be the entry point
<adamkowalski> you don't have to reason about the rest of the file, everything must be scoped inside that function, that's where all the work happens
schme245 has quit [Remote host closed the connection]
mahmudov has quit [Remote host closed the connection]
schme245 has joined #zig
frmdstryr has quit [Remote host closed the connection]
schme245 has quit [Remote host closed the connection]
<andrewrk> mikdusan, I believe the wiki is in sync with that
mahmudov has joined #zig
Akuli has quit [Quit: Leaving]
<mikdusan> I was just looking into the `/Ob2` inlining bug and found it still exists with *latest* VS 2019 16.4.2, and 16.5.0 preview 1.0, and it occurred to me, what if the issue is building/linking against llvm+clang from an incompatible compiler. It's probably not that, just trying to rule it out.
<mikdusan> I'll just build my own llvm+clang and see what happens...
<mikdusan> (TIL editing an issue comment re-opens the issue)
_Vi has joined #zig
<andrewrk> mikdusan, I think it was open already, since it's still an issue
<mikdusan> ah sorry 'bout that. re-opened
<andrewrk> no worries
<andrewrk> thanks for looking into it
<hryx> silly idea: rename `[*c]T` to `[*ambiguous]T` or `[*autotranslated]T`
frmdstryr has joined #zig
<hryx> that is all. Doesn't affect me, just reading over the thread in #2984
<andrewrk> that's not a bad idea
doublex has quit [Ping timeout: 260 seconds]
<hryx> I can make a comment on the issue
doublex has joined #zig
return0e_ has joined #zig
return0e_ has quit [Remote host closed the connection]
ltriant has joined #zig
<fengb> `*or[*]or?*or?[*]` 🙃
<hryx> `[whatevenisthis]T`
ltriant has quit [Ping timeout: 268 seconds]
Astronothing has quit [Read error: Connection reset by peer]
schme245 has joined #zig
dimenus has quit [Ping timeout: 240 seconds]
marijnfs has joined #zig
<marijnfs> whats going on with 'warn', can't I use it anymore for a single string? warn("something\n") doesn't compile
<frmdstryr> it requires args
<frmdstryr> warn("somthin\n", .{})
_Vi has quit [Ping timeout: 245 seconds]
FSX is now known as assert
assert is now known as FSX
<marijnfs> ah ok, what does .{} stand for?
<frmdstryr> An empty tuple
<marijnfs> why was it changed to a tuple? So you can directly output a whole struct or whatever?
<marijnfs> btw how do I print say an integer now?
<mikdusan> marijnfs: `warn("hello {} I am {} years old\n", .{"world", 9});`
<marijnfs> hmm, that's quite a change
<hryx> marijnfs: it was removed because varargs were removed entirely from the language: https://github.com/ziglang/zig/issues/208
<companion_cube> ah yeah, varargs were removed
<marijnfs> ah interesting
<marijnfs> ahyeah, might wanna make it more prominent? Wouldn't have figured out without IRC
<marijnfs> also i used to be able to cast like f64(10)
<marijnfs> can't do it anymore?
<fengb> @as(f64, 10)
<hryx> marijnfs: That was also changed recently: https://github.com/ziglang/zig/issues/1757
<adamkowalski> marijnfs: I recommend going over the docs. The very first example demonstrates the new warn syntax
<adamkowalski> It's a fast moving language so I browse their regularly. The doc examples get tested with each push
<adamkowalski> If there is another place to post news like that i'm curious where'd you'd want to see them?
<marijnfs> thats even after the struct change
<fengb> The more comprehensive changelog gets written for the next version's release notes
<mikdusan> we don't really have a running changelog which is what I think marijnfs is wanting
<marijnfs> I would also make a big post somewhere on zig website maybe? latest big changes
<adamkowalski> that's not a bad idea, would that be on the homepage or just on github
<fengb> Yeah I think that'd be helpful but it is a lot of extra work
<marijnfs> yeah
schme245 has quit [Remote host closed the connection]
<marijnfs> but some example place that is prominent, and checked that it compiles
<adamkowalski> fengb: well we can maybe have something like the arch homepage. mostly quiet, but when there is a breaking change that requires intervention we can post there?
<fengb> Hmm, maybe just exposing the documentation diff would be helpful
<fengb> adamkowalski: there's been breaking changes almost every week since September. It's really crazy
<adamkowalski> marijnfs: the doc examples are compiled. I think that's the source of truth. Blog posts are unreliable for such a new language
<marijnfs> yeah
<adamkowalski> fengb: Yeah but I would rather have them now while we are before 1.0. And I think it would be simpler if the author of the breaking change added to the changelog as it happens? That way it's not a chore to do in bulk later?
<fengb> andrewrk's time is limited and docs are hard. He's more motivated with a writeup ~1 month before actual release
<adamkowalski> We could probably have an automated system that every time the doc examples break, we keep a diff between the two examples for 1 or 2 weeks?
<fengb> I think having a doc diff is pretty useful and minimally intrusive. Even if it's just to keep a simple git log since previous release
<adamkowalski> yeah thats a good idea! I also think this is one of those things we shouldn't even have to bother andrew with. we could run it by him, but we should start delegating to the community for non essential projects
<fengb> I don't want to pretend to speak for him, but I've asked for it in the past before and that was his response then :P
<marijnfs> A breaking changes history would be quite useful, although almost everything is a breaking change in some way.
<adamkowalski> fengb: is there a way to run a zig compiler on a file but not emit output? Just check for errors?
ltriant has joined #zig
<adamkowalski> I want to write a plugin for emacs to lint on save
<mikdusan> adamkowalski: maybe `-fno-emit-bin` ?
<adamkowalski> thanks! i'll try that. has anybody already done something like this btw? I don't want to duplicate efforts if there is an existing project. I know zig-lsp exists on github but it stopped working with a lot of the latest zig features like anonymous tuples
<adamkowalski> ideally we would just use the compiler for the source of truth
<fengb> I think detecting merged issues might be better than documentation, since it links to "why" instead of just "how"
<mikdusan> adamkowalski: there's also `cat foo.zig | zig fmt --stdin` which exits with error status
ltriant has quit [Ping timeout: 240 seconds]
<adamkowalski> wait really? that would be perfect since I wanted to run zig fmt on save anyway haha
<mikdusan> adamkowalski: andy's vim pack runs zig fmt when the file is written
<adamkowalski> yeah I might have to get inspired by that
<adamkowalski> There's no love for emacs yet though haha
<mikdusan> heh
<frmdstryr> wtf, does zig search for build.zig if it's not in the current folder?
<mikdusan> yes
<frmdstryr> it seems to, confused mre for like 30 minutes as to why it was loading the wrong code only to find out it built into a different folder
<mikdusan> it goes up the dir tree
<frmdstryr> can I make an output dir relative to the build file?
<frmdstryr> using setOutputDir(".") put's it in whatever folder you run build in
<frmdstryr> so if you happen to be in some nested folder it puts it in there
<mikdusan> hmmm... build_root ?
<frmdstryr> that works
<frmdstryr> thanks
ltriant has joined #zig
<frmdstryr> it still puts the cache folder in the nested dir
marijnfs has quit [Ping timeout: 258 seconds]
ltriant has quit [Ping timeout: 240 seconds]
adamkowalski has quit [Remote host closed the connection]
ltriant has joined #zig
ltriant has quit [Ping timeout: 258 seconds]
<mikdusan> I'm not sure setting output relative to a build.zig is a good idea. eg, `cd work; zig build --build-file /somwhere/build.zig` and putting a cache/artifacts in pwd is reasonable
<Snektron> The Zig ast works in a really weird way