I saw that tuples to records desugaring is planned. I'm curious, aren't records always "wrapped", meaning they impose some (minimal, but still) memory usage overhead? Or does Roc optimize records to erase fields information when it's not needed at runtime?
What do you mean by wrapped?
I would compare tuples to C structs, in that they only contain the values and nothing else. Because with records I can pattern match on a subset of fields, and this code should work for all kinds of records that have these fields, I would imagine there is some additional memory needed for records (this is what I mean by "wrapped") so that at runtime each field name points to appropriate place in memory. Or is it optimized away when never needed for some particular record value?
Oh, that is all compile time
They are all compiled to c structs
Pattern matching knows byte offsets and expect values at compile time
Then for a row polymorphic function, how does it work for different records that might have the matched fields at different offsets? Are there multiple versions of this function at runtime? Or is there some type-offsets mapping saved somewhere in the program, and at runtime offsets are chosen based on some tag passed from callsite?
I believe it is like templated/generic functions where there is a version for each concrete type
A single Roc function can compile to many assembly functions, one for each record type
That answers my question and is good to know, thank you!
Michał Łępicki has marked this topic as resolved.
yeah - tuples, records, and single-tag tag unions all have zero memory overhead on top of the values they store
also they all compile to the same thing, so there's no runtime performance difference between using one over another
*non recursive single tags?
oops, yes - good point :big_smile:
although I guess in that case it's technically still true :thinking:
Not quite. Refcount
oh true, fair enough!
Richard Feldman said:
yeah - tuples, records, and single-tag tag unions all have zero memory overhead on top of the values they store
Does monomorphization count as memory overhead? You need to generate multiple functions and those functions do need to be stored in memory. I guess this isn't counted because it's a really tiny amount of constant overhead?
it does count as overhead. depending on how much you have it can sometimes be a problem (for example, if you have many specialized functions you are calling, the likelihood one’s code is in an instruction cache is much lower)
but in general it is reasonable to assume that the overhead is lower than using boxed values and dispatching at runtime based on the boxed type representation
yeah, so no memory overhead
but there are other performance considerations than that!
just to be pedantic there is also memory overhead right. like you have to load the binary, if there is more code there will be more to load
ha, also fair
so in the sense of like - the function itself has memory overhead
even if the data structure itself doesn't
If the function doesn't have memory overhead the datastrutures would need to. Also, the function would need to be dynamic at runtime which would make it bigger and have overhead. So umm...i think we are just debating pedantic details.
well yes, but that's fun :big_smile:
fair
Last updated: Jul 06 2025 at 12:14 UTC