stringtranslate.com

Futuros y promesas

En informática , futuro , promesa , retraso y diferido se refieren a construcciones utilizadas para sincronizar la ejecución de programas en algunos lenguajes de programación concurrentes . Describen un objeto que actúa como sustituto de un resultado inicialmente desconocido, generalmente porque el cálculo de su valor aún no está completo.

El término promesa fue propuesto en 1976 por Daniel P. Friedman y David Wise, [1] y Peter Hibbard lo llamó eventual . [2] Un concepto de futuro algo similar fue introducido en 1977 en un artículo de Henry Baker y Carl Hewitt . [3]

Los términos futuro , promesa , demora y diferido a menudo se usan indistintamente, aunque a continuación se tratan algunas diferencias de uso entre futuro y promesa . Específicamente, cuando se distingue el uso, un futuro es una vista de marcador de posición de solo lectura de una variable, mientras que una promesa es un contenedor de asignación única escribible que establece el valor del futuro. En particular, se puede definir un futuro sin especificar qué promesa específica fijará su valor, y diferentes promesas posibles pueden fijar el valor de un futuro determinado, aunque esto sólo puede hacerse una vez para un futuro determinado. En otros casos, un futuro y una promesa se crean juntos y se asocian entre sí: el futuro es el valor, la promesa es la función que establece el valor; esencialmente el valor de retorno (futuro) de una función asincrónica (promesa). Fijar el valor de un futuro también se llama resolverlo , cumplirlo o vincularlo .

Aplicaciones

Los futuros y las promesas se originaron en la programación funcional y paradigmas relacionados (como la programación lógica ) para desacoplar un valor (un futuro) de cómo se calculó (una promesa), permitiendo que el cálculo se hiciera de manera más flexible, en particular al paralelizarlo. Posteriormente, encontró uso en informática distribuida , para reducir la latencia de los viajes de ida y vuelta de las comunicaciones. Más tarde aún, ganó más uso al permitir escribir programas asincrónicos en estilo directo , en lugar de en estilo de paso continuo .

Implícito versus explícito

El uso de futuros puede ser implícito (cualquier uso del futuro obtiene automáticamente su valor, como si fuera una referencia ordinaria ) o explícito (el usuario debe llamar a una función para obtener el valor, como el getmétodo de java.util.concurrent.Futureen Java ). Obtener el valor de un futuro explícito puede denominarse punzante o forzado . Los futuros explícitos se pueden implementar como una biblioteca, mientras que los futuros implícitos generalmente se implementan como parte del lenguaje.

El artículo original de Baker y Hewitt describía futuros implícitos, que naturalmente están respaldados por el modelo de actor de computación y lenguajes de programación puramente orientados a objetos como Smalltalk . El artículo de Friedman y Wise describía sólo futuros explícitos, lo que probablemente refleja la dificultad de implementar eficientemente futuros implícitos en hardware en stock. La dificultad es que el hardware estándar no se ocupa de futuros para tipos de datos primitivos como los números enteros. Por ejemplo, una instrucción de adición no sabe cómo manejarla . En lenguajes puros de actor u objeto, este problema se puede resolver enviando el mensaje , que pide al futuro que se agregue a sí mismo y devuelva el resultado. Tenga en cuenta que el enfoque de paso de mensajes funciona independientemente de cuándo finaliza el cálculo y que no es necesario picar ni forzar.3 + future factorial(100000)future factorial(100000)+[3]3factorial(100000)

Canalización de promesas

El uso de futuros puede reducir drásticamente la latencia en sistemas distribuidos . Por ejemplo, los futuros permiten la canalización de promesas , [4] [5] tal como se implementa en los lenguajes E y Joule , que también se llamó call-stream [6] en el lenguaje Argus .

Considere una expresión que implique llamadas a procedimientos remotos convencionales , como por ejemplo:

t3 := ( xa() ).c( yb() )

que podría ampliarse a

t1 := xa(); t2 := yb(); t3 := t1.c(t2);

