This predicate makes the content of Stream available as a list of character codes, similar to reading the whole stream content into a list, and then using the list. However, in this lazy version the list is materialized in an incremental fashion, i.e. only when its elements are created by the list processing code, are the character codes read from the stream and filled in. For most purposes, this lazy list can be used like a normal list, e.g. in parsing with DCGs. The advantage of the lazy version is that at no time is it necessary to have the whole list in memory: the tail is created lazily from the stream, and the front will be garbage collected when no longer needed.
The stream must be open in read-mode. The list will reflect the stream content starting from the position the stream is at when stream_to_lazy_list/2 is called. The list will end with the last character in the stream. If the stream content changes while the list is partly materialised, the list content is undefined.
The stream should not be closed as long as it is possible to backtrack to a point between the call to stream_to_lazy_list/2 and the termination of the list. In most cases, it is not necessary to close the stream explicitly at all, because it will be closed automatically on garbage collection or on failure.
NOTE about cuts in current ECLiPSe versions: If a unification is followed immediately by a cut, and the unification causes waking, the waking occurs only after the cut. A unification that creates an element of the lazy list may therefore need a dummy 'true' goal before a subsequent cut in order to force waking.
copy_file(Old, New) :- open(Old, read, In), open(New, write, Out), stream_to_lazy_list(In, Codes), ( foreach(C,Codes), param(Out) do put(Out, C) ), close(In), close(Out).