Stream: beginners

Topic: recursive closures


view this post on Zulip Nick Hallstrom (Mar 25 2023 at 21:57):

Is there anyway around this or am I just out of luck for now?
recursive closures

view this post on Zulip Brendan Hansknecht (Mar 25 2023 at 21:58):

Can you avoid having a recursive closure and instead just have a recursive function?

view this post on Zulip Nick Hallstrom (Mar 25 2023 at 22:01):

I'm not sure if there's an easy way to do that. I'm messing with some parser combinator stuff

# Will parse any number of '-' followed by a single '+'
recurTest = plus |> map List.single |> orElse (prepend minus recurTest)

view this post on Zulip Brendan Hansknecht (Mar 25 2023 at 22:05):

Ah, since recurTest is passed to the prepend function, it has to be a closure and can't be a normal recursive function.

view this post on Zulip Brendan Hansknecht (Mar 25 2023 at 22:06):

I would guess there would be a way to rewrite such that just for this function it doesn't follow parser combinators but more directly parses, but I'm not sure if that would mix with the rest of your parser stuff.

view this post on Zulip Brendan Hansknecht (Mar 25 2023 at 22:07):

But yeah, you may be out of luck with this error. Not completely sure though.

view this post on Zulip Ayaz Hafiz (Mar 25 2023 at 22:10):

do you have a small reproduction?

view this post on Zulip Ayaz Hafiz (Mar 25 2023 at 22:10):

this should have been fixed a while ago. I can try to patch it now

view this post on Zulip Nick Hallstrom (Mar 25 2023 at 22:13):

Ya sure! One sec and I'll push it

view this post on Zulip Nick Hallstrom (Mar 25 2023 at 22:16):

Here's where I'm getting the error. It's not exactly small though :sweat_smile: I'll try and minimize it
https://github.com/Billzabob/roc-lox/tree/466b693816e0121034bf2bb9ea67bafcecf72cc4

view this post on Zulip Brendan Hansknecht (Mar 25 2023 at 22:17):

If this useful. It will also hit the issue and is pretty minimal:

app "helloWorld"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.3/5CcipdhTTAtISf4FwlBNHmyu1unYAV8b0MKRwYiEHys.tar.br" }
    imports [ pf.Stdout ]
    provides [main] to pf


factCPS = \n, cont ->
    if n == 0 then
        cont 1
    else
        factCPS (n - 1) \value -> cont (n * value)

main =
    factCPS 6 \x -> x
    |> Num.toStr
    |> Stdout.line

view this post on Zulip Nick Hallstrom (Mar 25 2023 at 22:21):

Here's my minified example, although I'm sure Brendan's is much more useful
https://github.com/Billzabob/roc-lox/tree/1a4612126b31cccd09f917665e867e5bc69b42b5

view this post on Zulip Ayaz Hafiz (Mar 25 2023 at 23:40):

wow, this is a fun bug! Im out of time for today but I'll make a patch tomorrow or Monday; in the meantime the branch fix-non-nullable-unwrapped-recursive-lset should unblock you.

view this post on Zulip Nick Hallstrom (Mar 25 2023 at 23:43):

I’ll give it a try! Thank you so much Ayaz! You’re always coming in clutch 💪

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 03:34):

Finally got to trying this Ayaz. It gave me a massive error:
Screenshot-2023-03-26-at-9.33.28-PM.png

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 03:36):

You can try it on the code in my minimal example link to reproduce it.

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 03:38):

I actually still get errors even if I remove the recursive stuff

view this post on Zulip Brendan Hansknecht (Mar 27 2023 at 03:48):

I think that is a debug print that ayaz added. Actual error would be farther down

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 03:51):

Oh shoot I just assumed it was an error :sweat_smile: I think my environment is messed up now somehow because now I'm constantly getting this even with the latest nightly of roc. Any idea what's wrong here?
Screenshot-2023-03-26-at-9.50.03-PM.png

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 03:57):

Oh, this only happens with the nightly. My older version of the roc compiler works.

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 04:02):

Anyways, went back to the bugfix branch and ran it again. This is the error at the bottom of all the debug print:
Screenshot-2023-03-26-at-10.01.18-PM.png

view this post on Zulip Brendan Hansknecht (Mar 27 2023 at 04:19):

Cool, yeah that's the real error.

view this post on Zulip Brendan Hansknecht (Mar 27 2023 at 04:21):

