Stream: contributing

Topic: Porting roc-pg


view this post on Zulip Bryce Miller (Jun 29 2026 at 14:08):

I’m interested in starting work on porting roc-pg to the new compiler, if that would be helpful.

A few questions:

  1. Are there any technical blockers/hurdles? For example, have package imports been implemented yet?
  2. @Agus Zubiaga Would you accept PRs and do you have time to review them?
  3. Does the following strategy sound reasonable?
    A. Make the minimum necessary changes to get it working.
    B. Evaluate whether any structural changes make sense given changes to Roc.

  4. Any other questions I should be asking? :sweat_smile:

view this post on Zulip Anton (Jun 29 2026 at 15:38):

For example, have package imports been implemented yet?

Package imports have been implemented.

view this post on Zulip Luke Boswell (Jun 29 2026 at 20:26):

Im finding things every now and then porting packages accross, but Im making GH issues and theyre getting resolved pretty fast. No known issues.

You can probably use the basic-webserver or basic-cli built from source off the migration PR branch ... there definitely some rough edges but the http stuff looks to be working ok.

view this post on Zulip Bryce Miller (Jun 29 2026 at 20:29):

I figured worst case I could just add TCP to my TigerBeetle platform. I’ll give basic-webserver a shot first though.

view this post on Zulip Bryce Miller (Jul 02 2026 at 14:06):

I recall seeing some kind of discussion on this topic before, but I'm not sure where the thread is.

In roc-pg there are some modules that are nested in directories. For example, Bytes.Decode, which is a Decode.roc file in a Bytes directory. These were previously imported as e.g. Bytes.Decode, which no longer works in current Roc.

In this case, There is decoding happening outside of the Bytes.Decode module, and Bytes.Decode just deals with decoding primitive types from lists of bytes, along with a few helpers. It seems the author's original intent here was to use the Bytes namespace to signal that this module doesn't handle all decoding, just the decoding primitives.

The cleanest thing I've found is to just move Decode.roc and Encode.roc up a level, and import them as Decode, Encode. Consumer modules are bringing lots of values into scope using exposing, so nesting these types under a Bytes type makes that a lot more clumsy:

import Bytes exposing [Decode]
i8 = Decode.i8
i16 = Decode.i16
# etc.

Another option I considered was using a name like DecodeBytes, though that makes the type name longer too.

I'm looking for suggestions on how best to organize modules here given Roc's current design. If I'm changing the organization from what it originally was, I want to make sure I'm thoughtful about it. :slight_smile:

view this post on Zulip Bryce Miller (Jul 02 2026 at 14:24):

Also, “It’s not a big deal, don’t worry about it too much” is an answer I will totally accept! I just don’t want to casually undo thoughtful choices Agus made if I’m going to submit a PR :sweat_smile:

view this post on Zulip Jared Ramirez (Jul 02 2026 at 14:34):

I believe the way to handle this now is to put them all into 1 module like:

# in Bytes.roc

Bytes := X.{
  # all top level byte fns

  Decode := Y.{
    # all decode-specific functions
  }
}

Then the user just imports Bytes and can do Bytes.Decode.i8 etc

view this post on Zulip Jared Ramirez (Jul 02 2026 at 14:40):

you could also define in a diff module like:

# Bytes.Internal.Decode
Decode := Y.{ ... }

then import & export it as an alias:

# in Bytes.roc
import Bytes.Internal.Decode as D

Bytes := X.{
  Decode :: D.Decode
}

view this post on Zulip Bryce Miller (Jul 02 2026 at 15:18):

Jared Ramirez said:

I believe the way to handle this now is to put them all into 1 module like:

# in Bytes.roc

Bytes := X.{
  # all top level byte fns

  Decode := Y.{
    # all decode-specific functions
  }
}

My instinct was to do exactly this, but then I realized that I'd need to update references to Bytes.Decode.i8 to be qualified, or do the clumsy assignment thing I mentioned above (which feels like something the language doesn't want me to do :sweat_smile:)

So instead of this:

import Decode exposing [await, map, u8, i32]
ProtocolBackend := [].{
    header : Decode({ msg_type : U8, len : I32 }, _)
    header = await(u8, |msg_type| map(i32, |len| { msg_type, len: len - 4 }))
}

