This is declaratively identical to eval_to_list/2.
The only difference is that the Result argument will only be instantiated once the complete result list (and its length) is known. As long as (subgoals of) eval_to_complete_list/2 delay, the Result variable is not touched. This behaviour makes it easier to write predicates that wait for an input list: they can delay until Result gets instantiated, and then proceed, assuming that Result is a proper, terminated list.
% Cases with insufficient instantiation: ?- eval_to_complete_list(Xs, R). R = R <delays until result fully known, R not bound> ?- eval_to_complete_list([1,2|Xs], R). R = R <delays until result fully known, R not bound> ?- eval_to_complete_list([1,2|Xs], R), Xs=[3]. R = [1,2,3] Yes ?- eval_to_complete_list(eval(Xz), R), Xz = [](1,2,3). R = [1,2,3] Yes ?- eval_to_complete_list([1]>>Ys, R). R = R <delays until result fully known, R not bound> ?- eval_to_complete_list([1]>>Ys, R), Ys = [2]. R = [1,2] Yes % Other examples see eval_to_list/2