Also, for your other issue. A recently merged commit slightly changed the name of roc functions that get exposed to the platform. So when you update to latest nightly you will have to update the linked function names as well. If you look at an example in the repo, you should be able to see the new names.

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 05:16):

So that would mean I just need to update my version of the CLI platform then? Assuming it’s been updated for that nightly change that is

view this post on Zulip Brendan Hansknecht (Mar 27 2023 at 05:22):

Yeah

view this post on Zulip Ayaz Hafiz (Mar 27 2023 at 15:16):

@Nick Hallstrom could you try again with https://github.com/roc-lang/roc/pull/5215? I made some other fixes in there. If you get the panic, could you print the backtrace given when you run with RUST_BACKTRACE=1 set?

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 17:17):

Haha just got this error:

I thought a non-nullable-unwrapped variant for a lambda set was impossible: how could such a lambda set be created without a base case?

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 17:17):

Here it is with the backtrace:

An internal compiler expectation was broken.
This is definitely a compiler bug.
Please file an issue here: https://github.com/roc-lang/roc/issues/new/choose
thread '<unnamed>' panicked at 'I thought a non-nullable-unwrapped variant for a lambda set was impossible: how could such a lambda set be created without a base case?', crates/compiler/mono/src/layout.rs:1644:61
stack backtrace:
   0: rust_begin_unwind
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:142:14
   2: roc_mono::layout::LambdaSet::layout_for_member
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/layout.rs:1644:61
   3: roc_mono::layout::LambdaSet::layout_for_member_with_lambda_name
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/layout.rs:1494:9
   4: roc_mono::ir::specialize_proc_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3495:27
   5: roc_mono::ir::specialize_variable
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3904:9
   6: roc_mono::ir::Procs::insert_anonymous
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:1204:35
   7: roc_mono::ir::with_hole
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:5091:36
   8: roc_mono::ir::from_can
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:6844:13
   9: roc_mono::ir::specialize_proc_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3428:32
  10: roc_mono::ir::specialize_variable
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3904:9
  11: roc_mono::ir::call_by_name_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:8435:31
  12: roc_mono::ir::call_by_name
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:8177:17
  13: roc_mono::ir::with_hole
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:5144:21
  14: roc_mono::ir::from_can
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:6844:13
  15: roc_mono::ir::specialize_proc_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3428:32
  16: roc_mono::ir::specialize_variable
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3904:9
  17: roc_mono::ir::Procs::insert_passed_by_name
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:1296:23
  18: roc_mono::ir::specialize_symbol
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:7899:25
  19: roc_mono::ir::assign_to_symbol
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:7977:13
  20: roc_mono::ir::assign_to_symbols
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:8011:18
  21: roc_mono::ir::call_specialized_proc
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:8758:17
  22: roc_mono::ir::call_by_name_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:8454:33
  23: roc_mono::ir::call_by_name
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:8177:17
  24: roc_mono::ir::with_hole
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:5144:21
  25: roc_mono::ir::from_can
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:6844:13
  26: roc_mono::ir::specialize_proc_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3428:32
  27: roc_mono::ir::specialize_variable
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3904:9
  28: roc_mono::ir::specialize_external_help
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3035:9
  29: roc_mono::ir::specialize_external_specializations
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:3015:13
  30: roc_mono::ir::specialize_all
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/mono/src/ir.rs:2947:9
  31: roc_load_internal::file::make_specializations
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/load_internal/src/file.rs:5714:13
  32: roc_load_internal::file::run_task
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/load_internal/src/file.rs:6456:17
  33: roc_load_internal::file::worker_task
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/load_internal/src/file.rs:2254:34
  34: roc_load_internal::file::load_multi_threaded::{{closure}}::{{closure}}
             at /Users/nickhallstrom/Dev/Home/roc/crates/compiler/load_internal/src/file.rs:2054:25
  35: crossbeam_utils::thread::ScopedThreadBuilder::spawn::{{closure}}
             at /Users/nickhallstrom/.cargo/registry/src/github.com-1ecc6299db9ec823/crossbeam-utils-0.8.15/src/thread.rs:440:31
  36: core::ops::function::FnOnce::call_once{{vtable.shim}}
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/ops/function.rs:248:5
  37: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/alloc/src/boxed.rs:1940:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

view this post on Zulip Ayaz Hafiz (Mar 27 2023 at 17:19):

