3 ms·
To be clear, I'm not talking about PTC/TCO in general in this comment, I'm talking about it specifically in the context of Javascript, and in the context of the
by MrJohz 3y ago
To be clear, I'm not talking about PTC/TCO in general in this comment, I'm talking about it specifically in the context of Javascript, and in the context of the common patterns of Javascript usage.
That is, PTC doesn't just need to be powerful than other forms of call, it needs to be more useful day-to-day than other ways of writing the same logic. I think this article shows that, at least with the common recursive examples, that's rarely the case - it is pretty much always clearer and significantly quicker to use loops and Array methods than it is to rely on PTC and recursion.
You make a good point that there are uses for PTC outside of recursion, and that there are things you can do with it that can't be done with existing constructs. I'm sure that's true, but in my experience, the things people want to do with these tools tend not to fit well with the other features of Javascript, such as the high degree of mutation, and the dynamic nature of the language. At which point, it's probably more useful to create a compile-to-Javascript language instead that uses these sorts of features internally.
But with the rise of WASM (which has PTC as a proposal that I believe some groups have already implemented), it makes a lot more sense to use WASM as a target instead. There, you have a lot more control over exactly what gets executed and how, along with generally smaller and faster code. The exception right now is obviously DOM manipulation, but with the GC work being done right now, the path is opening up to getting easier access to the DOM directly in WASM.
- zelphirkalt 3y agoThe article does not show much except TCO existing with Bun and JavaScriptCore. It uses a not very suitable mutable data structure to mutate it in each iteration. I would say for that example it is almost better to use the for loop, since it looks very imperative anyway and using recursion to do mutating procedure calls does not give much benefit. It is a not so well chosen example.
- MrJohz 3y agoThat's mostly the point I'm trying to make! What would you see as a more convincing example of TCO in this context?
- zelphirkalt 3y agoPerhaps an example using a persistent functional data structure would be good, but probably also more complex. Instead you could do some simpler example like factorial or fibonacci, which would usually run into a stack overflow, but due to Bun being based on JavaScriptCore not running into one. At first I wanted to suggest to implement Dijkstra's algorithm for finding shortest paths from a specific node to all other nodes, but then I found a mutation in my own implementation for updating the distances and routes to nodes tables, so I did not want to suggest something I hadn't fully done myself. But maybe, if you had something like functional hashes or similarly usable for the problem, you could do it. So I will link it here: https://notabug.org/ZelphirKaltstahl/guile-algorithms/src/839bb8a0d502727feab238e5ebaebb5f128c0891/graphs/lib/algorithms/dijkstra.scm https://notabug.org/ZelphirKaltstahl/guile-algorithms/src/83... Note, that I put a "warning" in there, at the place, where it still uses mutation. Potentially this could hinder parallelization. Not sure if applicable in this specific problem, but in general, if you want to parallelize an algorithm, it not having any mutation makes it much easier to parallelize it and use our modern machines, which have multiple cores. So shame on me for not having a mutation-free version yet ;)