После прочтения ответа Эрика Липлетса У меня сложилось впечатление, что await
и call/cc
- это почти две стороны одной и той же монеты, с большинством синтаксических различий. Однако при попытке реально реализовать call/cc
в С# 5 я столкнулся с проблемой: либо я неправильно понимаю call/cc (что довольно возможно), либо ждет только напоминание о вызове /cc.
Рассмотрим псевдокод следующим образом:
function main:
foo();
print "Done"
function foo:
var result = call/cc(bar);
print "Result: " + result;
function bar(continuation):
print "Before"
continuation("stuff");
print "After"
Если мое понимание вызова /cc верное, тогда это должно печатать:
Before
Result: stuff
Done
Реально, когда вызывается продолжение, состояние программы восстанавливается вместе с историей вызова, так что foo
возвращается в main
и никогда не возвращается к bar
.
Однако, если реализовано с помощью await
в С#, вызов продолжения не позволяет восстановить эту историю вызовов. foo
возвращается в bar
, и не может (я могу видеть), что await
может использоваться, чтобы сделать правильную историю вызовов частью продолжения.
Пожалуйста, объясните: я полностью неправильно понял операцию call/cc
или await
не совсем то же самое, что call/cc
?
Теперь, когда я знаю ответ, я должен сказать, что это хорошая причина думать о них как о довольно похожей. Посмотрите, как выглядит вышеприведенная программа в псевдо-С# -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"
Итак, в то время как стиль С# 5 никогда не дает нам объект продолжения для передачи значения, общее сходство довольно впечатляет. За исключением того, что на этот раз совершенно очевидно, что "After" никогда не вызывается, в отличие от примера true-call/cc, что является еще одной причиной любить С# и хвалить его дизайн!