Cada declaración necesita que se envíe un mensaje y se reciba una respuesta antes de que pueda continuar con la siguiente declaración. Supongamos, por ejemplo, que x, y, t1y t2están todos ubicados en la misma máquina remota. En este caso, deben realizarse dos viajes completos de ida y vuelta a la red hasta esa máquina antes de que la tercera instrucción pueda comenzar a ejecutarse. La tercera declaración provocará otro viaje de ida y vuelta a la misma máquina remota.

Usando futuros, la expresión anterior podría escribirse

t3 := (x <- a()) <- c(y <- b())

que podría ampliarse a

t1 := x <- a(); t2 := y <- b(); t3 := t1 <- c(t2);

La sintaxis utilizada aquí es la del lenguaje E, donde x <- a()significa enviar el mensaje a()de forma asincrónica a x. A las tres variables se les asignan inmediatamente futuros para sus resultados y la ejecución continúa con las declaraciones posteriores. Los intentos posteriores de resolver el valor de t3pueden causar un retraso; sin embargo, la canalización puede reducir la cantidad de viajes de ida y vuelta necesarios. Si, como en el ejemplo anterior, x, y, t1y t2están todos ubicados en la misma máquina remota, una implementación canalizada puede calcular t3con un viaje de ida y vuelta en lugar de tres. Debido a que los tres mensajes están destinados a objetos que se encuentran en la misma máquina remota, sólo es necesario enviar una solicitud y sólo es necesario recibir una respuesta que contenga el resultado. El envío t1 <- c(t2)no se bloquearía incluso si t1y t2estuvieran en máquinas diferentes entre sí, o hacia xo y.

La canalización de promesas debe distinguirse del paso de mensajes asincrónicos en paralelo. En un sistema que admite el paso de mensajes en paralelo pero no la canalización, el mensaje enviado x <- a()y y <- b()en el ejemplo anterior podría proceder en paralelo, pero el envío de t1 <- c(t2)tendría que esperar hasta que ambos t1y t2se hubieran recibido, incluso cuando x, y, t1y t2están en el mismo control remoto. máquina. La ventaja relativa de la latencia de la canalización se vuelve aún mayor en situaciones más complicadas que involucran muchos mensajes.

La canalización de promesas tampoco debe confundirse con el procesamiento de mensajes canalizados en sistemas de actores, donde es posible que un actor especifique y comience a ejecutar un comportamiento para el siguiente mensaje antes de haber completado el procesamiento del mensaje actual.

Vistas de solo lectura

En algunos lenguajes de programación como Oz , E y AmbientTalk , es posible obtener una vista de solo lectura de un futuro, lo que permite leer su valor cuando se resuelve, pero no permite resolverlo:

La compatibilidad con vistas de solo lectura es coherente con el principio de privilegio mínimo , ya que permite restringir la capacidad de establecer el valor a los sujetos que necesitan establecerlo. En un sistema que también admite canalización, el remitente de un mensaje asincrónico (con resultado) recibe la promesa de solo lectura para el resultado y el destino del mensaje recibe el solucionador.

Futuros específicos del hilo

Algunos lenguajes, como Alice ML , definen futuros asociados con un hilo específico que calcula el valor del futuro. [9] Este cálculo puede comenzar con entusiasmo cuando se crea el futuro o con pereza cuando se necesita su valor por primera vez. Un futuro perezoso es similar a un golpe seco , en el sentido de un cálculo retrasado.

Alice ML también admite futuros que pueden resolverse mediante cualquier hilo y los llama promesas . [8] Este uso de promesa es diferente de su uso en E como se describe anteriormente. En Alice, una promesa no es una vista de solo lectura y no se admite la canalización de promesas. En cambio, la canalización ocurre naturalmente para los futuros, incluidos los asociados con promesas.

Semántica de bloqueo versus no bloqueo

Si se accede al valor de un futuro de forma asincrónica, por ejemplo enviándole un mensaje o esperándolo explícitamente usando una construcción como whenen E, entonces no hay dificultad en retrasar hasta que el futuro se resuelva antes de que el mensaje pueda ser enviado. recibido o se completa la espera. Este es el único caso que se debe considerar en sistemas puramente asincrónicos, como los lenguajes de actores puros.

Sin embargo, en algunos sistemas también es posible intentar acceder inmediata o sincrónicamente a un valor futuro. Luego hay que hacer una elección de diseño:

