Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement mutual recursion TCO on JavaScript #3830

Open
lpil opened this issue Nov 14, 2024 · 2 comments
Open

Implement mutual recursion TCO on JavaScript #3830

lpil opened this issue Nov 14, 2024 · 2 comments
Labels
help wanted Contributions encouraged priority:medium

Comments

@lpil
Copy link
Member

lpil commented Nov 14, 2024

V8 (the most widely used JS engine) doesn't implement tail calls for some bad reason, so we need to implement tail call optimisation in the compiler.

Today we support self-recursion. Extend this to support mutual recursion.

My thought was that we could compile this code

pub fn up(a) {
  case wibble(a) {
    True -> down(a)
    False -> a
  }
}

pub fn down(a) {
  case wobble(a) {
    True -> up(a * a)
    False -> down(a + 1)
  }
}

To something like this

export function up(a) {
  return mutual$up$down(0, a);
}

export function down(a) {
  return mutual$up$down(1, a);
}

export function mutual$up$down(mode, up$a, down$a) {
  if (mode == 0) {
    // This is the `up` function
    if (wibble(up$a)) {
      mode = 1;
      down$a = up$a;
    } else {
      return up$a;
    }
  } else {
    // This is the `down` function
    if (wibble(down$a)) {
      mode = 1;
      down$a = down$a * down$a;
    } else {
      mode = 0;
      up$a = down$a;
    }
  }
}

The exact names etc we would use would need some thought, but you get the idea.

We already identify functions reference loops during analysis, so perhaps we could use that as a starting point for identifying when this optimisation can be applied.

This would be a challenging item of work.

@lpil lpil added help wanted Contributions encouraged priority:medium labels Nov 14, 2024
@inoas
Copy link
Contributor

inoas commented Nov 14, 2024

It cannot be a circle of 3 functions? If it can, does Erlang support this?

@lpil
Copy link
Member Author

lpil commented Nov 14, 2024

It would support any number of mutually recursive functions.

@lpil lpil changed the title Implement mutual recursion on JavaScript Implement mutual recursion TCO on JavaScript Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Contributions encouraged priority:medium
Projects
None yet
Development

No branches or pull requests

2 participants