So I was wondering if others had ideas on how to improve a functions like this:
popAddr : Emulator -> [T Emulator Addr]
popAddr = \emu0 ->
T emu1 lo = pop emu0
T emu2 hi = pop emu1
T emu2 (toAddr lo hi)
It seems pretty poorly suited for pipelining due to the first 2 functions returning more results than the next function takes. That being said, I feel like there has to be a way to make this better than having emu0
, emu1
, emu2
. Any thoughts?
if pop
returns a record like { emu : Emulator, addr : Addr }
then you could go:
popAddr : Emulator -> { emu : Emulator, addr : Addr }
popAddr = \emu ->
lo = pop emu
hi = pop lo.emu
{ emu: hi.emu, addr: toAddr lo.addr hi.addr }
Would that end up duplicating the underlying emulator? Or should roc clean that up correctly recognizing that even though lo.addr
is used later, lo.emu
is not and can allow in place mutation.
interesting - I'm not sure!
This becomes very important when updating memory. Otherwise any random operation can suddenly be copying a 64KB list.
I guess I will give that a test and count the allocations.
I hope someday the editor visualizes memory performance per line :)
That would be nice. Though you have a slight problem that a line might be performant 95% of the time until you call it with a list that isn't unique. This is part of the reason I really want to be able to write expect (unique myList)
But also, having the editor track that would be great. Have it tell you. This list was copied because back on line 52 it became shared. We theoretically should be able to do that analysis.
Exactly! Show the risky call stacks that a line is involved in :D
Last updated: Jul 05 2025 at 12:14 UTC