Stream: beginners

Topic: new compiler: `roc test` with common util functions


view this post on Zulip Rick Hull (Jan 31 2026 at 01:08):

I am developing an application with the new roc compiler. I have some type modules that call common utility functions (i.e. different type modules reusing the same common functions). this seems to make roc test unhappy. is this by design? these are all pure functions

view this post on Zulip Luke Boswell (Jan 31 2026 at 01:08):

roc test shouldn't be unhappy about anything... have you found a bug?

view this post on Zulip Rick Hull (Jan 31 2026 at 01:11):

i feel like I'm Doing It Wrong, but i've tried all kinds of things. let's say I have parse.roc with some pure functions defined, that take strings and return numbers. then a type module like Wager, that has a parse method (or function) which calls functions defined in parse.roc (ignore capitalization issues; i have been trying all kinds of different module organizations). what's the simplest thing that definitely should work?

view this post on Zulip Rick Hull (Jan 31 2026 at 01:13):

the parse utility functions do things like parse_u32('1234') => U32 (let's say) and then Wager or several other types in different modules need to call parse_u32 on different things

view this post on Zulip Rick Hull (Jan 31 2026 at 01:14):

this "parse utility file" has a few objectives: includes unit tests; is importable or callable from other files; these other files should have unit tests as well.

view this post on Zulip Rick Hull (Jan 31 2026 at 01:16):

what's good new compiler application to reference? i have been using basic-cli (migrate-zig-compiler) but this is showing more platform-style organization

view this post on Zulip Luke Boswell (Jan 31 2026 at 01:37):

$ roc example_app.roc
dbg: Ok([1])
dbg: Ok([1, 2, 3])
dbg: Err(NotANumber)
dbg: Err(NotANumber)
dbg: Ok([4, 2])
$ roc test Parser.roc --verbose
All (4) tests passed in 37.1 ms.
PASS: Parser.roc:24
PASS: Parser.roc:25
PASS: Parser.roc:26
PASS: Parser.roc:27

Parser.roc

# a Roc type module includes a single nominal type
Parser := {}.{

    # this is an function associated with the Parser type
    # e.g. "12" -> [1,2]
    parse_digits : Str -> Try(List(U8), [NotANumber])
    parse_digits = |str| {
        bytes = Str.to_utf8(str)
        bytes.fold(Ok([]), |acc, byte| {
            match acc {
                Err(e) => Err(e)
                Ok(digits) => {
                    if '0' <= byte and byte <= '9' {
                        Ok(List.append(digits, byte - '0'))
                    } else {
                        Err(NotANumber)
                    }
                }
            }
        })
    }
}

expect Parser.parse_digits("12") == Ok([1,2])
expect Parser.parse_digits("abc") == Err(NotANumber)
expect Parser.parse_digits("123") == Ok([1,2,3])
expect Parser.parse_digits("1234") == Ok([1,2,3,4])

example_app.roc

app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.6/2BfGn4M9uWJNhDVeMghGeXNVDFijMfPsmmVeo6M4QjKX.tar.zst" }

import pf.Stdout
import Parser

main! = |_args| {
    dbg Parser.parse_digits("1")
    dbg Parser.parse_digits("123")
    dbg Parser.parse_digits("NotADigit")
    dbg Parser.parse_digits("0.1")
    dbg Parser.parse_digits("42")
    Ok({})
}

view this post on Zulip Rick Hull (Jan 31 2026 at 01:40):

This should help! Taking rhe dogs for a walk rn ...

view this post on Zulip Luke Boswell (Jan 31 2026 at 01:42):

Rick Hull said:

what's good new compiler application to reference? i have been using basic-cli (migrate-zig-compiler) but this is showing more platform-style organization

There isn't any examples or documentation yet -- aside from the bits and pieces in the langref/ ... the new compiler isn't a very friendly place for beginners right now and there are unimplemented or buggy things lurking around every corner.

view this post on Zulip Luke Boswell (Jan 31 2026 at 01:43):

The more we try and build real things though we can find the issues and fix them one by one... so it's very helpful when people try things out and report any issues or questions.

view this post on Zulip Rick Hull (Jan 31 2026 at 02:00):

@Luke Boswell big help, thanks! we (me and claude) were using [].{...} not {}.{...} what are the implications?

view this post on Zulip Luke Boswell (Jan 31 2026 at 02:00):

Both should work...

view this post on Zulip Luke Boswell (Jan 31 2026 at 02:01):

[] is an empty tag union, {} is an empty record, both are zero sized types.

view this post on Zulip Rick Hull (Jan 31 2026 at 02:05):

i think we found a bug, but compiler is like 10 days old; continuing to test and narrow down; will get the latest nightly

view this post on Zulip Rick Hull (Jan 31 2026 at 02:06):

For now:

The bug is precisely: inside a {}.{...} type method at comptime, once a different method
is called on one parameter (e.g. a.to_u64()), subsequent access to the other parameter
(b) loses scope. to_str doesn't trigger it — likely because it's the same builtin method
called on both, so the comptime evaluator doesn't context-switch the same way.

grabbing a newer compiler to retest

view this post on Zulip Rick Hull (Jan 31 2026 at 02:12):

https://gist.github.com/rickhull/289ef29265d182ada8accc81957fd93a # latest roc-nightly

view this post on Zulip Luke Boswell (Jan 31 2026 at 02:17):

Rick Hull said:

https://gist.github.com/rickhull/289ef29265d182ada8accc81957fd93a # latest roc-nightly

looks like a bug to me, can you make a GH issue?

view this post on Zulip Rick Hull (Jan 31 2026 at 02:36):

we were able to repro a segfault repeatedly, at address 0xblahblah, supposedly ASCII 'tosh'; unable to repro for now

view this post on Zulip Rick Hull (Jan 31 2026 at 02:40):

● Bash(roc test src/ParseUtil.roc --verbose 2>&1)
  ⎿  Error: Exit code 139

     Segmentation fault (SIGSEGV) in the Roc compiler.
     Fault address: 0x74736f68

     Please report this issue at: https://github.com/roc-lang/roc/issues

● THERE IT IS! The segfault! When Value.parse_sexp (a type method) calls tokenize (a
  module-level function with fold) at comptime IN THE SAME FILE, it segfaults!

  But wait - spike/Value.roc works with the exact same structure. Let me compare the two
  more carefully:
● This is a deep compiler bug. For now, we have a working version in spike/Value.roc and
  the copy in ParseUtil_minimal.roc. The full ParseUtil.roc segfaults for reasons we
  haven't identified yet.

  Summary for you: We've hit a Roc compiler bug that causes segfaults when type methods
  call module-level functions at comptime. We've identified that fold-based tokenize works
   (avoiding for/var), but there's still a segfault in the full ParseUtil that doesn't
  occur in the minimal spike/Value.roc version. We have working code we can build from,
  but debugging the compiler bug itself would require more investigation.

view this post on Zulip Rick Hull (Jan 31 2026 at 02:58):

it looks like there are 3 bugs, and initial suspicion is that they are all specific to roc test

view this post on Zulip Luke Boswell (Jan 31 2026 at 02:59):

If you log a GH issue with the files to minimally reproduce, that would be helpful.

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:00):