Como ejemplo de la primera posibilidad, en C++11 , un subproceso que necesita el valor de un futuro puede bloquearse hasta que esté disponible llamando a las funciones miembro wait()o get(). También puede especificar un tiempo de espera en la espera utilizando las funciones miembro wait_for()o wait_until()para evitar un bloqueo indefinido. Si el futuro surgió de una llamada a std::asyncentonces una espera de bloqueo (sin tiempo de espera) puede provocar una invocación sincrónica de la función para calcular el resultado en el hilo en espera.

Construcciones relacionadas

Los futuros son un caso particular de los " eventos " primitivos de sincronización , que sólo pueden completarse una vez. En general, los eventos se pueden restablecer al estado vacío inicial y, por lo tanto, completarse tantas veces como desee. [11]

Una I-var (como en el lenguaje Id ) es un futuro con semántica de bloqueo como se define anteriormente. Una estructura I es una estructura de datos que contiene I-vars. Una construcción de sincronización relacionada que se puede configurar varias veces con diferentes valores se denomina M-var . M-vars admite operaciones atómicas para tomar o colocar el valor actual, donde tomar el valor también devuelve M-var a su estado vacío inicial . [12]

Una variable lógica concurrente [ cita requerida ] es similar a un futuro, pero se actualiza mediante unificación , de la misma manera que las variables lógicas en la programación lógica . Por lo tanto, puede vincularse más de una vez a valores unificables, pero no puede devolverse a un estado vacío o sin resolver. Las variables de flujo de datos de Oz actúan como variables lógicas concurrentes y también tienen una semántica de bloqueo como se mencionó anteriormente.

Una variable de restricción concurrente es una generalización de variables lógicas concurrentes para soportar la programación lógica de restricciones : la restricción puede reducirse varias veces, indicando conjuntos más pequeños de valores posibles. Normalmente hay una manera de especificar un procesador que debería ejecutarse siempre que la restricción se reduzca aún más; esto es necesario para soportar la propagación de restricciones .

Relaciones entre la expresividad de diferentes formas de futuro.

Los futuros ansiosos de subprocesos específicos se pueden implementar directamente en futuros no específicos de subprocesos, creando un subproceso para calcular el valor al mismo tiempo que se crea el futuro. En este caso, es deseable devolver una vista de solo lectura al cliente, de modo que solo el hilo recién creado pueda resolver este futuro.

Para implementar futuros implícitos específicos de subprocesos diferidos (como los proporcionados por Alice ML, por ejemplo) en términos de futuros no específicos de subprocesos, se necesita un mecanismo para determinar cuándo se necesita por primera vez el valor del futuro (por ejemplo, la WaitNeededconstrucción en Oz [13 ] ). Si todos los valores son objetos, entonces la capacidad de implementar objetos de reenvío transparentes es suficiente, ya que el primer mensaje enviado al reenviador indica que se necesita el valor futuro.

Los futuros no específicos de subprocesos se pueden implementar en futuros específicos de subprocesos, suponiendo que el sistema admita el paso de mensajes, haciendo que el subproceso de resolución envíe un mensaje al propio subproceso del futuro. Sin embargo, esto puede verse como una complejidad innecesaria. En los lenguajes de programación basados ​​en subprocesos, el enfoque más expresivo parece ser proporcionar una combinación de futuros no específicos de subprocesos, vistas de solo lectura y una construcción WaitNeeded o soporte para reenvío transparente.

Estrategia de evaluación

La estrategia de evaluación de futuros, que puede denominarse llamada por futuro , no es determinista: el valor de un futuro se evaluará en algún momento entre el momento en que se crea el futuro y el momento en que se utiliza su valor, pero no se determina el momento preciso. de antemano y puede cambiar de una ejecución a otra. El cálculo puede comenzar tan pronto como se crea el futuro ( evaluación ansiosa ) o solo cuando el valor realmente se necesita ( evaluación diferida ), y puede suspenderse a la mitad o ejecutarse en una sola ejecución. Una vez asignado el valor de un futuro, no se vuelve a calcular en accesos futuros; Esto es como la memorización utilizada en la llamada por necesidad .

