...

/

Implementing a Lazy Generator

Implementing a Lazy Generator

This lesson gives detailed knowledge on generators and lazy evaluation. It explains how to write a generator for lazy evaluation.

We'll cover the following...

Introduction

A generator is a function that returns the next value in a sequence each time the function is called, like:

generateInteger() => 0
generateInteger() => 1
generateInteger() => 2
....

It is a producer that only returns the next value, not the entire sequence. This is called _lazy evaluations, which means only computing what you need at the moment, therefore saving valuable resources (memory and CPU). It is technology for the evaluation of expressions on demand.

Explanation

An example (of lazy generation) would be the generation of an endless sequence of even numbers. To generate it and use those numbers one by one would be difficult and certainly would not fit into memory! But, a simple function per type with a channel and a goroutine can do the job.

For example, in the following program, we see a Go implementation with a channel of a generator of ints. The channel is named yield and resume, terms commonly used in coroutine code.

Press + to interact
package main
import (
"fmt"
)
var resume chan int
func integers() chan int {
yield := make (chan int)
count := 0
go func () {
for {
yield <- count
count++
}
} ()
return yield
}
func generateInteger() int {
return <-resume
}
func main() {
resume = integers()
fmt.Println(generateInteger()) //=> 0
fmt.Println(generateInteger()) //=> 1
fmt.Println(generateInteger()) //=> 2
}

In the code above, at line 6, resume is declared as a channel of integers. This is initialized at line 24, where it gets the return value of the integers() function. ...