nickel
nickel copied to clipboard
Infinite loop (and memory usage)
When trying to export the following file, nickel gets stuck and starts using up all my memory:
{ y = { foo = y } }
I mean, it is an infinite loop, right? Although we should probably be able to detect that without black-holing, and I'm not sure why we don't.
What behavior do you think would be right?
I'd expect the same infinite recursion error that you get from, say let rec y = y in y
I haven't tested this hypothesis, but I believe it's to be expected that black-holing doesn't detect such loops. In fact, as long as you don't use deep_seq (but both nickel eval and nickel export do use it, which is why it's looping), this term doesn't loop, in that it's always productive: if we evaluate y, we get a lazy record {foo = y}. If we then evaluate foo, we get in one step the record {foo = y}, and so on. It's basically an infinite record { y = { foo = {foo = { foo = ...., which is - at each step - at most one variable substitution away from being in weak head normal form.
So, evaluating y always terminates, and doesn't trigger the infinite recursion detection.
However, this is different when forcing/deep_sequing the record, of course, because we are now trying to recurse into an infinite data structure. I wonder if we can extend the blackholing mechanism to handle this case, by forbidding thunks to be evaluated again while we're still forcing the children of this thunk.
Related to #1722