4 ms·
It's a misnomer. It's not just "an optimization"; in some cases, it alters program semantics.
by jhgb 5y ago
It's a misnomer. It's not just "an optimization"; in some cases, it alters program semantics.
- cryptonector 5y agoUsually the only visible side-effect of TCO is stack trace compression and failure to exhaust the stack. You can call that semantics if you like, but I think most people wouldn't. It's absurd that Java doesn't do TCO because of the stack compression "issue" (as I understand, that's why Java doesn't TCO).
- jhgb 5y agoTermination instead of divergence definitely is a change in semantics.
- cryptonector 5y agoNo, failure to fail is not a change in semantics. EDIT: "My program used to fail with a stack size exhaustion error, but now it works -- I'm so angry about this!" -no one ever.
- jhgb 5y agoBut they'd complain about the opposite -- for example if the program were an external-event-driven state automaton.
- cryptonector 5y agoTCO does not do the opposite. TCO helps avoid stack exhaustion without introducing new faults. TCO might cause your program to avoid one stack exhaustion fault only to reveal a different fault (possibly a different stack exhaustion fault). This is not a semantics change. And it's not a bug either.
- jhgb 5y agoWhat do you mean by "reveal a different fault"? A program with an indefinite amount of tail calls does not have "a fault".
- cryptonector 5y agoIf you have a program that fails due to stack exhaustion, but fixing it by enabling TCO causes it to run longer and therefore run into some other problem...
- jhgb 5y agoBut that's not a fault in the program. That's a fault in its execution environment revealed by the program.
- adrianN 5y agoC++ compilers are free to optimize infinite loops without side effects away and people are generally fine with that.
- jhgb 5y agoWell, I'm sure this is not the worst thing about C++ that C++ people are "generally fine with", so that really doesn't tell me a lot. Not quite sure if this applies to useful programs, though. Lack of tail call elimination can definitely break a class of useful programs even with side effects.
- fsckboy 5y ago> You can call that semantics if you like, but I think most people wouldn't. Tail Call Optimization (TCO) is an optimization, yes; but if Tail Call Elimination is required in the implementation of a language as it is in Scheme, then programmers in the language can rely on it (along with lexical scope) to write iterative loops instead as recursive calls. That is a change in program language semantics. see Guy Steele's "Debunking the 'Expensive Procedure Call' Myth, or, Procedure Call Implementations Considered Harmful, or, Lambda: The Ultimate GOTO" http://dspace.mit.edu/handle/1721.1/5753 http://dspace.mit.edu/handle/1721.1/5753
- cryptonector 5y agoMy point is that adding TCO is not a breaking semantics change, as its only visibility will be through a) the fact that more code works with it than w/o it, b) elision of tail-calling frames in stack traces. In particular I don't consider (b) to be a problem. I'm aware (b) is a matter of opinion, but really, TCO is much too valuable to use (b) as an argument against TCO.
- haberman 5y ago> but if Tail Call Elimination is required in the implementation of a language as it is in Scheme This is also supported as a non-standard extension in C, C++, and Objective-C as of Clang 13: https://clang.llvm.org/docs/AttributeReference.html#musttail https://clang.llvm.org/docs/AttributeReference.html#musttail (I implemented this). > see Guy Steele's "Debunking the 'Expensive Procedure Call' Myth Yes! :) I cited this paper in my blog article describing how we are using musttail: https://blog.reverberate.org/2021/04/21/musttail-efficient-interpreters.html https://blog.reverberate.org/2021/04/21/musttail-efficient-i...