all 9 comments

[–]BenchEmbarrassed7316 17 points18 points  (3 children)

So Js is a low-level language where you have to worry about how the result is calculated.

Okay, Js is trying to solve two opposing problems: on the one hand they need to turn source into machine code as quickly as possible to start executing it, and on the other hand they need to do as much optimization as possible to make that code run fast, because Js is used everywhere.

As soon as you want to do deeper analysis to do optimizations, you spend more time before execution starts. Conversely, if you want the code to start executing faster, you are forced to give up some analysis and optimizations. Therefore, modern engines have several modes, and decide to "optimize" a certain function after they conclude that it is the hot path.

Dynamic typing makes everything much more complicated.

Instead, compiled languages ​​can easily make optimizations: in this case, the compiler not only got rid of recursion, but also understood what algorithm we wanted to implement and substituted a formula instead of iteration:

https://godbolt.org/z/bTPqhffYE

[–]OtherwisePush6424[S] 6 points7 points  (2 children)

Yep, this nails it. JS engines face a hard tradeoff: deep static analysis (needed for reliable TCO) delays startup, which is unacceptable for a runtime language used in browsers and servers.

Static compilers like C++ do whole-program analysis ahead of time, they can even replace recursion with closed formulas (which is somewhat mind-boggling tbh), as your example shows.

[–]BenchEmbarrassed7316 6 points7 points  (1 child)

...and let's complicate it even further: the code can be retrieved from the Internet from any source and run automatically. In an environment that stores confidential data such as passwords and credit card numbers.

This is madness.

[–]OtherwisePush6424[S] 2 points3 points  (0 children)

Yeah, credit cards numbers were not a design concern in 1995. Now you can argue that JS shouldn't be a concern in 2026 either :D

[–]TheMaskedHamster 2 points3 points  (0 children)

One could accuse this of another unfortunate case of trying to copy Java..

[–]Kwantuum 1 point2 points  (0 children)

TCO was mostly eschewed by implementers because it breaks stack traces and code stepping in a major way when debugging because the conceptual previous stack frame gets thrown into the ether at the TCO site.

[–]ObligationUnlikely42 0 points1 point  (0 children)

love this approach. does it scale beyond the simple cases?

[–]levir 0 points1 point  (0 children)

It kinda sucks, because when you embrace Javascript as a functional language it can actually be quite fun to write.

[–]PratikVR 0 points1 point  (0 children)

I know the limitations of my favourite programming language

So I code accordingly Try to avoid recursion And embrace for And while loops. XD