| |
| ▲ | gpm 13 hours ago | parent | next [-] | | For what it's worth there's reasonably active [1] work on implementing opt-in guaranteed tail calls - but it's not particularly fast going. LLVM (the backend rust uses) needs better support for musttail (e.g. some architectures just don't support it [2]). [1] https://github.com/rust-lang/rust/issues/112788 [2] https://github.com/rust-lang/rust/issues/153827 By-default guaranteed tail calls really isn't rust's style, because it means subtle changes (introducing a destructor, re-ordering code, etc) can change semantics without you realizing it. If you want to guarantee that a call can't allocate a new stack frame you should have to say it. | | |
| ▲ | lioeters 12 hours ago | parent | next [-] | | Not so familiar with this area, but isn't the existing behavior of implicitly creating new stacks more of a problem than implicit tail-call elimination? Seems the latter is a kind of compiler-level optimization, of which there are already many (I think) that change the semantics internally but guarantee the outward behavior stays the same. But I can understand the preference for an explicit opt-in, to make clear that it is enforced and not assumed. | | |
| ▲ | gpm 12 hours ago | parent [-] | | > implicitly creating new stacks I'd argue that it's explicit - that's what a function call does and you don't have implicit function calls in rust. > Seems the latter is a kind of compiler-level optimization, of which there are already many (I think) that change the semantics internally but guarantee the outward behavior stays the same. What you're asking for here already exists. Tail calls might be optimized into not allocating extra stack frames, the rust compiler just doesn't guarantee that it will perform that optimization (and almost certainly won't when code is compiled without optimizations... for instance). What people want is the semantic guarantee that the stack frame won't be allocated. Not just a compiler that often performs the optimization. Otherwise you can't be sure that your code will keep working with new compiler flags/versions/architectures/... You could say "whenever the code is the right shape we'll guarantee the optimization" (C++ famously did this for things like copy elision)... but now the shape of code comes with non-obvious semantic guarantees and that's not rust's style. Hence the proposal for a keyword instead. | | |
| ▲ | lioeters 12 hours ago | parent [-] | | I see it, certain algorithms need guaranteed tail-call elimination, otherwise they are too inefficient and must be manually unrolled or rewritten to avoid blowing the stack. So a compiler optimization that is "nice to have" is not good enough. | | |
| ▲ | clhodapp 3 hours ago | parent [-] | | No algorithm requires tail-call elimination in a general-purpose language with imperative mutability. It's just another way to express iteration. |
|
|
| |
| ▲ | jmalicki 3 hours ago | parent | prev [-] | | > because it means subtle changes (introducing a destructor, re-ordering code, etc) can change semantics without you realizing it. No, it won't change semantics - if you say @musttail or similar, it will simply fail to compile if you, say, introduce a destructor - the semantics will not subtly change. | | |
| ▲ | afdbcreid 2 hours ago | parent | next [-] | | Incorrect. `become` does change drop order - https://play.rust-lang.org/?version=nightly&mode=debug&editi.... | | |
| ▲ | jmalicki an hour ago | parent [-] | | That's not implementing tail calls breaks things, that's bad design of implementing tail calls breaking things. The whole idea of "let's change semantics to make it easier" is dumb. If you want guaranteed tail calls, change your code until it works. |
| |
| ▲ | gpm 3 hours ago | parent | prev [-] | | Uh, yes, if you guarantee the semantics only when the code explicitly opts in and not by default then semantics will not subtly change, that is the point of my comment | | |
| ▲ | jmalicki 3 hours ago | parent [-] | | It's not a change in semantics of compiled code. It is only a change of whether or not the code will compile. |
|
|
| |
| ▲ | IshKebab 9 hours ago | parent | prev [-] | | Do any widely used languages guarantee tail call optimization? It's a pretty niche feature. | | |
| ▲ | gpm 9 hours ago | parent [-] | | Scala, ocaml, racket, clojure, zig. For recursion only kotlin. (For most of these only with syntax specifying it) |
|
|