AEl futuro perezoso es un futuro que de manera determinista tiene una semántica de evaluación perezosa: el cálculo del valor del futuro comienza cuando el valor se necesita por primera vez, como en la llamada por necesidad. Los futuros perezosos son útiles en lenguajes cuya estrategia de evaluación no es perezosa por defecto. Por ejemplo, enC++ 11,estos futuros perezosos se pueden crear pasando lastd::launch::deferredpolítica de lanzamiento astd::async, junto con la función para calcular el valor.

Semántica de futuros en el modelo actor.

En el modelo de actor, una expresión del formulario future <Expression>se define por cómo responde a un Evalmensaje con el entorno E y el cliente C de la siguiente manera: La expresión futura responde al Evalmensaje enviando al cliente C un actor F recién creado (el proxy para el respuesta de evaluación <Expression>) como valor de retorno al mismo tiempo que se envía <Expression>un Evalmensaje con el entorno E y el cliente C. El comportamiento predeterminado de F es el siguiente:

Sin embargo, algunos futuros pueden abordar solicitudes de formas especiales para proporcionar un mayor paralelismo. Por ejemplo, la expresión 1 + future factorial(n)puede crear un nuevo futuro que se comportará como el número 1+factorial(n). Este truco no siempre funciona. Por ejemplo, la siguiente expresión condicional:

if m>future factorial(n) then print("bigger") else print("smaller")

se suspende hasta que el futuro for factorial(n)haya respondido a la solicitud preguntando si mes mayor que él mismo.

Historia

Las construcciones de futuro y/o promesa se implementaron por primera vez en lenguajes de programación como MultiLisp y Act 1 . El uso de variables lógicas para la comunicación en lenguajes de programación lógica concurrente era bastante similar al de los futuros. Estos comenzaron en Prolog con Freeze e IC Prolog , y se convirtieron en una verdadera primitiva de concurrencia con Relational Language, Concurrent Prolog , cláusulas Horn protegidas (GHC), Parlog , Strand , Vulcan , Janus , Oz-Mozart , Flow Java y Alice ML . La I-var de asignación única de los lenguajes de programación de flujo de datos , que se origina en Id y se incluye en Concurrent ML de Reppy , es muy parecida a la variable lógica concurrente.

La técnica de canalización de promesas (usar futuros para superar la latencia) fue inventada por Barbara Liskov y Liuba Shrira en 1988, [6] e independientemente por Mark S. Miller , Dean Tribble y Rob Jellinghaus en el contexto del Proyecto Xanadu alrededor de 1989. [14]

El término promesa fue acuñado por Liskov y Shrira, aunque se referían al mecanismo de canalización con el nombre call-stream , que ahora rara vez se utiliza.

Tanto el diseño descrito en el artículo de Liskov y Shrira como la implementación de la canalización de promesas en Xanadu tenían el límite de que los valores de promesa no eran de primera clase : un argumento o el valor devuelto por una llamada o envío no podía ser directamente una promesa. (Por lo tanto, el ejemplo de canalización de promesas dado anteriormente, que utiliza una promesa para el resultado de un envío como argumento para otro, no habría sido expresable directamente en el diseño del flujo de llamadas o en la implementación de Xanadu). Parece que las promesas y los flujos de llamadas nunca se implementaron en ninguna versión pública de Argus, [15] el lenguaje de programación utilizado en el artículo de Liskov y Shrira. El desarrollo de Argus se detuvo alrededor de 1988. [16] La implementación de Xanadu de la canalización de promesas solo estuvo disponible públicamente con el lanzamiento del código fuente de Udanax Gold [17] en 1999, y nunca se explicó en ningún documento publicado. [18] Las implementaciones posteriores en Joule y E admiten promesas y resolutores totalmente de primera clase.

Varios de los primeros lenguajes de actores, incluida la serie Act, [19] [20] admitían tanto el paso de mensajes paralelos como el procesamiento de mensajes canalizados, pero no el canalización de promesas. (Aunque es técnicamente posible implementar la última de estas características en los dos primeros, no hay evidencia de que los idiomas de la Ley lo hicieran).

