WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Scala · Advanced · question 58 of 100

What are delimited continuations in Scala, and how can they be used to manage control flow?

📕 Buy this interview preparation book: 100 Scala questions & answers — PDF + EPUB for $5

Delimited continuations are a mechanism used in functional programming languages, like Scala, to control the flow of a program by capturing the future computation (the continuation) at specific points, and using it later to resume the computation. In contrast to undelimited continuations, delimited continuations capture only a portion of the future execution, with well-defined boundaries.

In Scala, delimited continuations are provided via the ‘scala-continuations‘ library, which offers two main operations ‘shift‘ and ‘reset‘. The ‘shift‘ operation captures a delimited continuation, while ‘reset‘ is used to define the boundary of the continuation.

‘shift‘ has the following signature:

def shift[A, B, C](f: (A => B) => C): A @cpsParam[B, C]

Here, ‘f‘ is a function that takes a continuation (a function of type ‘A => B‘) as its input and produces a value of type ‘C‘. ‘shift‘ returns a value of type ‘A‘ and marks the computation as a delimited continuation using the ‘@cpsParam‘ annotation.

‘reset‘ has the following signature:

def reset[A, B](b: => A @cpsParam[A, B]): A

The ‘reset‘ function takes a block of code marked with ‘@cpsParam‘ (a computation that has ‘shift‘ inside it), and returns the result of type ‘A‘. It serves as the delimiter for the continuation.

Here’s a simple example demonstrating delimited continuations in Scala:

import scala.util.continuations._

def example: Int = reset {
  1 + shift { k: (Int => Int) => k(2) } * 3
}

println(example)  // Outputs: 7

In this example:

1. ‘reset‘ introduces the boundary for the delimited continuation.

2. The expression inside ‘reset‘ gets transformed: ‘1 + shift(...) * 3‘. The ‘shift‘ captures the continuation ‘k‘ (which is a function ‘Int => Int‘), representing the computation performed after ‘shift‘.

3. We pass an integer ‘2‘ to ‘k‘, and the continuation ‘k‘ will be applied to this value: ‘k(2)‘.

4. The continuation ‘k‘, in this case, is equivalent to ‘x => x * 3‘: After ‘shift‘, it captures the expression ‘* 3‘. Thus, when ‘k(2)‘ is executed, it becomes ‘2 * 3‘.

5. The value of the ‘reset‘ expression becomes ‘1 + (2 * 3)‘ which equals ‘7‘.

Delimited continuations can be useful for managing control flow in various scenarios, such as implementing generators, asynchronous programming, or custom control structures. They provide a way to encapsulate partial computation and restore it later, which can simplify complex control flow structures.

For instance, consider a simple generator example:

import scala.util.continuations._

def twoInts: (Int, Int) @cps[Unit] = shift { k: ((Int, Int) => Unit) =>
  k((0, 1))
  k((1, 1))
  k((2, 2))
}

reset {
  for ((x, y) <- twoInts) println(s"($x, $y)")
}

Here, ‘twoInts‘ is a generator that, upon each call to ‘k‘, yields a tuple of two integers. The ‘reset‘ block is used to define the boundary for the delimited continuation, and the ‘for‘ loop will execute the ‘println‘ statement for each tuple produced by ‘twoInts‘. The output will be:

(0, 1)
(1, 1)
(2, 2)

In summary, delimited continuations in Scala provide an expressive mechanism for managing control flow by capturing and resuming portions of the computation. The ‘scala-continuations‘ library provides the ‘shift‘ and ‘reset‘ operations that allow you to work with delimited continuations effectively.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Scala interview — then scores it.
📞 Practice Scala — free 15 min
📕 Buy this interview preparation book: 100 Scala questions & answers — PDF + EPUB for $5

All 100 Scala questions · All topics