I'd love to start implementing some of the missing builtin List functions in the new compiler, but I need some input / direction before I start.
The rust compiler's List builtin exposed 79 functions, whereas the zig compiler exposes 33 functions for List. I understand that there are some differences in philosophy regarding API design since moving over to the new compiler, so some of these may no longer relevant or desired. I think a few few seem quite important, and others are much lower priority or perhaps not wanted at all.
Please advise, and I would be happy to start tackling some of these!
Analogues with different names are grouped in the same row and noted with (≈name).
| Category | Rust (crates/.../List.roc) |
Zig (src/build/roc/Builtin.roc) |
|---|---|---|
| Length / emptiness | len, is_empty |
len, is_empty |
| Element access | get |
get |
| Element mutation | set, replace, update, swap |
Missing: set, replace, update, swap |
| Append | append, append_if_ok |
append — Missing: append_if_ok |
| Prepend | prepend, prepend_if_ok |
Missing: prepend, prepend_if_ok |
| Constructors | with_capacity, single, repeat, range |
with_capacity, single, repeat — Missing: range |
| Concatenation | concat, join, intersperse, concat_utf8 |
concat, join_with (≈join) — Missing: intersperse, concat_utf8 |
| Reversal | reverse |
rev (≈reverse) |
| Endpoints | first, last |
first, last |
| Take / drop | take_first, take_last, drop_first, drop_last, drop_at, drop_if |
take_first, take_last, drop_first, drop_last, drop_at, drop_if |
| Membership | contains |
contains |
| Equality | — | is_eq (Zig extra — no Rust analogue) |
| Predicates over list | any, all, count_if |
any, all, count_if |
| Find | find_first, find_last, find_first_index, find_last_index |
Missing all 4: find_first, find_last, find_first_index, find_last_index |
| Map | map, map_with_index, map_try, map_try!, map2, map3, map4, join_map, join_map! |
map — Missing 8: map_with_index, map_try, map_try!, map2, map3, map4, join_map, join_map! |
| Filter | keep_if, keep_if_try!, keep_oks, keep_errs |
keep_if — Missing: keep_if_try!, keep_oks, keep_errs |
| Walk / fold | walk, walk!, walk_backwards, walk_until, walk_backwards_until, walk_try, walk_try!, walk_with_index, walk_with_index_until, walk_from, walk_from_until |
fold (≈walk), fold_rev (≈walk_backwards) — Missing 9: walk!, walk_until, walk_backwards_until, walk_try, walk_try!, walk_with_index, walk_with_index_until, walk_from, walk_from_until |
| Reductions | sum, product, min, max |
sum — Missing: product, min, max |
| Sort | sort_with, sort_asc, sort_desc |
sort_with — Missing: sort_asc, sort_desc |
| Sublist | sublist |
sublist |
| Splitting | split_at, split_first, split_last, split_on, split_on_list, starts_with, ends_with |
Missing all 7: split_at, split_first, split_last, split_on, split_on_list, starts_with, ends_with |
| Each (effects) | for_each!, for_each_try! |
for_each! — Missing: for_each_try! |
| Chunks | chunks_of |
Missing: chunks_of |
| Capacity tuning | reserve, release_excess_capacity |
Missing: reserve, release_excess_capacity |
| Encoding / decoding | — (handled via Encode/Decode abilities, not on List) |
encode, decode (Zig extras — no Rust analogue on List) |
is_eq, encode, decode (3)Some personal priorities / suggestions for a starting place would be:
yeah all of those in that list sound good!
let's not do effectful versions yet
Never proud of stale PRs, but you can look at https://github.com/roc-lang/roc/pull/9306 which was my go at addig set, replace and subscript methods. I've managed to implement these on my linux machine, things worked, but CI failed on some targets, like windows and I won't be able to continue it. Feel free to do whatever you want with the PR, continue it, disregard it, copy the revelant parts from it onto your own branch. I just hope it will get used somehow. @Ian McLerran
I can have a look at the Windows issues tomorrow.
Thx luke. It was 1.5 month ago and I don't know how much has changed since then. I won't be able to dive back into the code, as my non-internet life needs me. Appreciate it, just setting the expectations.
Thanks, @Norbert Hajagos! I'll take a look! I've built prepend and set so far, but I'd love to pull in some already completed work on replace and subscript.
PS: Sorry Norbert - I don't know how I missed your open PR for this! Didn't mean to steal your thunder! 🤦🏻♂️
It looks like @Ian McLerran has picked up the changes in his PR if I'm reading that correctly. I'm still happy to have a look at Windows if you need. I've currently got that machine booted in Linux running through the zig 16 migration issues, but can switch across and have a look whenever we need.
I've pulled several of Norbert's changes into my PR. My PR is running through CI right now, so we'll see what happens when we get to windows checks.
Ian McLerran said:
PS: Sorry Norbert - I don't know how I missed your open PR for this! Didn't mean to steal your thunder! 🤦🏻♂️
Naaah, I'm glad it wasn't left in the dust. I've had other PRs like that and I always feel bad because of them.
Looks like you're blazing through the List builtins! If you have found something useful in the PR you've incorporated, flagging that single commit with "Co-authored-by: ...." is more than enough. That's my thunder :smile:
Once you've merged in, I'd be interested in the solution. Can you drop a message here for me?
Haha alright, glad to hear that. I blazed through a bunch of them that were pure roc, which I had already implemented in a library. I yanked some of your code too, so I was able to hit the ground running fast. Having Claude around doesn't hurt either! :wink:
I will definitely let you know what the solution is once I get there... I'm still failing in CI right now!
@Luke Boswell If you've got time for an assist, I'd love a little help trouble shooting CI here. I'm failing in the zig workflow check-once check.
It fails at zig build test-playground -Doptimize=ReleaseSmall -- --verbose, with 14/15 pass, 1 fail. However when I run locally on macOS, the same command passes 15/15.
I don't think I will have time to help today but some useful info: CI runs that on ubuntu 22.04
Well I reproduced on macOS now, so its not limited to Ubuntu.
I didn't have the -Doptimize=ReleaseSmall flag when I checked that yesterday on an earlier CI run.
Claude's summary of a cursory investigation into the CI failure:
| Test | Result |
|---|---|
| Main (origin/main, no changes) | 15/15 ✓ |
| PR (all changes) | 14/15, fails on Variable Redefinition |
| PR with only Builtin.roc reverted | 15/15 ✓ |
AI Hallucination alert (claude's investigation)
I am certain that we don't want to replace the wasm_allocator, and of course claude could be way off base, but I thought I'd post this here as background info for anyone looking into the issue.
@Ian McLerran zig build minici passes on my Linux ubuntu x64 machine
I forgot to try zig build test-playground -Doptimize=ReleaseSmall -- --verbose
Further detail:
REPL Variable Redefinition - Dependency Updates traps with TrapOutOfBoundsMemoryAccess on the 5th REPL_STEP under
-Doptimize=ReleaseSmall. Passes in Debug. Reverting the Builtin.roc
additions to main passes 15/15.
Investigation so far:
playground_exe.initial_memory to 256 MB — no change. std.heap.WasmAllocator: has free-list reuse per power-of-2 size class, not a pure bump allocator.Parsed the playground.wasm memory section: min=57 pages, no max declared
(bytebox defaults max to 65536 pages / 4 GB). So the trap is a real load/store OOB, not ceiling exhaustion.
Added @wasmMemorySize(0) probes throughout compileSource and runReplExpression, and bumped the WASM debug log buffer from 4 KB to 32 KB so the trap log isn't truncated.
What the probes show on the failing run:
compileReplInspectedModule on the first expression eval; the second expression's compileReplInspectedModule only adds 2 pages.compiled.deinit(allocator) - specifically lowered.deinit → RuntimeImageProgram.shm.deinit(allocator). The first compiled.deinit completes normally; only the second one traps.I'll take a look at this now
Claude is still working on it, I am going out for dinner, I will probably push a fix tomorrow.
Claude gave up, I asked it to make a prompt for itself for a clean start, and I now put it on max reasoning.
Claude keeps struggling, can you try codex on this one @Richard Feldman?
To reproduce, run this on PR#9440:
$ zig build test-playground -Doptimize=ReleaseSmall -- --verbose
I can take a look at this tomorrow :thumbs_up:
Last updated: May 23 2026 at 12:51 UTC