I'd end up with this:

import Bytes exposing [Decode]
ProtocolBackend := [].{
    header : Decode({ msg_type : U8, len : I32 }, _)
    header = Decode.await(Decode.u8, |msg_type| Decode.map(Decode.i32, |len| { msg_type, len: len - 4 }))
}

I don't mind using the values fully qualified. I like the added clarity actually. Is this what would be considered idiomatic here?

view this post on Zulip Bryce Miller (Jul 03 2026 at 01:01):

Well, I was hoping to do the conversion without too many structural changes initially, but I see I have optional record fields to deal with too so I might just need to embrace the refactoring :sweat_smile:

view this post on Zulip Jared Ramirez (Jul 03 2026 at 03:48):

What you ended up with is idiomatic! I personally like things quantified tho

But if you really wanted to match the original style, you could have one line importing/exposing Bytes then another line importing/exposing Bytes.Decode

view this post on Zulip Bryce Miller (Jul 22 2026 at 22:52):

I think this is very close. Everything is type checking, but when I attempt to build or run using the latest main for basic-cli, it hangs on the specialization step.

I also have some remaining questions about API given the changes to the module system and addition of static dispatch, but I'll get it working first!

view this post on Zulip Niclas Ahden (Jul 22 2026 at 22:54):

Cool! I'm excited for this!

Perhaps this unblocks you temporarily? https://github.com/niclas-ahden/basic-cli/releases/tag/0.22.1

view this post on Zulip Bryce Miller (Jul 22 2026 at 22:54):

Hmm, I could actually give that a shot. I need to update my bitshifts anyway since they just changed.

view this post on Zulip Niclas Ahden (Jul 22 2026 at 22:56):

Yeah, and tomorrow's basic-cli will probably be back to working. I'll maintain my fork as necessary, but it's not a replacement for the real thing :)

view this post on Zulip Luke Boswell (Jul 22 2026 at 23:05):

I'm just waiting for https://github.com/roc-lang/roc/pull/10312 to land (which unblocks Glue for the platforms) -- and then I plan to manually trigger a fresh nightly

view this post on Zulip Luke Boswell (Jul 22 2026 at 23:06):

Then work on basic-cli is unblocked and I can continue merging in PR's etc

view this post on Zulip Luke Boswell (Jul 22 2026 at 23:07):

I hadn't realised the current RC doesn't work with the nightly... so I'll trigger a fresh RC too. There has been quite a few changes land in basic-cli already since the last RC

view this post on Zulip Bryce Miller (Jul 22 2026 at 23:15):

Yeah so I don't think the problem is the platform at all. still hanging on specialization

view this post on Zulip Bryce Miller (Jul 22 2026 at 23:15):

roc check is < 200 ms tho

view this post on Zulip Luke Boswell (Jul 22 2026 at 23:29):

If you can wrap it up in a bow (minimal repro) and post a GH Issue that will be most helpful. I've been finding issues like this for a while and Richard fixes them pretty quickly (often faster than it took me to find and isolate the bug report :sweat_smile: ).

view this post on Zulip Luke Boswell (Jul 22 2026 at 23:29):

Then it usually just takes a few days for the fixes to flow through CI into a nightly etc

view this post on Zulip Bryce Miller (Jul 22 2026 at 23:30):

Yeah last time I encountered this he (or Jared) had it fixed in a flash! Might take me a bit to get a repro though, I'm not sure where to start :sweat_smile:

view this post on Zulip Bryce Miller (Jul 22 2026 at 23:31):

Maybe I can throw some tokens at it

view this post on Zulip Bryce Miller (Jul 22 2026 at 23:52):

view this post on Zulip Bryce Miller (Jul 23 2026 at 00:24):

#10327

Non blocking, as I can actually reorder definitions to make the issue go away.

view this post on Zulip Bryce Miller (Jul 23 2026 at 00:25):

And it works!
Screenshot 2026-07-22 at 8.24.48 PM.png

view this post on Zulip Luke Boswell (Jul 23 2026 at 00:45):

basic-webserver should be usable if you build from source

view this post on Zulip Luke Boswell (Jul 23 2026 at 00:45):

https://github.com/roc-lang/basic-webserver/pull/163


Last updated: Jul 23 2026 at 13:15 UTC