Dejemos que Eric Lippert responda a esta:
La pregunta obvia en este punto es: si CPS es tan increíble, ¿por qué no lo usamos todo el tiempo? ¿Por qué la mayoría de los desarrolladores profesionales nunca han oído hablar de él, o aquellos que lo han hecho, piensan que es algo que solo hacen esos locos programadores de Scheme?
En primer lugar, es simplemente difícil para la mayoría de las personas que están acostumbradas a pensar en subrutinas, bucles, try-catch-finally y demás para razonar sobre los delegados que se utilizan para controlar el flujo de esta manera. Estoy revisando mis notas sobre CPS de CS442 en este momento y veo que en 1995 escribí un profQUOTE: "Con las continuas tienes que pararte de cabeza y tirarte". El profesor Duggan (*) tenía toda la razón al decir eso. Recordemos hace un par de días que nuestro pequeño ejemplo de transformación CPS de la expresión C # M (B ()? C (): D ()) involucraba cuatro lambdas. No todos son buenos para leer códigos que usan funciones de orden superior. Impone una gran carga cognitiva.
Además, una de las cosas buenas de tener declaraciones de flujo de control específicas integradas en un idioma es que permiten que su código exprese claramente el significado del flujo de control al tiempo que oculta los mecanismos: las pilas de llamadas y las direcciones de retorno y las listas de controladores de excepciones y regiones protegidas y así. Las continuaciones hacen explícitos los mecanismos de flujo de control en la estructura del código. Todo ese énfasis en el mecanismo puede abrumar el significado del código.
En el siguiente artículo , explica cómo la asincronía y las continuaciones son exactamente equivalentes entre sí, y repasa una demostración de tomar una operación de red síncrona simple (pero bloqueante) y reescribirla en un estilo asíncrono, asegurándose de cubrir todo lo oculto gotchas que deben cubrirse para hacerlo bien. Se convierte en un desorden masivo de código. Su resumen al final:
Santo cielo, qué desastre tan horrible hemos hecho. Hemos expandido dos líneas de código perfectamente claro en dos docenas de los espaguetis más deliciosos que hayas visto. Y, por supuesto, ni siquiera se compila porque las etiquetas no están dentro del alcance y tenemos un error de asignación definitivo. Todavía tendríamos que volver a escribir el código para solucionar esos problemas.
¿Recuerdas lo que decía sobre los pros y los contras de CPS?
- PRO: Los flujos de control arbitrariamente complejos e interesantes pueden construirse a partir de partes simples: verificar.
- CON: La reificación del flujo de control a través de continuaciones es difícil de leer y de razonar: verifique.
- CON: El código que representa los mecanismos de flujo de control abruma por completo el significado del código: verificar.
- CON: La transformación del flujo de control de código ordinario en CPS es el tipo de cosas en las que los compiladores son buenos, y casi nadie más lo es - verifique.
Este no es un ejercicio intelectual. Las personas reales terminan escribiendo código moralmente equivalente al anterior todo el tiempo cuando tratan con la asincronía. E, irónicamente, a pesar de que los procesadores se han vuelto más rápidos y más baratos, pasamos cada vez más tiempo esperando cosas que no estén vinculadas al procesador. En muchos programas, gran parte del tiempo empleado es con el procesador vinculado a cero esperando que los paquetes de red realicen el viaje de Inglaterra a Japón y viceversa, o que los discos giren, o lo que sea.
Y ni siquiera he hablado de lo que sucede si quieres componer más operaciones asincrónicas. Suponga que desea hacer ArchiveDocuments una operación asincrónica que toma un delegado. Ahora todo el código que lo llama también debe escribirse en CPS. La mancha simplemente se extiende.
Lograr que la lógica asincrónica sea correcta es importante, solo será
más importante en el futuro, y las herramientas que le hemos dado lo hacen
"ponerse de cabeza y volverse del revés", como sabiamente dijo el profesor Duggan.
El estilo de aprobación continua es poderoso, sí, pero tiene que haber una mejor manera de hacer un buen uso de ese poder que el código anterior.
Vale la pena leer ambos artículos, y la siguiente serie sobre una nueva característica del lenguaje C # que mueve todo este desorden al compilador y le permite escribir su código como flujo de control normal con una palabra clave especial para marcar ciertas partes como asíncronas. No eres un desarrollador de C #. No lo soy, pero aún así fue una experiencia muy esclarecedora cuando la encontré por primera vez.