Lazy data structures are a powerful abstraction can increase the readability of your program while encouraging separation of concerns.
What are they? Simply put, they are data structures that “realize” what they contain when they’re needed (or right before they’re needed).
What can you do with lazy data structures? How about a page-scraper that paginates as needed:
# pseudocode seed_url = "http://example.com/page/" # generate a lazy list of urls: # - http://example.com/page/1 # - http://example.com/page/2 # - etc. urls = lazy { for (i = 0; i < 100; i++) { yield seed_url + string(i) } } # a lazy list of html pages pages = map(urls, fetchURLPageContents) # a lazy list of list of links links_per_page = map(pages, extractLinksFromHTML) # flatten to just a lazy list of links links = join(links_per_page) # do stuff with links for link in links { record(link) } This creates a powerful abstract that separate tasks your program needs to get done behind an implicit interface. The ending for loop doesn’t need to know that those links came from multiple page fetches or the file system. If the loop short-circuited, then it minimizes the number of unnecessary fetches.
...