nickel icon indicating copy to clipboard operation
nickel copied to clipboard

Infinite loop (and memory usage)

Open jneem opened this issue 1 year ago • 8 comments

When trying to export the following file, nickel gets stuck and starts using up all my memory:

{ y = { foo = y } }

jneem avatar Feb 09 '24 22:02 jneem

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?

yannham avatar Feb 14 '24 19:02 yannham

I'd expect the same infinite recursion error that you get from, say let rec y = y in y

jneem avatar Feb 14 '24 22:02 jneem

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.

yannham avatar Feb 16 '24 08:02 yannham

Related to #1722

D-Brox avatar Mar 19 '24 18:03 D-Brox