3 ms·
I don't think that's related? The bug alluded to looks something like function rm(node) { for (const child of ls(node)) rm(child);
by shiomiru 17d ago
I don't think that's related? The bug alluded to looks something like
function rm(node) {
for (const child of ls(node))
rm(child);
unlink(node);
}
and no amount of tail call optimization will save you here, because this isn't tail recursion. Of course you could rewrite it using an explicit stack + tail recursion, but then you might as well be using a while loop.
- tosti 16d agoSo it's enumerating all the subdirectories first and unlinks the tree afterwards? I get that this isn't transactional and inherently prone to race conditions, but if this is indeed the problem, it's rediculous. A single while loop could do the job correctly and use less RAM. It'd probably also be faster. But that wouldn't be a rusty thing to do? I look at code from the heirloom project and, despite its warts, I think we've lost something in the past 45 years or so.
- shiomiru 15d ago> A single while loop could do the job correctly and use less RAM. It'd probably also be faster. But that wouldn't be a rusty thing to do? No, the "single while loop" is just harder to implement than a naive recursion, because recursion is a natural way to implement tree traversal. With a while loop, you need an explicit stack, which is more complex. (A stackless traversal seems unrealistic here, as getting the succeeding node would be too expensive. Not that I've tried...) > I look at code from the heirloom project and, despite its warts, I think we've lost something in the past 45 years or so. I've just tried and heirloom rm segfaults on the same test too. Which is no wonder, seeing how that code also recurses. (It's mentioned somewhere else in the thread, but this is exactly the reason why GNU had to specify "no hard limits" as a policy. Unix used to be full of such bugs.)
- tosti 14d agoThank you for clearing that up. Good points!