If you are familiar with databases, a very frequent way to process data is:
- Ask a question like
select * from foobar - While there is more data, do: get next row of results and process it
You do not control how the result is generated and in which way (indexes? Full table scans?), or when (should all the data be generated at once or incrementally when being asked for?). All you know is: if there is more data, you will get it when you ask for it.
Lazy evaluation is pretty close to the same thing. Say you have an infinite list defined as ie. the Fibonacci sequence - if you need five numbers, you get five numbers calculated; if you need 1000 you get 1000. The trick is that the runtime knows what to provide where and when. It is very, very handy.
(Java programmers can emulate this behavior with Iterators - other languages may have something similar)