On this page:
8.1 Introduction
8.2 Optional Reading
8.3 Part 1:   Language Comparison
8.4 Part 2:   Implementation State
8.4.1 Program 1
8.4.2 Program 2
8.4.3 Program 3
8.5 What To Hand In
8 Generators

    8.1 Introduction

    8.2 Optional Reading

    8.3 Part 1: Language Comparison

    8.4 Part 2: Implementation State

      8.4.1 Program 1

      8.4.2 Program 2

      8.4.3 Program 3

    8.5 What To Hand In

8.1 Introduction

In this assignment, you will learn more about generators.

8.2 Optional Reading

This article provides a very nice introduction to generators in the Icon programming language, which is no longer used but inspired most modern work on generators. Generators in Icon were central to the language, not an added-on feature, and this shows how they are integrated into the language. (Notice, in paricular, how the truthy-falsy nature of the language appears to be a win early on, but becomes problematic later on.) You can see other examples on Wikipedia. It’s worth noting that Icon was created in the late 1970s!
You do not need to read this article for anything in this assignment. However, it’s important if you want to further study programming languages. You may also find it interesting for thinking as a programmer.

8.3 Part 1: Language Comparison

Consider the following program written in Python 3 (run it online!):

x = 0

 

def a(b):

    global x

    b()

    x = 3

 

def c():

    a(lambda: (yield 1))

    yield x

 

gen = c()

print(next(gen))

print(next(gen))

We’ve translated the above program into this seemingly equivalent Racket program (run it online!):
#lang racket
(require racket/generator)
 
(define x 0)
 
(define (a b)
 (b)
 (set! x 3))
 
(define c
 (generator ()
            (a (lambda () (yield 1)))
            (yield x)))
 
(c)
(c)
First, confirm that these programs look equivalent; that is, we might expect the generators in both to yield 1, then yield 3. Then, run both programs, and answer the following question:
Do these programs behave the same way? If not, try to explain why they differ. You are welcome to consult the Internet for help understanding their behaviors.

8.4 Part 2: Implementation State

We want you to demonstrate your understanding of generators by drawing the stack + heap configurations, in the style of Stacker, for the following three Python programs. Show the stack at the point that pause is called. You can use whatever tools you want (including just hand-writing on paper). You don’t have to worry about matching the Stacker’s colors. However, please do follow the three-column layout of the Stacker tool.
Note: You will want a new kind of value to represent a running generator. It’s similar to a closure but different in a crucial way. Explain why ordinary closures can’t straightforwardly be used for this purpose. (This gets to the heart of why generators are different from functions.)

8.4.1 Program 1

def gen(x):

    yield x

    yield x + 1

g = gen(0)

next(g) + pause() + next(g)

8.4.2 Program 2

def gen(x):

    while True:

        yield x

        x += 1

g = gen(0)

next(g) + next(g) + pause()

8.4.3 Program 3

def gen(x):

    yield (yield x)

g = gen(0)

 

next(g)

pause()

next(g)

pause()

Note that this program has two pauses, so you will need to produce two responses, not only one.

8.5 What To Hand In

You will submit six responses to this assignment on Gradescope:
  • A file for the language comparison.

  • A file explaining the reason for the generator block.

  • Four files showing the Stacker-like output.

You can update your submissions as many times as you want before the deadline.