Después de leer Eric Lippert’s answer, tengo la impresión de que await
y call/cc
son más o menos las dos caras de la misma moneda, con la mayoría de las diferencias sintácticas. Sin embargo, al tratar de implementar realmente call/cc
en C# 5, me encontré con un problema: o entiendo mal call/cc (que es bastante posible), o aguardar es sólo con reminiscencias de call/cc.C# aguarden vs continuaciones: ¿no es lo mismo?
Considérese la pseudo-código como este:
function main:
foo();
print "Done"
function foo:
var result = call/cc(bar);
print "Result: " + result;
function bar(continuation):
print "Before"
continuation("stuff");
print "After"
Si mi comprensión de llamada/cc es correcta, entonces esto debe imprimir:
Before
Result: stuff
Done
crucial, cuando la continuidad se llama, el programa el estado se restablece junto con el historial de llamadas, por lo que foo
vuelve a main
y nunca vuelve a bar
.
Sin embargo, si se implementa utilizando await
en C#, llamar a la continuación no restaura este historial de llamadas. foo
vuelve a bar
, y no hay manera (que yo pueda ver) de que await
se pueda usar para hacer que el historial de llamadas sea parte de la continuación.
Por favor, explique: ¿entendí mal el funcionamiento de call/cc
, o await
simplemente no es lo mismo que call/cc
?
Ahora que sé la respuesta, debo decir que hay una buena razón para pensar que son bastante similares. Considere lo que el programa anterior se ve como en la 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"
Así, mientras que el estilo C# 5 nunca nos da un objeto de continuación para pasar un valor de, en general, la similitud es bastante sorprendente. Excepto que esta vez es totalmente obvio que "Después" nunca se llama, a diferencia del ejemplo de la llamada real/cc, que es otra razón para amar a C# y alabar su diseño.
Timwi es correcto; esperar es más como un llamado de "efecto local"/cc; esta es una sutileza que no pensé llamar en mi respuesta original. Lo he actualizado –