Stream: compiler development

Topic: opaque type Encoding/Decoding derivation


view this post on Zulip Notification Bot (Jul 27 2026 at 19:24):

Dzmitry Misiuk has marked this topic as unresolved.

view this post on Zulip Dzmitry Misiuk (Jul 27 2026 at 19:30):

Following up: the bare encoder_for : _ / parser_for : _ derives fine for an opaque over a record, but not for one over a primitive — the validated-newtype case, e.g. a Username := Str carrying a min-length that should drive its codec and its schema from one declaration:

Username := Str.{ encoder_for : _ }
expect Json.to_str(Username.("ada")) == "\"ada\""   # nightly: {}   main: panics (encoder_for selected an unsupported shape)

The derived parser panics the same way.

The cause is small: shapeContent peels the nominal to its backing, a record backing hits a shape the encoder/parser already handle, but a primitive backing hits a scalar they don't. I have a fix — peel one layer, encode/parse the backing, wrap/unwrap the value across the .nominal boundary (mirrors the record path; ~85 lines, minici green, JsonEncodeRoundTrip still passes).

One call for you: peel or reject? I did peel — support it, consistent with records, and it's format-generic (a derived encoder_for : _ on a non-JSON custom format works too, so it helps any Encoding codec, not just JSON). If you'd rather reject-for-now, I'll flip it. Happy to open a draft PR whenever you want the diff.

view this post on Zulip Richard Feldman (Jul 27 2026 at 19:31):

that's a bug, can you open a GitHub issue for it?

view this post on Zulip Richard Feldman (Jul 27 2026 at 19:31):

I can implement the fix, no problem

view this post on Zulip Dzmitry Misiuk (Jul 27 2026 at 19:40):

Opened: https://github.com/roc-lang/roc/issues/10425 — repro, root cause, and the suggested fix (both halves) are in there. I've got a working patch too (minici green) if it saves you time, but all yours.

view this post on Zulip Dzmitry Misiuk (Jul 31 2026 at 18:15):

Opened a PR for #10425: https://github.com/roc-lang/roc/pull/10495 — covers the infallible scalar backings, with the fallible-float bit flagged as a follow-up. All yours to take or land.

view this post on Zulip Dzmitry Misiuk (Aug 01 2026 at 12:10):

Follow-up to #10495: the fallible-float boundary is now closed at the checker — Money := F64.{ encoder_for : _ } gets the same clean TYPE MISMATCH as a bare F64 instead of panicking. PR: https://github.com/roc-lang/roc/pull/10519

view this post on Zulip Richard Feldman (Aug 01 2026 at 12:36):

@Dzmitry Misiuk let's not do Money := F64 - Dec should always be used for money! :smile:

view this post on Zulip Dzmitry Misiuk (Aug 01 2026 at 13:35):

Ha, fair — renamed the example to Ratio := F64 Latitude := F64 (Dec for money, noted :smile:). The rejection behavior is the same.


Last updated: Aug 12 2026 at 12:35 UTC