Hi there,
I'm still trying to get AoC 2025 Day 01 to work.
I was missing List.split_on and List.map_try so I tried to implement them.
It took me a while but I managed to have zero compilation error or warning. However, I'm getting a segfault now:
Here's my full program:
app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.3/98T93wthPgoBRLYtPTT4RBBsQunrfDG94gihPf1zYYmE.tar.zst" }
import pf.Stdout
data =
\\L50
\\L12
\\R13
\\L1
\\L5
\\R5
parse_instruction: List(U8) -> Try(I32, _)
parse_instruction = |chars| {
match chars {
[] => Err(ParsingError)
[c, ..rest] => {
num_str = Str.from_utf8(rest)?
num = I32.from_str(num_str)?
if c == 'L' { Ok(-num) } else { Ok(num) }
}
}
}
count_zeroes: List(I32), I32, U32 -> U32
count_zeroes = |instructions, pos, count| {
match instructions {
[] => count
[inst, ..rest] => {
new_pos = pos + inst
new_count =
if new_pos % 100 == 0
count + 1
else
count
rest->count_zeroes(new_pos, new_count)
}
}
}
split_on: List(a), a -> List(List(a)) where [a.is_eq : a, a -> Bool]
split_on = |elements, delimiter| {
help = |remaining, chunks, current_chunk| {
match remaining {
[] => chunks.append(current_chunk)
[x, ..rest] => {
if x == delimiter {
help(rest, chunks.append(current_chunk), [])
} else {
help(rest, chunks, current_chunk.append(x))
}
}
}
}
help(elements, [], [])
}
map_try: List(a), (a -> Try(b, c)) -> Try(List(b), c)
map_try = |list, to_result_fun| {
list->walk_try(
[],
|state, elem| {
match to_result_fun(elem) {
Ok(ok) => Ok(state->List.append(ok))
Err(b) => Err(b)
}
}
)
}
walk_try: List(a), s, (s, a -> Try(s, c)) -> Try(s, c)
walk_try = |list, init, func| {
match list {
[] => { Ok(init) }
[val, ..rest] => {
maybe_state = func(init, val)
match maybe_state {
Ok(state) => walk_try(rest, state, func)
Err(b) => Err(b)
}
}
}
}
main!: List Str -> Try({}, Exit)
main! = |_args| {
maybe_instructions = data.to_utf8()->split_on('\n')->map_try(parse_instruction)
match maybe_instructions {
Ok(instructions) => {
result1 = instructions->count_zeroes(50, 0)
Stdout.line!(result1.to_str())
Ok({})
}
_ => Err(Exit(1))
}
}
Here's the segfault:
error: Child process /Users/ageron/Library/Caches/roc/e59c636351ad64c25ba81dca340f7248/temp/roc-tmp-9Tj9smFRS15c5UvOO30epYt9BZ2CYQ9G/roc_run_994723065 killed by signal: 11
error: Child process crashed with segmentation fault (SIGSEGV)
I'm running the latest code compiled from source (Roc compiler version debug-b578eea3).
Thanks for your help!
Is that type annotation on main correct? main!: List Str -> Try({}, Exit)
I think it should be
main! : List(Str) => Try({}, [Exit(I32)])
Oh good point, thanks. I commented it out and still got the segfault
Are you able to post a copy of your cli running roc check roc test and roc ...
Sure. Here's roc check:
-- BAD LIST REST PATTERN SYNTAX ------------------
List rest patterns should use the `.. as name` syntax, not `..name`.
For example, use `[first, .. as rest]` instead of `[first, ..rest]`.
┌─ /Users/ageron/dev/roc/aoc2025-roc/day01.roc:18:13
│
18 │ [c, ..rest] => {
│ ^^^^^^
-- BAD LIST REST PATTERN SYNTAX ------------------
List rest patterns should use the `.. as name` syntax, not `..name`.
For example, use `[first, .. as rest]` instead of `[first, ..rest]`.
┌─ /Users/ageron/dev/roc/aoc2025-roc/day01.roc:30:16
│
30 │ [inst, ..rest] => {
│ ^^^^^^
-- BAD LIST REST PATTERN SYNTAX ------------------
List rest patterns should use the `.. as name` syntax, not `..name`.
For example, use `[first, .. as rest]` instead of `[first, ..rest]`.
┌─ /Users/ageron/dev/roc/aoc2025-roc/day01.roc:47:17
│
47 │ [x, ..rest] => {
│ ^^^^^^
-- BAD LIST REST PATTERN SYNTAX ------------------
List rest patterns should use the `.. as name` syntax, not `..name`.
For example, use `[first, .. as rest]` instead of `[first, ..rest]`.
┌─ /Users/ageron/dev/roc/aoc2025-roc/day01.roc:76:15
│
76 │ [val, ..rest] => {
│ ^^^^^^
roc test gives a segfault:
zsh: segmentation fault roc2 test day01.roc
Not sure whether it matters but I'm using a symlink named roc2.
I tried replacing ..rest with .. as rest, and now roc check gives no error, but I still get the segfault.
My guess is the segfault is refcounting related... shouldn't be too hard to find.
If you're interested to explore yourself, you can build roc with refcount tracing zig build roc -Dtrace-refcount and if you build a debug version of the zig platform template it also has refcount tracing... then when you run you will get a detailed trace of every allocation (incref/decref)
Cool, thanks Luke
I normally feed that trace into claude and a few moment later have narrowed down which builtin isn't following the correct ownership semantics
Write a test to reproduce, then fix, then verify etc... :smiley:
A couple questions:
.. as rest or ..rest in the new compiler?builtins currently implemented https://github.com/roc-lang/roc/blob/bb17e26f7bd1aa51ce8e18a2a795eab9d07369a9/src/build/roc/Builtin.roc#L4
about the rest thing... I'm not sure -- the discussions are many and so these things get blurry. I would look into the code, or maybe try it out on a smaller test program.
I ran zig build roc -Dtrace-refcount and now when I run roc day01.roc I get:
[REFCOUNT] INCREF list (copyToPtr) ptr=0x101460018 len=1 rc=1 slice=0 elems_rc=1
error: Child process /Users/ageron/Library/Caches/roc/e59c636351ad64c25ba81dca340f7248/temp/roc-tmp-2q9ZB7TrXASkuFMITQ3Xqvx7AXG5qNWK/roc_run_994723065 killed by signal: 11
error: Child process crashed with segmentation fault (SIGSEGV)
and if you build a debug version of the zig platform template
How can I do that?
Clone the template repository, then zig build you can also do zig build native which is quicker because it only builds the libraries for your current system and doesn't cross-compile for all the supported os/arches
Use a relative path to the ../roc-platform-template-zig/platform/main.roc in your test app
I'll try that after lunch, thanks Luke.
Last updated: Dec 21 2025 at 12:15 UTC