Después de 2000, se produjo un importante resurgimiento del interés en futuros y promesas, debido a su uso en la capacidad de respuesta de las interfaces de usuario, y en el desarrollo web , debido al modelo de transmisión de mensajes de solicitud-respuesta . Varios lenguajes convencionales ahora tienen soporte de lenguaje para futuros y promesas, más notablemente popularizados FutureTasken Java 5 (anunciado en 2004) [21] y las construcciones async/await en .NET 4.5 (anunciado en 2010, lanzado en 2012) [22] [23] en gran medida inspirado en los flujos de trabajo asincrónicos de F#, [24] que data de 2007. [25] Esto ha sido adoptado posteriormente por otros lenguajes, en particular Dart (2014), [26] Python (2015), [27] Hack (HHVM), y borradores de ECMAScript 7 (JavaScript), Scala y C++ (2011).

Lista de implementaciones

Algunos lenguajes de programación admiten futuros, promesas, variables lógicas concurrentes, variables de flujo de datos o I-vars, ya sea mediante soporte de lenguaje directo o en la biblioteca estándar.

Lista de conceptos relacionados con futuros y promesas por lenguaje de programación

Los lenguajes que también respaldan la canalización de promesas incluyen:

Lista de implementaciones de futuros basadas en bibliotecas

Corrutinas

Los futuros se pueden implementar en corrutinas [27] o generadores , [103] , lo que da como resultado la misma estrategia de evaluación (por ejemplo, multitarea cooperativa o evaluación diferida).

Canales

Los futuros se pueden implementar fácilmente en canales : un futuro es un canal de un solo elemento y una promesa es un proceso que envía al canal, cumpliendo el futuro. [104] [105] Esto permite que futuros se implementen en lenguajes de programación concurrentes con soporte para canales, como CSP y Go . Los futuros resultantes son explícitos, ya que se debe acceder a ellos mediante la lectura del canal, y no solo mediante la evaluación.

Ver también

