Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,263
    • Issues 4,263
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 417
    • Merge Requests 417
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Wiki
  • delimited continuations

Last edited by Takenobu Tani Jul 03, 2020
Page history New page

delimited continuations

Adding delimited continuations primops to Haskell

This page contains information on the Delimited continuation primops Proposal.

Discussion

The Delimited continuation primops Proposal is being discussed on the ghc proposal #313.

Source material

Some motivating examples in the video: Alexis King, Effects for Less, ZuriHac 2020

Implementation

The implementation in progress can be found at https://gitlab.haskell.org/lexi.lambda/ghc/-/tree/first-class-continuations .

How delimited continuations work

See Alexis King's mail.

Delimited continuations allow capturing slices of the call stack and restoring them later. For example, the program

    do y <- prompt $ do x <- control0 $ \k -> k (pure 10)
                        pure (x + 5)
       print y

will print 15. To understand what’s happening operationally, we can imagine an abstract call stack made up of continuation frames:

    ┌──────────┐
    │  ● + 5   │    redex: control0 $ \k -> k (pure 10)
    ├──────────┤
    │ prompt ● │
    ├──────────┤
    │ print ●  │
    ├──────────┤
    │   ...    │
    ├──────────┤

Here, each ● represents the “hole” where the evaluated result of the redex will be returned. control0 moves all the frames between the top of the stack and the first prompt into the heap and returns a reference to them, so after a single reduction step, we have

    ┌──────────┐
    │ print ●  │    redex: k1 (pure 10)
    ├──────────┤    heap:  k1 = ┌──────────┐
    │   ...    │                │  ● + 5   │
    ├──────────┤                └──────────┘

When a continuation is applied, its stored stack frames are copied back onto the top of the current stack, and the argument becomes the new redex:

    ┌──────────┐
    │  ● + 5   │    redex: pure 10
    ├──────────┤
    │ print ●  │
    ├──────────┤
    │   ...    │
    ├──────────┤

Now it should hopefully be clear how we end up printing 15.

Clone repository

GHC Home
GHC User's Guide

Joining In

Newcomers info
Mailing Lists & IRC
The GHC Team

Documentation

GHC Status Info
Working conventions
Building Guide
Debugging
Commentary

Wiki

Title Index
Recent Changes