tweag / nickel

Better configuration for less

Home Page:https://nickel-lang.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Some sub-expressions of thunks are re-evaluated several times

yannham opened this issue · comments

Describe the bug
During unrelated tests, I noticed that some expressions which should be only evaluated once given the lazy evaluation model of Nickel are actually re-evaluated potentially many time. This bug hits in particular thunks which are in weak head normal form from the beginning, such as arrays or records.

To Reproduce

Put a computation inside an array and that array inside a thunk, and request the evaluation of the element several times:

nickel> let trace_eval = fun x => std.trace "evaled!" x in let y = [trace_eval null] in [std.array.elem 0 y, std.array.elem 0 y]
std.trace: evaled!
std.trace: evaled!
[ false, false ]

Expected behavior

I expect that the expression trace_eval null, part of the thunk y, is only evaluated at most once:

nickel> let trace_eval = fun x => std.trace "evaled!" x in let y = [trace_eval null] in [std.array.elem 0 y, std.array.elem 0 y]
std.trace: evaled!
[ false, false ]

Environment

  • OS name + version:
  • Version of the code:

Additional context

The issue should to be related to the elimination of generated variables, which caused some invariant previously held to become false. In particular, the function Thunk::should_update, which decides if a thunk is worth updating, is at fault. A fix is on its way.