| The page that you linked to shows off some features that are not really found in any major programming langauge. Time-traveling search is a big one for me. Many languages have exceptions, but with shift/reset, you can implement your own exception handling behavior trivially, including things like resumable exceptions. Some languages have async/await, but almost all of those implementations are state-machine based, which means that they don't compose well when used with more complex language features like generics and higher order functions. But more than that, in continuation-based asynchronous programming, "async" functions are just normal functions that execute in an async prompt. Here's an example of a multi-user asynchronous TCP echo server in my toy language with tagged delimited continuations: async {
loop {
let conn = accept_connection("localhost", 9999)
async {
loop {
let data = conn.next_data()
conn.send(data)
}
}
}
}
Where all of those asyncrhonous constructs (including `async` itself) are really short wrappers around delimited continuation machinery.You'll notice that the nested calls to `async` indicate that there are two asyncrhonous contexts 1. Connection acceptance happen on their own "thread" of control 2. Each connection gets their own context in which everything is internally asyncrhonous |