Hacker News new | ask | show | jobs
by richdougherty 1470 days ago
I agree, syntactic tail calls seems like a great compromise if automatic tail calls are too risky. I'd love to have them in the language.

Here are some strawman syntax examples from the Syntactic Tail Calls proposal.

Return Continue

  function factorial(n, acc = 1) {
    if (n === 1) {
      return acc;
    }
    return continue factorial(n - 1, acc * n)
  }

  let factorial = (n, acc = 1) => continue
    n == 1 ? acc
           : factorial(n - 1, acc * n);

  // or, if continue is an expression form:
  let factorial = (n, acc = 1) =>
  n == 1 ? acc
         : continue factorial(n - 1, acc * n);
Function sigil

  // # sigil, though it's already 'claimed' by private state.
  #function() { /* all calls in tail position are tail calls */ }

  // Note that it's hard to decide how to readably sigil arrow functions.

  // This is probably most readable.
  () #=> expr
  // This is probably most in line with the non-arrow sigil.
  #() => expr

  // rec sigil similar to async functions
  rec function() { /* likewise */ }
  rec () => expr
!-return

  function () { !return expr }

  // It's a little tricky to do arrow functions in this method.
  // Obviously, we cannot push the ! into the expression, and even
  // function level sigils are pretty ugly.

  // Since ! already has a strong meaning, it's hard to read this as
  // a tail recursive function, rather than an expression.
  !() => expr

  // We could do like we did for # above, but it also reads strangely:
  () !=> expr
https://github.com/tc39/proposal-ptc-syntax#syntax-alternati...