Stream: compiler development

Topic: Recursive Types with List


view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 19:44):

What would it take to make each of these two types work?

Node : [Branch Str (List Node)]
Node : (Str, List Node)

Fundamentally, I think both of these should be valid. Also, both of them are semi-common issues that users have hit in various cases.
Would these me something that I could just dive into? How complex is the code? Any general thought on path forward/how to implement?

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 19:54):

Do we know what the specific issue is?

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 19:54):

I'm actually kind of surprised at least the tag case doesn't work

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 19:54):

Oh wait.... Is this just never allowed in roc because it would mean that an end user could create a reference cycle which would break roc automatic memory management?

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 19:55):

How could they create a reference cycle? I think since the language is pure and eager it's impossible to create a cycle

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 19:57):

Oh yeah, would end up creating a copy in the case I was thinking it would cycle...nvm

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 20:00):

For Node : (Str, List Node), we say that it needs to be a tag (which in my opinion is wrong, List should count as a break and make that valid)

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 20:01):

Node : [Branch Str (List Node)] -> Actually, this works. I think I had messed something else up when testing before.

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 20:04):

Ok. So then I guess the target feature would be allow recursive types if either

  1. They are through tags
  2. They are through List (given Dict is based on List, it should also be covered)

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 20:04):

And 1 already works.

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 20:04):

I wonder if this is mostly just a case of making the type checker more lax.

view this post on Zulip Richard Feldman (Nov 08 2023 at 20:05):

yeah I also thought this already worked

view this post on Zulip Richard Feldman (Nov 08 2023 at 20:05):

but apparently not!

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:04):

yeah, the fix for the tuple case should be pretty straightforward

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:05):

I guess this probably doesn't work either, right?

W : List W

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:05):

but that should pass as well (poor man's linked list)

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:06):

(or, poor man's natural number)

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 21:41):

Cool. I'll look into it. Hopefully it is just a matter of allowing more things in some sort of recursive check or something

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:45):

You'll probably want to look where https://github.com/roc-lang/roc/blob/5fed22405b347707b59fc3ac7608e1e7bb2068e4/crates/compiler/can/src/def.rs#L3282-L3290
is being called in that file, and update the branches that lead to the call site

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:45):

Although, this may end up being trickier than it seems

view this post on Zulip Ayaz Hafiz (Nov 08 2023 at 21:46):

Because changing the restriction is easy, but then the type-checker also needs to be updated to support recursion in a position that's not a recursive tag union

view this post on Zulip Brendan Hansknecht (Nov 08 2023 at 21:47):

Yep


Last updated: Jul 06 2025 at 12:14 UTC