It should be easy enough to fix I think. I'm looking at some other bugs rn

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:00):

roc test hasn't had any love in months

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:01):

It hasn't been upgraded to use the new coordinator, so that could be related here

view this post on Zulip Dan G Knutson (Jan 31 2026 at 03:26):

Questions about the single-nominal-type-per-file syntax:

  1. Is it fair to treat Builtin.roc as sort of a bible for this pattern, other than the special ProvidedByCompiler constructor?
  2. Are multiple top-level type declarations (or nominal type declarations) intended to be a compile error now?

view this post on Zulip Dan G Knutson (Jan 31 2026 at 03:27):

I'm wondering if a windows-specific bug I'm running into working on the glue command is actually a case of 2 not being treated as a compile error when it should be an error.

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:37):

I recently added the error for not having a top level nominal type... I dont think I added one for multiple top level nominal types.

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:37):

It should be an error

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:38):

I would say Builtin.roc is probable the best example, aside from the annotation only parts the compiler implements internally

view this post on Zulip Rick Hull (Jan 31 2026 at 03:43):

https://github.com/roc-lang/roc/issues/9117
https://github.com/roc-lang/roc/issues/9118
https://github.com/roc-lang/roc/issues/9119

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:45):

For reference type modules should be named with an uppercase, like Bug3.roc not bug3.roc -- and match the name of the type they exposing

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:46):

See https://github.com/roc-lang/roc/blob/main/langref/modules.md

view this post on Zulip Rick Hull (Jan 31 2026 at 03:47):

this was just iterating on getting a minimal repro, not necessarily realistic; would it matter here?

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:48):

The compiler shouldn't segfault, and should give helpful error messages... so if we find any situation where it doesn't that's a bug

view this post on Zulip Luke Boswell (Jan 31 2026 at 03:48):

I thought I'd mention that in case it unblocks you

view this post on Zulip Dan G Knutson (Jan 31 2026 at 04:06):

I'm not sure how I would go about reproducing it, but without the error for multiple type declarations in a file, we get fun stack corruption on windows. Might be worth figuring out how to avoid that even if we won't hit this specific case any more.


Last updated: Feb 20 2026 at 12:27 UTC