Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7680315
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T18:05:13+00:00 2026-05-31T18:05:13+00:00

After reading Eric Lippert’s answer I got the impression that await and call/cc are

  • 0

After reading Eric Lippert’s answer I got the impression that await and call/cc are pretty much two sides of the same coin, with at most syntactic differences. However, upon trying to actually implement call/cc in C# 5, I ran into a problem: either I misunderstand call/cc (which is fairly possible), or await is only reminiscent of call/cc.

Consider pseudo-code like this:

function main:
    foo();
    print "Done"

function foo:
    var result = call/cc(bar);
    print "Result: " + result;

function bar(continuation):
    print "Before"
    continuation("stuff");
    print "After"

If my understanding of call/cc is correct, then this should print:

Before
Result: stuff
Done

Crucially, when the continuation is called, the program state is restored along with the call history, so that foo returns into main and never comes back to bar.

However, if implemented using await in C#, calling the continuation does not restore this call history. foo returns into bar, and there’s no way (that I can see) that await can be used to make the correct call history part of the continuation.

Please explain: did I completely mis-understand the operation of call/cc, or is await just not quite the same as call/cc?


Now that I know the answer, I have to say that there’s a good reason to think of them as fairly similar. Consider what the above program looks like in pseudo-C#-5:

function main:
    foo();
    print "Done"

async function foo:
    var result = await(bar);
    print "Result: " + result;

async function bar():
    print "Before"
    return "stuff";
    print "After"

So while the C# 5 style never gives us a continuation object to pass a value to, overall the similarity is quite striking. Except that this time it’s totally obvious that “After” never gets called, unlike in the true-call/cc example, which is another reason to love C# and praise its design!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T18:05:14+00:00Added an answer on May 31, 2026 at 6:05 pm

    await is indeed not quite the same as call/cc.

    The kind of totally fundamental call/cc that you are thinking of would indeed have to save and restore the entire call stack. But await is just a compile-time transformation. It does something similar, but not using the real call stack.

    Imagine you have an async function containing an await expression:

    async Task<int> GetInt()
    {
        var intermediate = await DoSomething();
        return calculation(intermediate);
    }
    

    Now imagine that the function you call via await itself contains an await expression:

    async Task<int> DoSomething()
    {
        var important = await DoSomethingImportant();
        return un(important);
    }
    

    Now think about what happens when DoSomethingImportant() finishes and its result is available. Control returns to DoSomething(). Then DoSomething() finishes and what happens then? Control returns to GetInt(). The behaviour is exactly as it would be if GetInt() were on the call stack. But it isn’t really; you have to use await at every call that you want simulated this way. Thus, the call stack is lifted into a meta-call-stack that is implemented in the awaiter.

    The same, incidentally, is true of yield return:

    IEnumerable<int> GetInts()
    {
        foreach (var str in GetStrings())
            yield return computation(str);
    }
    
    IEnumerable<string> GetStrings()
    {
        foreach (var stuff in GetStuffs())
            yield return computation(stuff);
    }
    

    Now if I call GetInts(), what I get back is an object that encapsulates the current execution state of GetInts() (so that calling MoveNext() on it resumes operation where it left off). This object itself contains the iterator that is iterating through GetStrings() and calls MoveNext() on that. Thus, the real call stack is replaced by a hierarchy of objects which recreate the correct call stack each time via a series of calls to MoveNext() on the next inner object.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

After reading the documentation for MySQL Workbench I got the impression that it's possible
After reading the answer to this question , I learned that SFINAE can be
After reading this description of late static binding (LSB) I see pretty clearly what
After reading this answer: best way to pick a random subset from a collection?
I know, I know... Eric Lippert's answer to this kind of question is usually
After reading some posts like this one: Choose File Dialog It appears that Android
After reading a question on @private I understand how that works. However, since all
After reading the topic Is MD5 really that bad , I was thinking about
After reading around, I've realized that SQL ( MySQL in my case ) does
After reading this SE Discussion a question pops up. Why jquery defined two methods

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.