I implemented zig allocators in my platform lol
app [main!] { pf: platform "../platform/main.roc" }
import pf.Stdout
import pf.AllocHost
main! : List(Str) => Try({}, [Exit(I32)])
main! = |_args| {
Stdout.line!("Testing poke/peek with Try-based alloc...")
# Allocate 4 bytes - returns [Ok(U64), OutOfMemory]
alloc_result = AllocHost.alloc_impl!(4)
match alloc_result {
OutOfMemory => {
Stdout.line!("Allocation failed: OutOfMemory")
Err(Exit(1))
}
Ok(ptr) => {
Stdout.line!("Allocated 4 bytes.")
# Write "Roc!" using poke
AllocHost.poke_impl!({ byte: 82, ptr: ptr })
AllocHost.poke_impl!({ byte: 111, ptr: ptr + 1 })
AllocHost.poke_impl!({ byte: 99, ptr: ptr + 2 })
AllocHost.poke_impl!({ byte: 33, ptr: ptr + 3 })
Stdout.line!("Written 'Roc!' to memory.")
# Read back using peek
c1 = AllocHost.peek_impl!(ptr)
c2 = AllocHost.peek_impl!(ptr + 1)
c3 = AllocHost.peek_impl!(ptr + 2)
c4 = AllocHost.peek_impl!(ptr + 3)
Stdout.line!("Read back: ${Str.inspect(c1)} ${Str.inspect(c2)} ${Str.inspect(c3)} ${Str.inspect(c4)}")
# Expected: 82 111 99 33 = "Roc!"
Stdout.line!("Expected: 82 111 99 33")
# Deallocate
AllocHost.dealloc_impl!(ptr)
Stdout.line!("Deallocated. SUCCESS!")
Ok({})
}
}
}
Cool! Note, I have never issued a malloc(), ever. However, in my reading, it seems that malloc/free is really a bad pattern unless you need it, and that arena allocation is probably a better starting point, depending on context, or else never-free-and-quit (not for long-running processes, obviously; but web workers can quit once the request is cleared).
It was mostly satire since roc is not memory managed
RIP me :laughing:
Last updated: Feb 20 2026 at 12:27 UTC