7 ms·
Not sure I like the `become` keyword. Seems bizarre - someone encountering this word in code for the first time would have no idea what it's doing. Why don't t
by sparkie 1y ago
Not sure I like the `become` keyword. Seems bizarre - someone encountering this word in code for the first time would have no idea what it's doing.
Why don't they just use `tailcall`? That would make it's obvious what it's doing because we've been using the term for nearly half a century, and the entire literature on the subject uses the term "tail call".
Even better would be to just automatically insert a tail call - like every other language that has supported tail calls for decades - provided the callee has the same signature as the caller. If it's undesirable because we want a stack trace, then instead have some keyword or attribute to suppress the tail call - such as `no_tail`, `nontail` or `donttail`.
Requiring tail calls to be marked will basically mean the optimization will be underutilized. Other than having a stack trace for debugging, there's basically no reason not to have the optimization on by default.
- kibwen 1y agoRust does allow tail call optimization. But that's LLVM's decision to optimize tail calls on a case-by-case basis. An explicit syntax to denote tail calls would be the difference between tail call optimization and guaranteed tall call elimination, which is important because if you're writing a tail-recursive function then it's pretty trivial to blow the stack at any moderate recursion depth unless you can guarantee the elimination. As for why it's not trivial for Rust to do this by default, consider the question of what should happen in the case of local destructors, which in an ordinary function would be called after `return myfunc()` returns, but in a tail-recursive function would need to be called beforehand. The proposals for `become` tend to handle this by making it a compiler error to have any locals with destructors in scope at the point of the tail-call, further motivating the explicit syntax.
- burnt-resistor 1y agoI looked into it. There's a crate for it: https://docs.rs/tailcall https://docs.rs/tailcall
- celeritascelery 1y agoI am surprised this works reliably. I am interested to see what they are doing under the hood to guarantee tail call elimination.
- nixpulvis 1y agoI'm generally pretty conservative about keywords. But it changes the semantics of the return, so it makes sense to change the word used in that position.
- andrewflnr 1y agoAs far as the name of the keyword: anyone who knows what "tail call" means will figure out "become" pretty quickly. If they don't get it from context clues, someone will just have to tell them, "oh, it's a tail call", and the confusion will dissolve, because "become" is really not a bad word for what happens in a tail call. (This is obviously less important than the implementation issues kibwen handled.)
- lmm 1y ago> Even better would be to just automatically insert a tail call - like every other language that has supported tail calls for decades - provided the callee has the same signature as the caller. I've used Scala for many years and concluded this was a mistake. It makes it too easy to accidentally rely on an optimisation and then break your code much later with a seemingly innocuous change. Better to make it explicit.
- Quekid5 1y agoJust add the @tailrec annotation -- then the compiler will complain loudly if you break tail calls.
- lmm 1y agoYes, the problem is if you didn't add it but the compiler was still silently TCOing your function, until one day it doesn't.
- Quekid5 1y agoSure, but if you're relying on the TCO, you kind of have to actually state that, regardless? (At least if you want to avoid accidental regressions.) I don't see any way around having to state your intent (as a programmer) for this. It's just a semantic difference in behavior unless your Abstract Machine allows for just ignoring the possibility of stack overflow entirely.
- lmm 1y ago> I don't see any way around having to state your intent (as a programmer) for this. I want a way to state that my intent is to not rely on the TCO. Even a second explicit annotation for "do not TCO this function" would be better than what Scala currently does (but frankly TCO is surprising enough to debug that I think it should be opt-in rather than opt-out).
- Quekid5 1y ago
- dfawcus 1y agoFWIW, Alef also used a 'become' keyword for a tail-call version of 'return'. That in a quite C-like language.