lol nice :laughter_tears: do you have a diff or something that you know causes this issue?

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 17:21):

No not really. I haven't been able to get it to compile at all unless I just remove the recursion.

view this post on Zulip Ayaz Hafiz (Mar 27 2023 at 17:46):

can you show me what the recursion looks like?

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 21:18):

It's right here:
https://github.com/Billzabob/roc-lox/blob/1a4612126b31cccd09f917665e867e5bc69b42b5/parser.roc#L11-L12
I'm trying to get parser combinators working. It's a recursive parser that's failing.

view this post on Zulip Ayaz Hafiz (Mar 27 2023 at 23:16):

Nick, could you workaround recursively calling recurTest somehow here? For example, maybe

# Will parse any number of '-' followed by a single '+'
recurTest = oneOrMore minus |> andThen plus

(I can give the definitions of oneOrMore and andThen if it's helpful)

I have a fix for the immediate issue here, but there is a larger, more subtle issue that will probably take us some time to solve with the current pattern (otherwise, with how Roc currently compiles the recurTest, it will result in a stack overflow with no easy fix to avoid it)

view this post on Zulip Nick Hallstrom (Mar 27 2023 at 23:22):

Well the problem isn’t actually with recurTest, that was me just trying to reproduce it with a simpler example. I need a recursive parser because in the Lox compiler that I’m trying to build, and expression can be recursive. But it’s not really blocking me so it’s no big deal for now! Thanks a bunch for looking into it!

view this post on Zulip Ayaz Hafiz (Mar 27 2023 at 23:31):

Okay cool. Let us know if the same panic comes up again, we can try to find workarounds on a case-by-case basis.
(also, pumped to see the Lox compiler!)

view this post on Zulip Nick Hallstrom (Mar 28 2023 at 03:40):

Maybe I need to wait for the Roc compiler to mature a bit more before I'll be able to do this parser combinator stuff :sweat_smile: Two more errors that I've encountered:

thread '<unnamed>' panicked at 'extension variable is another tag union, but I expected it to be either open or closed!', crates/compiler/types/src/types.rs:4618:21

and

thread '<unnamed>' panicked at 'assertion failed: _old_full_layout.is_none()', crates/compiler/mono/src/layout/intern.rs:662:9

view this post on Zulip Nick Hallstrom (Mar 28 2023 at 03:47):

Here's a commit that has the former error:
https://github.com/Billzabob/roc-lox/tree/32cdf0fe646a551063ed4ffacd8a9a325ad3ea46
And here's a commit that has the latter error:
https://github.com/Billzabob/roc-lox/tree/3076c13380f43533bd46bd440fac6992874bb480

view this post on Zulip Ayaz Hafiz (Mar 28 2023 at 19:51):

Thanks! I think both of them will be dealt with in https://github.com/roc-lang/roc/pull/5221 :D

view this post on Zulip Nick Hallstrom (Mar 29 2023 at 02:22):

Ayaz seriously I can’t express how impressive it is that you always squash all these bugs so dang fast! I’ll try this out right now!

view this post on Zulip Nick Hallstrom (Mar 29 2023 at 02:25):

Woohoo! Yep that fixed them both! Thank you so so much :pray:

view this post on Zulip Ayaz Hafiz (Mar 29 2023 at 14:50):

Thanks for continuing to help us surface all these issues!!

view this post on Zulip Jim Balhoff (Mar 29 2023 at 17:23):

@Ayaz Hafiz I'm not sure if it was the same issue, but you may have also fixed my problem here: https://github.com/roc-lang/roc/issues/5212 It works now with the latest build

view this post on Zulip Ayaz Hafiz (Mar 29 2023 at 17:42):

:heart_eyes: nice! Thanks for the update.

view this post on Zulip Jim Balhoff (Mar 29 2023 at 17:45):

Thank you! This one on the other hand is still a problem (I was hoping they were connected): https://github.com/roc-lang/roc/issues/5189

view this post on Zulip Ayaz Hafiz (Mar 29 2023 at 18:00):

Cool, will make sure to take a look - thanks for the ping.

view this post on Zulip Ayaz Hafiz (Mar 29 2023 at 23:39):

@Jim Balhoff I know what the bug here is, I'll try to fix it tomorrow or Friday.

view this post on Zulip Jim Balhoff (Mar 30 2023 at 00:03):

That's great, thank you.


Last updated: Jul 05 2025 at 12:14 UTC