{ "cells": [ { "cell_type": "markdown", "id": "941f6882-7137-4088-9057-c21c30ab0ab5", "metadata": {}, "source": [ "### Transformation to a Register Machine" ] }, { "cell_type": "markdown", "id": "2d1eadbf-fdb3-4df5-9067-51beae223bc8", "metadata": {}, "source": [ "We will start with a simple recursive function in Scheme that just adds up the first *n* positive integers:" ] }, { "cell_type": "code", "execution_count": null, "id": "f02bd99c-cdd2-47c4-a270-0b63365a7bbd", "metadata": { "tags": [] }, "outputs": [], "source": [ "(define sum\n", " (lambda (n)\n", " (if (= n 0)\n", " 0\n", " (+ n (sum (- n 1))))))" ] }, { "cell_type": "code", "execution_count": null, "id": "7a391c8b-0129-4b6d-9d2a-2251c16918ed", "metadata": { "tags": [] }, "outputs": [], "source": [ "(sum 5)" ] }, { "cell_type": "markdown", "id": "a85ef6fd-edde-469c-b7e6-c31a8986f14f", "metadata": {}, "source": [ "Next, we rewrite `sum` in continuation-passing style (CPS):" ] }, { "cell_type": "code", "execution_count": null, "id": "a1880d65-32ac-4fd1-85bb-bc82f2c528cb", "metadata": { "tags": [] }, "outputs": [], "source": [ "(define sum-cps\n", " (lambda (n k)\n", " (if (= n 0)\n", " (k 0)\n", " (sum-cps (- n 1)\n", " (lambda (value)\n", " (k (+ n value)))))))" ] }, { "cell_type": "markdown", "id": "ec5d5a2f-d385-45ca-8cc0-16682bf70599", "metadata": {}, "source": [ "To run `sum-cps` we need to provide the *initial continuation* `(lambda (value) value)`" ] }, { "cell_type": "code", "execution_count": null, "id": "ad9d3a50-464b-4306-9e65-c09e41fa3517", "metadata": { "tags": [] }, "outputs": [], "source": [ "(sum-cps 5 (lambda (value) value))" ] }, { "cell_type": "markdown", "id": "d4b3e87d-29cc-45a3-856e-ce0de2582920", "metadata": {}, "source": [ "For convenience, our top-level `sum` function will just call `sum-cps` with the initial continuation:" ] }, { "cell_type": "code", "execution_count": null, "id": "72b1d569-57c6-4026-abe5-628b62b5ecca", "metadata": { "tags": [] }, "outputs": [], "source": [ "(define sum\n", " (lambda (n)\n", " (sum-cps n (lambda (value) value))))" ] }, { "cell_type": "code", "execution_count": null, "id": "089277a1-5a2f-4d89-8a10-97857d9e1d6a", "metadata": { "tags": [] }, "outputs": [], "source": [ "(sum 5)" ] }, { "cell_type": "markdown", "id": "af64e288-e421-40da-bf1a-b2d4b87f8fae", "metadata": {}, "source": [ "Notice that our continuations are represented as anonymous *lambda* functions. Here we are taking advantage of Scheme's ability to easily create and pass around higher-order functions. In the above code, there are two such continuation functions: `(lambda (value) value)` and `(lambda (value) (k (+ n value)))`. In general, a *lambda* expression that represents a continuation may or may not contain **free variables**, depending on the context in which it arises. For example, the continuation `(lambda (value) value)` has no free variables, since `value` is bound by the lambda's formal parameter, while the continuation `(lambda (value) (k (+ n value)))` has two free variables: `k` and `n`." ] }, { "cell_type": "markdown", "id": "7b40e618-d34c-4bb4-b5be-c103f0ee40e5", "metadata": {}, "source": [ "#### Changing the representation of continuations\n", "\n", "We now change the representation of continuations from Scheme functions to Scheme data structures, which will just be ordinary lists (also referred to as **continuation records**). Each lambda expression that represents a continuation will get replaced by a call of the form `(make-cont