<blinghound>
I've got a tagged union of 20+ ui widget types, they all share common functions, and at the moment I've got a seperate switch statement for every common function, switching on the union tag, to then call the type specific function with the same name
<blinghound>
is there a pattern I can use to avoid having to write a huge switch statement for every common function?
ur5us has quit [Ping timeout: 244 seconds]
<blinghound>
or some comptime magic to automatically write it?
<andrewrk>
blinghound, alexnask[m] is the wizard of this particular use case
blinghound has quit [Ping timeout: 245 seconds]
ur5us has joined #zig
<waleee-cl>
wasn't it him that used code generation with python or something along those lines?
<ifreund>
this is an educated guess, I didn't actually try it
<danyspin97>
ifreund: it works, thanks!
<ifreund>
no problem
<danyspin97>
how can I copy a struct from stack to heap?
<danyspin97>
I have Struct but I need *Struct
<ifreund>
const ptr = allocator.create(Foo);
<ifreund>
ptr.* = foo;
<ifreund>
you can also just take the address of your struct on the stack, but be careful with the lifetime
<leeward>
*argument that implicit struct copy via = shouldn't work*
<leeward>
But it does.
<ifreund>
leeward: My ideal would be allowing the "copy" with = whenever that copy can be optimized away with result location or whatever
<fengb>
*retort that all assignment is copying so it's not really implicit
<ifreund>
and if it can't be then require some std.mem.foo or a builtin
<leeward>
ifreund: Yeah, that's a fair compromise, but a little harder to reason about.
<danyspin97>
ifreund: yea, that's why I didn't use &
<leeward>
fengb: It's true that it's not really implicit, but it is a common footgun: I know I've shot myself with it.
<ifreund>
leeward: I agree, it's inconsistent
<fengb>
New operator for memcpy?
<ifreund>
:=.
<fengb>
lol
<fengb>
#5076 flashbacks
<ifreund>
exactly :D
<ifreund>
man I am slowly making progress on this wasm backend
<ifreund>
hopefully I'll be able to put up a PR this weekend
<danyspin97>
hurray, just finished benice :)
<ifreund>
is any software ever truely finished? :P
<danyspin97>
at least, 0.1 is xD
<fengb>
:o
<fengb>
That's so much more progress than I pump out
<danyspin97>
i still need to understand async in zig
<danyspin97>
that could be a nice improvements
<ifreund>
first release is definitely a good milestone
<ifreund>
still not quite there with river, though I've been dogfooding it for over a month now
euandreh has joined #zig
dingenskirchen has quit [Quit: dingenskirchen]
dingenskirchen has joined #zig
dingenskirchen has quit [Client Quit]
dingenskirchen has joined #zig
cole-h has joined #zig
Ashpool has quit [Quit: Leaving]
waleee-cl has joined #zig
<danyspin97>
and just by adding -Drelease-fast, the program broke xD
<leeward>
Does it still work in -Drelease-safe?
<danyspin97>
leeward: my bad, the problem is not related to -Drelease-fast
<leeward>
Well, that's probably a good thing.
<leeward>
Optimizer bugs are hard to track down.
<gruebite>
what does this mean? expected type '(bound fn(i32, i32) anyerror!void)', found 'fn(i32, i32) anyerror!void'
<gruebite>
i'm assuming my default function pointer being assigned is determining the anyerror type and thus can't be reassigned
<ifreund>
could you paste the code snippet somewhere?
<Nypsie[m]>
I assume first you assign it something like var myFunc = struct.func and later you try to reassign it doing myFunc = someFunc
<Nypsie[m]>
In the former, the first function is a bound function
<Nypsie[m]>
* In the former, the function is a bound function
<leeward>
Is "bound function" defined anywhere in the docs?
<gruebite>
yeah, after simplifying it made more sense
<gruebite>
and that was it
<Nypsie[m]>
I'm probably wrong here but I believe all non-global functions are bound functions.
<Nypsie[m]>
i.e. they're bound to a struct
<leeward>
Aren't files structs?
<fengb>
Only things accessed as methods are bound
<Nypsie[m]>
Yeah true actually
<Nypsie[m]>
Ah there we go, Fengb to the rescue :P
<leeward>
So it's about how they're called?
<ifreund>
there is one reference in the docs, grep for BoundFn
<fengb>
And it's kinda deceptive because they aren't really bound in the FP sense >_>
<ifreund>
not a very useful reference though :D
<leeward>
And...BoundFn appears in a list saying @Type is unavailable for it.
<Nypsie[m]>
Aaah, so if you'd do myFunc(struct, 5) instead of struct.myFunc(5) it's no longer considered a bound function?
<leeward>
Definitely doesn't count as being defined.
<gruebite>
i was thinking something akin to interfaces would be just checking if variables exist. if we had lua function call syntax for non delcaration functions like foo:myfunc() it could work :P
<gruebite>
there's likely way better ways though
<ifreund>
@hasDecl()
<gruebite>
runtime i'm thinking
riba has joined #zig
dingenskirchen has quit [Remote host closed the connection]
riba has quit [Ping timeout: 260 seconds]
edr has quit [Ping timeout: 264 seconds]
<ifreund>
andrewrk: I'd like to store some wasm-specific info in Decl similar to the already present link/fn_link fields
<ifreund>
should a make a union over Elf and Wasm specific stuff or do we need to support both at the same time?
edr has joined #zig
<andrewrk>
ifreund, here's an idea for that: make it an untagged union with a field for ELF and a field for Wasm
<andrewrk>
so the "tag" is implied by the target object format rather than stored redundantly in the union (although in zig safe modes will have a hidden safety field)
<ifreund>
andrewrk: sounds good to me, thanks!
<ifreund>
hmm, might to a quick PR doing only that to make the upcoming wasm PR less noisy
<andrewrk>
makes sense to me
<andrewrk>
the only other consideration here is if the amount of data needing to be stored is significantly different than for ELF, we can get more creative with the memory layout so that one object format does not cause the other one to have to pay the memory usage cost per Decl
<andrewrk>
if they're nearly the same amount of memory, then probably an untagged union is simplest
<ifreund>
Not entirely sure how much I'll need for wasm yet, shouldn't be more than what's already there for elf though I think
<andrewrk>
anyway the idea would be that when allocating a Decl, it would allocate a variable amount of memory depending on the object format, so accessing the "link" field would be trailing the rest of the Decl and of a size that is implied by the object format of the compilation
<andrewrk>
but yeah I think starting with untagged union is a good start
edr has quit [Ping timeout: 240 seconds]
edr has joined #zig
<andrewrk>
I have a fun (standard library related) surprise for everyone today :)
<Nypsie[m]>
Hit it :)
<ifreund>
ArrayList -> Vec?
<andrewrk>
gotta get it working on windows first
<Nypsie[m]>
Such a tease haha :P
edr has quit [Ping timeout: 256 seconds]
edr has joined #zig
dermetfan has quit [Ping timeout: 244 seconds]
<ifreund>
man, the stage2 tests run so damn fast
pmwhite has quit [Remote host closed the connection]
<andrewrk>
yeah all you have to do is wait for stage1 to build the test harness, haha
<andrewrk>
it's been a long time coming. feels bad to promise fast compiler speed and then not deliver for a long time
pmwhite has joined #zig
<andrewrk>
I have a bunch of experiments I want to do to make stage2 even faster, but I want to set up performance tracking benchmarks first
<andrewrk>
that was one of the main motivations of ziglang/gotta-go-fast
GreaseMonkey has joined #zig
<ifreund>
Yeah, also would be good to bench more realistic programs once it gains enough features
r4pr0n has joined #zig
<andrewrk>
agreed
<andrewrk>
still some big design decisions to solve too. each one represents a potential compromise of perf, and therefore will have to be very carefully considered. possibly even with some language modifications, if it means a fundamental difference in the achievable compilation speed
<andrewrk>
affecting the "best theoretical compilation speed" is a valid reason to make language changes, in my opinion
<andrewrk>
there are things that inherently affect the best theoretical perf of a compiler, regardless of any particular implementation's details
<andrewrk>
for example I think swift is doomed to be slow for some kinds of things because it has to do some advanced multi-variable equation solving to figure out the type system
<andrewrk>
which is kind of ironic when you consider the name of the language
<ifreund>
heh, I think I saw a blog post on that recently
<andrewrk>
zig is also doomed to be slow if you use @setEvalBranchQuota(9999999) and then make a giant comptime while loop. but that's a bit more intentional by the programmer
<andrewrk>
also, incremental compilation goes a long way to mitigate this
<pixelherodev>
*cough* JITed comptime *cough*
<pixelherodev>
Or even just static loop detection
<leeward>
Do you care if Zig is slow when building release-*?
<pixelherodev>
e.g. `comptime while (i < 10000000) : (i += 1) {}`
<leeward>
Ooh, ooh, solve the halting problem for comptime.
<pixelherodev>
We could discard empty body loops, for instance
<andrewrk>
leeward, not nearly as much. clearly there is still a limit on how slow it can be before it compromises the usefulness of the build mode, but it is allowed to be several orders of magnitude slower
<andrewrk>
I think our rule of thumb for debug safety checks is that they are allowed to cause 100x slowdowns, but not more than that
<ifreund>
incremental compilation also doesn't make sense for release builds
<leeward>
^^
<andrewrk>
agreed
<pixelherodev>
Disagreeed
<pixelherodev>
disagreed*
<pixelherodev>
There's one valid use I can think of
<leeward>
It's not like the parse tree takes a lot of time to generate.
<pixelherodev>
If you want to optimize a hot-loop, for instance
<pixelherodev>
It's useful to be able to test performance changes on-demand
<ifreund>
i don't think you can draw any meaningful conclusions from an incrementally compiled binary
<pixelherodev>
In other words, there's a situation in which you could reasonably use release builds while developing
<pixelherodev>
ifreund: not with the current backends, sure
<ifreund>
the codegen is too different and introduces a lot of overhead/bloat
<leeward>
It's totally true that release builds can be useful while developing, and if it were practical to do incremental release builds it would make sense. But it's not, so it's not worth the tradeoff.
<pixelherodev>
Agreed, yeah
<pixelherodev>
Incremental release builds would be a whole different ballpark, and aren't worth the effort
<pixelherodev>
Might be useful to allow for a binary which an adjusted _start, though
<pixelherodev>
e.g. have it run a single specified function and then exit
<pixelherodev>
That would be a small frontend tweak instead of requiring a full additional backend
<leeward>
May as well build it in userland.
<pixelherodev>
That's what I was thinking, actually - it'd be a build.zig + start.zig integration, probably
<pixelherodev>
`zig build -Drun_function=foo` for instance
<pixelherodev>
Could be a distinct build step from the normal one
dermetfan has joined #zig
<andrewrk>
leeward, in the traces I've been doing so far, creating the parse tree is something like 33% of the total compilation time
<andrewrk>
the way zig models optimizing a hot loop is that you would compile in debug mode, but use @optimizeFor(.release_fast) in the hot loop
<andrewrk>
it's also planned to be able to pick .release_fast for packages other than the main application, and .debug for the main application. so you'd get incremental compilation but with release builds for your dependencies
<ifreund>
I can't wait
<gruebite>
best way to represent an enumeration of bitflags?
<leeward>
33% either means Zig takes a lot of time to parse or it's compiling really fast.
<gruebite>
i want to put them in an enum. perhaps a namespace struct instead?
<ifreund>
your suggestion on the PR I just opened makes sense, the only thing I'm struggling with is a more generic name than TextBlock which makes 0 sense for wasm
<ifreund>
could just do something non-descriptive like LinkDeclData, but that's also flawed
<leeward>
Per-block (and per-package) build mode sounds useful, but aren't packages source? How do you not rebuild the release-fast bits every time?
<ifreund>
magic I guess :P
<andrewrk>
leeward, it could be both, meaning there is potential for even more speed :D
<andrewrk>
leeward, the beautiful thing about leaving memory layout of most types and calling convention of most functions unspecified is that the compiler has the power to choose arbitrary conventions in order to facilitate exactly this use case :)
<andrewrk>
so the compiler identifies the boundaries between debug and optimized builds, and picks an arbitrary (but consistent) ABI for itself to use
<andrewrk>
which is how incremental compilation works anyway
<fengb>
packed struct of u1 works great if you make sure the size is to power of two. Otherwise you'll run into some nasty packed bugs
<ifreund>
do you even need to make it packed?
<fengb>
Yeah, otherwise u1 take up at least 1 byte
<andrewrk>
ifreund, align(0) would mean it doesn't have to be packed
<ifreund>
ah, I see
<gruebite>
bitflags are used in boolean expressions. doing packed struct { flag1: u1 } means i have to do: str.flag1 == 1
<gruebite>
or is u1 a special case and i can use it in boolean expressions? :P
<fengb>
You can do packed bool
<fengb>
Also a one bit
<gruebite>
packed bool is u1?
<fengb>
Yep
<gruebite>
nice
<andrewrk>
if you make all the fields have default 0/false values you can then only set the flags you want
<gruebite>
yeah
<gruebite>
can i print unicode (u32) characters?
<gruebite>
{c} is ascii which won't accept u32
<gruebite>
looking std.unicode right now
<gruebite>
and a way to uppcase unicode :D
<andrewrk>
unicode-aware upcase/downcase is often an underestimated challeng. it depends on human culture, which is constantly changing
<companion_cube>
aren't there tables for that? normalization and all?
<andrewrk>
yeah but you have to get them from somewhere, and they have to be maintained with human labor. it's a dependency
<fengb>
Can we have an async frame resumed by mechanical turk 🤔
<andrewrk>
no problem if that's what you need. but it's good to double check that you want to add a dependency on that
cole-h has quit [Quit: Goodbye]
waleee-cl has quit [Quit: Connection closed for inactivity]
toppo has joined #zig
<andrewrk>
ifreund, #5997 looks good. if you tell me you tested it locally I'll merge it before waiting for CI
<andrewrk>
`./zig build test-stage2` should suffice
<ifreund>
All 1 tests passed.
<ifreund>
./build/zig build test-stage2 0.04s user 0.02s system 81% cpu 0.065 total
<gruebite>
what's zig's solution to compile time library configuration? like: #define FOO_MAX 2 #ifndef FOO_MAX #define FOO_MAX DEFAULT #endif
dermetfan has quit [Ping timeout: 260 seconds]
<ifreund>
well, you have a lot of freedom really
<ifreund>
you can check for values set in the root soruce file using @hasDecl()
<ifreund>
you can also pass in options through the build system using build_options
<gruebite>
nice, and branch on that
<andrewrk>
yeah just be careful with addBuildOptions, I think the implementation needs to be taught about a few more types
<andrewrk>
I fixed strings recently
<ifreund>
I've only ever used bools :D
<gruebite>
there should be an xor keyword
toppo has quit [Quit: Leaving]
<gruebite>
for logical xor
<fengb>
There’s a proposal
<gruebite>
:D
<fengb>
Although logical xor is the same as “foo != bar”