Referencias

  1. ^ Friedman, Daniel; David sabio (1976). El impacto de la programación aplicativa en el multiprocesamiento . Congreso Internacional sobre Procesamiento Paralelo. págs. 263–272.
    Versión preliminar de: Friedman, Daniel; Wise, David (abril de 1978). "Aspectos de la programación aplicativa para el procesamiento paralelo". Transacciones IEEE en computadoras . C-27 (4): 289–296. CiteSeerX 10.1.1.295.9692 . doi :10.1109/tc.1978.1675100. S2CID  16333366. 
  2. ^ Hibbard, Peter (1976). Instalaciones de procesamiento paralelo . Nuevas direcciones en lenguajes algorítmicos, (ed.) Stephen A. Schuman, IRIA, 1976.
  3. ^ Henry panadero; Carl Hewitt (agosto de 1977). Los procesos de recolección incremental de basura. Actas del Simposio sobre lenguajes de programación de inteligencia artificial. Avisos ACM SIGPLAN 12, 8. págs. Archivado desde el original el 4 de julio de 2008 . Consultado el 13 de febrero de 2015 .
  4. ^ Canalización de promesas en erights.org
  5. ^ Canalización de promesas en la wiki de C2
  6. ^ ab Barbara Liskov; Liuba Shrira (1988). "Promesas: soporte lingüístico para llamadas a procedimientos asincrónicos eficientes en sistemas distribuidos". Actas de la Conferencia SIGPLAN '88 sobre diseño e implementación de lenguajes de programación; Atlanta, Georgia, Estados Unidos . ACM. págs. 260–267. doi :10.1145/53990.54016. ISBN 0-89791-269-1.También publicado en ACM SIGPLAN Avisos 23 (7).
  7. ^ Promesas sólidas con Dojo diferido, Site Pen, 3 de mayo de 2010
  8. ^ ab "Promise", Alice Manual , DE: Uni-SB, archivado desde el original el 8 de octubre de 2008 , consultado el 21 de marzo de 2007
  9. ^ ab "Future", manual de Alice , DE: Uni-SB, archivado desde el original el 6 de octubre de 2008 , consultado el 21 de marzo de 2007
  10. ^ Promesa, derechos E
  11. ^ 500 líneas o menos, "Un rastreador web con rutinas asyncio" de A. Jesse Jiryu Davis y Guido van Rossum dice "la implementación utiliza un evento asyncio.Event en lugar del futuro que se muestra aquí. La diferencia es que un evento se puede restablecer, mientras que un Futuro no puede pasar de resuelto a pendiente."
  12. ^ Controlar MVar concurrente, Haskell, archivado desde el original el 18 de abril de 2009
  13. ^ WaitNeeded, Mozart Oz, archivado desde el original el 17 de mayo de 2013 , consultado el 21 de marzo de 2007
  14. ^ Promise, Sunless Sea, archivado desde el original el 23 de octubre de 2007
  15. ^ Argos, MIT
  16. ^ Liskov, Barbara (26 de enero de 2021), Computación distribuida y Argus, Historia oral, IEEE GHN
  17. ^ Gold, Udanax, archivado desde el original el 11 de octubre de 2008
  18. ^ Tubería, derechos E
  19. ^ Henry Lieberman (junio de 1981). "Una vista previa del acto 1". Nota 625 del MIT AI. {{cite journal}}: Citar diario requiere |journal=( ayuda )
  20. ^ Henry Lieberman (junio de 1981). "Pensar en muchas cosas a la vez sin confundirse: paralelismo en el acto 1". Nota 626 del MIT AI. {{cite journal}}: Citar diario requiere |journal=( ayuda )
  21. ^ Goetz, Brian (23 de noviembre de 2004). "Simultaneidad en JDK 5.0". IBM .
  22. ^ ab "Async en 4.5: vale la pena esperar - Blog .NET - Inicio del sitio - Blogs de MSDN". Blogs.msdn.com . Consultado el 13 de mayo de 2014 .
  23. ^ abc "Programación asincrónica con Async y Await (C# y Visual Basic)". msdn.microsoft.com . Consultado el 13 de mayo de 2014 .
  24. ^ Tomas Petricek (29 de octubre de 2010). "C# y F# asíncronos (I.): Introducción simultánea".
  25. ^ Don Syme; Tomás Petricek; Dmitry Lomov (21 de octubre de 2010). "El modelo de programación asincrónica de F#, PADL 2011".
  26. ^ ab Gilad Bracha (octubre de 2014). "Soporte de asincronía del lenguaje Dart: fase 1".
  27. ^ ab "PEP 0492 - Corrutinas con sintaxis asíncrona y en espera".
  28. ^ Kenjiro Taura; Satoshi Matsuoka; Akinori Yonezawa (1994). "ABCL / f: un lenguaje orientado a objetos concurrente tipificado polimórfico basado en el futuro: su diseño e implementación". En Actas del taller DIMACS sobre Especificación de algoritmos paralelos, número 18 de la Serie Dimacs en Matemáticas Discretas e Informática Teórica . Sociedad Matemática Estadounidense. págs. 275–292. CiteSeerX 10.1.1.23.1161 . 
  29. ^ "Completador asíncrono de dardos SDK de Dart".
  30. ^ "Tarea".
  31. ^ Steve Dekorte (2005). "Io, el lenguaje de programación".
  32. ^ "Usar promesas". Red de desarrolladores de Mozilla . Consultado el 23 de febrero de 2021 .
  33. ^ "Facilitando la programación asincrónica con async y await". Red de desarrolladores de Mozilla . Consultado el 23 de febrero de 2021 .
  34. ^ Rico Hickey (2009). "cambios.txt en 1.1.x del clojure de Richhickey". GitHub .
  35. ^ "Futuro: lenguaje de programación Kotlin".
  36. ^ Seif Haridi; Nils Franzen. "Tutorial de Oz". Biblioteca global de usuarios de Mozart. Archivado desde el original el 14 de mayo de 2011 . Consultado el 12 de abril de 2011 .
  37. ^ Lanzamiento de Python 3.2
  38. ^ Lanzamiento de Python 3.5
  39. ^ "Paralelismo con los futuros". PLT . Consultado el 2 de marzo de 2012 .
  40. ^ "Promesa de clase". raku.org . Consultado el 19 de agosto de 2022 .
  41. ^ "Futuro en std::future - Rust". doc.rust-lang.org . Consultado el 16 de diciembre de 2023 .
  42. ^ Mirlo ceceo común
  43. ^ Common Lisp ansioso por el futuro2
  44. ^ Lisp en paralelo: una biblioteca de programación paralela para Common Lisp
  45. ^ Llamada PC Lisp común
  46. ^ "Capítulo 30. Hilo 4.0.0" . Consultado el 26 de junio de 2013 .
  47. ^ "Biblioteca Dlib C++ #thread_pool" . Consultado el 26 de junio de 2013 .
  48. ^ "GitHub - facebook/folly: una biblioteca C++ de código abierto desarrollada y utilizada en Facebook". GitHub . 8 de enero de 2019.
  49. ^ "HPX". 10 de febrero de 2019.
  50. ^ "Diapositivas de hilos de POCO" (PDF) .
  51. ^ "QtCore 5.0: Clase QFuture". Proyecto Qt. Archivado desde el original el 1 de junio de 2013 . Consultado el 26 de junio de 2013 .
  52. ^ "Estrella de mar". Proyecto Seastar . Consultado el 22 de agosto de 2016 .
  53. ^ "stlab es el trabajo en curso de lo que era el Laboratorio de tecnología de software de Adobe. Las bibliotecas fuente de Adobe (ASL), las bibliotecas de plataforma y las nuevas bibliotecas stlab están alojadas en github". 31 de enero de 2021.
  54. ^ Groovy GPars Archivado el 12 de enero de 2013 en Wayback Machine.
  55. ^ Cujo.js
  56. ^ JavaScript cuando.js
  57. ^ Promesas/especificación A+
  58. ^ promesas
  59. ^ JavaScript MochKit.Async
  60. ^ JavaScript Angularjs
  61. ^ Promesa de nodo de JavaScript
  62. ^ "JavaScript Q". Archivado desde el original el 31 de diciembre de 2018 . Consultado el 8 de abril de 2013 .
  63. ^ JavaScript RSVP.js
  64. ^ Biblioteca de clases YUI JavaScript
  65. ^ Clase de promesa YUI JavaScript
  66. ^ JavaScript pájaro azul
  67. ^ Java JDiferido
  68. ^ Java ParSeq
  69. ^ Objective-C MAFuture GitHub
  70. ^ Objective-C MAFuture mikeash.com
  71. ^ Promesa RX de Objective-C
  72. ^ ObjC-ColapsingFutures
  73. ^ Kit de promesas de Objective-C
  74. ^ Promesa objc de Objective-C
  75. ^ Objective-C OAPromesa
  76. ^ OCaml perezoso
  77. ^ Futuro de Perl
  78. ^ Promesas de Perl
  79. ^ Perl reflejo
  80. ^ Promesa de Perl :: ES6
  81. ^ "Promise::XS - Promesas rápidas en Perl - metacpan.org". metacpan.org . Consultado el 14 de febrero de 2021 .
  82. ^ PHP reacciona/promesa
  83. ^ Implementación incorporada de Python
  84. ^ futuros de Python
  85. ^ "Torcidos diferidos". Archivado desde el original el 6 de agosto de 2020 . Consultado el 29 de abril de 2010 .
  86. ^ Futuro del paquete R
  87. ^ futuro
  88. ^ Rubí concurrente
  89. ^ Gema de la promesa de rubí
  90. ^ Rubí libuv
  91. ^ "Gema de celuloide de rubí". Archivado desde el original el 8 de mayo de 2013 . Consultado el 19 de febrero de 2022 .
  92. ^ Ruby recurso futuro
  93. ^ caja de futuros-rs
  94. ^ Biblioteca de utilidades de Twitter
  95. ^ "Asíncrono rápido". Archivado desde el original el 31 de diciembre de 2018 . Consultado el 23 de junio de 2014 .
  96. ^ Kit de futuro rápido
  97. ^ MCD rápido de Apple
  98. ^ Swift FutureLib
  99. ^ bignerdranch/Diferido
  100. ^ Thomvis/Futures brillantes
  101. ^ belozierov/SwiftCoroutine
  102. ^ promesa tcl
  103. ^ ¿Async/await resuelve un problema real?
  104. ^ Ir a patrones de lenguaje Futuros
  105. ^ Ir a patrones de lenguaje

enlaces externos