En informática , los futuros , las promesas , los retrasos y los diferidos son construcciones que se utilizan para sincronizar la ejecución de programas en algunos lenguajes de programación concurrentes . Cada uno es un objeto que actúa como un sustituto de un resultado inicialmente desconocido, generalmente porque el cálculo de su valor aún no ha finalizado.
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 algo similar, futuro, fue introducido en 1977 en un artículo de Henry Baker y Carl Hewitt . [ 3 ]
Los términos futuro , promesa , retraso y diferido se suelen usar indistintamente, aunque existen algunas diferencias en su uso . En concreto, cuando se distinguen, un futuro es una representación de una variable de solo lectura , mientras que una promesa es un contenedor de asignación única y modificable que establece el valor del futuro. Cabe destacar que un futuro puede definirse sin especificar qué promesa concreta establecerá su valor, y diferentes promesas pueden establecer el valor de un futuro dado, aunque esto solo 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 asíncrona (promesa). Establecer el valor de un futuro también se denomina resolverlo , cumplirlo o vincularlo .
Aplicaciones
Las promesas y los futuros 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 calculaba (una promesa), lo que permitía realizar el cálculo de forma más flexible, sobre todo mediante la paralelización. Posteriormente, se utilizaron en la computación distribuida para reducir la latencia de las comunicaciones. Más tarde, su uso se amplió al permitir escribir programas asíncronos de forma directa , en lugar de hacerlo mediante el paso de continuaciones .
Implícito frente a 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 `get` java.util.concurrent.Futureen Java ). Obtener el valor de un futuro explícito se denomina "stinging" o "forcing" . Los futuros explícitos pueden implementarse como una biblioteca, mientras que los futuros implícitos suelen implementarse como parte del lenguaje.
El artículo original de Baker y Hewitt describía futuros implícitos, que son soportados naturalmente en el modelo de actor de computación y en lenguajes de programación puramente orientados a objetos como Smalltalk . El artículo de Friedman y Wise describía solo futuros explícitos, probablemente reflejando la dificultad de implementar eficientemente futuros implícitos en hardware estándar. La dificultad radica en que el hardware estándar no maneja futuros para tipos de datos primitivos como los enteros. Por ejemplo, una instrucción de suma no sabe cómo manejar . En lenguajes de actor puro u orientados a objetos, este problema se puede resolver enviando el mensaje , que le pide al futuro que se sume a sí mismo y devuelva el resultado. Nótese que el enfoque de paso de mensajes funciona independientemente de cuándo finalice la computación y que no se necesita ninguna restricción/forzamiento.3 + future factorial(100000)future factorial(100000)+[3]3factorial(100000)
Promesas en desarrollo
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 ] como se implementa en los lenguajes E y Joule , que también se denominó flujo de llamadas [ 6 ] en el lenguaje Argus .
Consideremos una expresión que involucre 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 instrucción requiere que se envíe un mensaje y se reciba una respuesta antes de que la siguiente pueda ejecutarse. Supongamos, por ejemplo, que x, y, t1, y t2se encuentran en la misma máquina remota. En este caso, deben realizarse dos viajes de ida y vuelta completos a esa máquina antes de que la tercera instrucción pueda comenzar a ejecutarse. La tercera instrucción provocará entonces otro viaje de ida y vuelta a la misma máquina remota.
Utilizando 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 asíncrona a x. A las tres variables se les asignan inmediatamente futuros para sus resultados, y la ejecución procede a las instrucciones subsiguientes. Los intentos posteriores de resolver el valor de t3pueden causar un retraso; sin embargo, la canalización puede reducir el número de viajes de ida y vuelta necesarios. Si, como en el ejemplo anterior, x, y, t1, y t2están todos ubicados en la misma máquina remota, una implementación en canalización 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 están en la misma máquina remota, solo es necesario enviar una solicitud y solo 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 a xo y.
Es importante distinguir entre el procesamiento en paralelo de promesas y el paso de mensajes asíncrono en paralelo. En un sistema que admite el paso de mensajes en paralelo pero no el procesamiento en paralelo, el mensaje enviado x <- a()en y <- b()el ejemplo anterior podría procesarse en paralelo, pero el envío de t1 <- c(t2)tendría que esperar hasta que se recibieran ambos t1mensajes , incluso cuando , , , y se encuentren en la misma máquina remota. La ventaja de latencia relativa del procesamiento en paralelo se vuelve aún mayor en situaciones más complejas que involucran muchos mensajes.t2xyt1t2
Tampoco debe confundirse el procesamiento en paralelo de promesas con el procesamiento de mensajes en paralelo 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, que permite leer su valor cuando se resuelve, pero no permite resolverlo:
- En Oz, el
!!operador se utiliza para obtener una vista de solo lectura. - En E y AmbientTalk, un futuro se representa mediante un par de valores denominado par promesa/resolutor . La promesa representa la vista de solo lectura, y el resolvedor es necesario para establecer el valor del futuro.
- En C++ (desde C++11 ) un
std::futureproporciona una vista de solo lectura. El valor se establece directamente mediante unstd::promise, o se establece al resultado de una llamada a función mediantestd::packaged_taskostd::async. - En la API Deferred de Dojo Toolkit , a partir de la versión 1.5, un objeto de promesa exclusivo para el consumidor representa una vista de solo lectura. [ 7 ]
- En Alice ML , los futuros proporcionan una vista de solo lectura , mientras que una promesa contiene tanto un futuro como la capacidad de resolver el futuro [ 8 ] [ 9 ]
- En .NET
System.Threading.Tasks.Task<T>representa una vista de solo lectura. La resolución del valor se puede realizar a través deSystem.Threading.Tasks.TaskCompletionSource<T>.
La compatibilidad con vistas de solo lectura es coherente con el principio de mínimo privilegio , ya que permite restringir la capacidad de establecer el valor a los sujetos que necesitan hacerlo. En un sistema que también admite la canalización, el remitente de un mensaje asíncrono (con resultado) recibe la promesa de solo lectura del resultado, y el destinatario del mensaje recibe el resolvedor.
Futuros específicos de cada hilo
Algunos lenguajes, como Alice ML , definen futuros asociados a un hilo específico que calcula su valor. [ 9 ] Este cálculo puede iniciarse de forma inmediata al crearse el futuro o de forma diferida cuando se necesita su valor por primera vez. Un futuro diferido es similar a un thunk , en el sentido de un cálculo diferido.
Alice ML también admite futuros que pueden ser resueltos por cualquier hilo, y los denomina promesas . [ 8 ] Este uso de promesa es diferente de su uso en E, como se describió 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 de forma natural para futuros, incluidos aquellos asociados con promesas.
Semántica de bloqueo frente a semántica sin bloqueo
Si se accede al valor de una promesa de forma asíncrona, por ejemplo, enviándole un mensaje o esperándola explícitamente mediante una construcción como whenen E, no hay problema en retrasar la espera hasta que la promesa se resuelva antes de recibir el mensaje o finalizar la espera. Este es el único caso que debe considerarse en sistemas puramente asíncronos, como los lenguajes de actores puros.
Sin embargo, en algunos sistemas también puede ser posible intentar acceder de forma inmediata o sincrónica al valor de un futuro. En ese caso, hay que tomar una decisión de diseño:
- El acceso podría bloquear el hilo o proceso actual hasta que se resuelva el problema (posiblemente con un tiempo de espera). Esta es la semántica de las variables de flujo de datos en el lenguaje Oz .
- El intento de acceso síncrono siempre podría indicar un error, por ejemplo, lanzando una excepción . Esta es la semántica de las promesas remotas en E. [ 10 ]
- Potencialmente, el acceso podría tener éxito si el futuro ya está resuelto, pero señalar un error si no lo está. Esto tendría la desventaja de introducir indeterminismo y la posibilidad de condiciones de carrera , y parece ser una elección de diseño poco común.
Como ejemplo de la primera posibilidad, en C++11 , un hilo que necesita el valor de una promesa puede bloquearse hasta que esté disponible llamando a las funciones miembro wait()`get` o ` get()get`. También se puede especificar un tiempo de espera usando las funciones miembro wait_for()`get` o `get` wait_until()para evitar bloqueos indefinidos. Si la promesa surgió de una llamada a ` get`, std::asyncentonces una espera bloqueante (sin tiempo de espera) puede provocar la invocación síncrona de la función para calcular el resultado en el hilo en espera.
Construcciones relacionadas
Los futuros son un caso particular de la primitiva de sincronización " eventos ", que solo se pueden completar una vez. En general, los eventos se pueden restablecer a un estado vacío inicial y, por lo tanto, completarse tantas veces como se desee. [ 11 ]
Una I-var (como en el lenguaje Id ) es un futuro con semántica de bloqueo, tal como se definió anteriormente. Una I-estructura es una estructura de datos que contiene I-vars. Una construcción de sincronización relacionada que puede establecerse varias veces con diferentes valores se denomina M-var . Las M-vars admiten operaciones atómicas para tomar o poner el valor actual, donde tomar el valor también restablece la M-var a su estado vacío inicial . [ 12 ]
Una variable lógica concurrente es similar a un futuro, pero se actualiza mediante unificación , al igual 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 volver a un estado vacío o no resuelto. Las variables de flujo de datos de Oz actúan como variables lógicas concurrentes y también poseen semántica de bloqueo, como se mencionó anteriormente.
Una variable de restricción concurrente es una generalización de las variables de lógica concurrente para admitir la programación lógica con restricciones : la restricción puede restringirse varias veces, lo que indica conjuntos más pequeños de valores posibles. Normalmente, existe una forma de especificar una función diferida que debe ejecutarse cada vez que la restricción se restringe aún más; esto es necesario para admitir la propagación de restricciones .
Relaciones entre la expresividad de diferentes formas de futuro
Las promesas específicas de un hilo pueden implementarse fácilmente en promesas que no sean específicas de un hilo, creando un hilo para calcular el valor al mismo tiempo que se crea la promesa. En este caso, es conveniente devolver una vista de solo lectura al cliente, de modo que solo el hilo recién creado pueda resolver esta promesa.
Para implementar futuros implícitos perezosos específicos de hilo (como los que proporciona Alice ML, por ejemplo) en términos de futuros no específicos de hilo, 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 del futuro.
Las promesas no específicas de un hilo pueden implementarse dentro de promesas específicas de un hilo, siempre que el sistema admita el paso de mensajes, haciendo que el hilo que resuelve la promesa envíe un mensaje al hilo de la promesa. Sin embargo, esto puede considerarse una complejidad innecesaria. En los lenguajes de programación basados en hilos, el enfoque más expresivo parece ser proporcionar una combinación de promesas no específicas de un hilo, vistas de solo lectura y, o bien una construcción WaitNeeded , o bien compatibilidad con el 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 su creación y su uso, pero el momento preciso no se determina de antemano y puede variar de una ejecución a otra. El cálculo puede comenzar tan pronto como se crea el futuro ( evaluación inmediata ) o solo cuando se necesita el valor ( evaluación diferida ), y puede suspenderse a mitad de camino o ejecutarse en una sola ejecución. Una vez asignado el valor de un futuro, no se vuelve a calcular en los accesos posteriores; esto es similar a la memorización utilizada en la llamada por necesidad .
AUn futuro perezoso es un futuro que tiene una semántica de evaluación perezosa determinista: el cálculo del valor del futuro comienza cuando se necesita por primera vez, como en el caso de 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 los futuros en el modelo del actor
En el modelo de actor, una expresión de la forma 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 la respuesta de la evaluación <Expression>) como valor de retorno simultáneamente con el envío <Expression>de un Evalmensaje con el entorno E y el cliente C. El comportamiento predeterminado de F es el siguiente:
- Cuando F recibe una solicitud R , comprueba si ya ha recibido una respuesta (que puede ser un valor de retorno o una excepción lanzada) tras evaluar
<Expression>el procedimiento de la siguiente manera:- Si ya tiene una respuesta V , entonces
- Si V es un valor de retorno, entonces se envía la solicitud R.
- Si V es una excepción , entonces se lanza al cliente de la solicitud R.
- Si aún no tiene una respuesta, entonces R se almacena en la cola de solicitudes dentro de F.
- Si ya tiene una respuesta V , entonces
- Cuando F recibe la respuesta V de la evaluación
<Expression>, entonces V se almacena en F y- Si V es un valor de retorno, entonces todas las solicitudes en cola se envían a V.
- Si V es una excepción, se lanza al cliente de cada una de las solicitudes en cola.
Sin embargo, algunas promesas pueden manejar las solicitudes de maneras especiales para proporcionar mayor paralelismo. Por ejemplo, la expresión 1 + future factorial(n)puede crear una nueva promesa 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 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 fue bastante similar a 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 variable I de asignación única de los lenguajes de programación de flujo de datos , originada en Id e incluida en Concurrent ML de Reppy , es muy similar a la variable lógica concurrente.
La técnica de enrutamiento de promesas (que utiliza 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 ellos se referían al mecanismo de procesamiento en paralelo con el nombre de flujo de llamadas , que ahora se usa muy poco.
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 la limitación de que los valores de las promesas no eran de primera clase : un argumento para, o el valor devuelto por una llamada o envío no podía ser directamente una promesa (por lo que el ejemplo de canalización de promesas dado anteriormente, que usa una promesa para el resultado de un envío como argumento para otro, no habría sido directamente expresable en el diseño de flujo de llamadas ni 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 la canalización de promesas de Xanadu solo estuvo disponible públicamente con la publicación 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 de primera clase completos.
Varios lenguajes de actores primitivos, incluida la serie Act, [ 19 ] [ 20 ] admitían tanto el paso de mensajes en paralelo como el procesamiento de mensajes en paralelo, pero no el procesamiento en paralelo de promesas. (Aunque técnicamente es posible implementar la última de estas características en las dos primeras, no hay evidencia de que los lenguajes Act lo hicieran).
Después del año 2000, se produjo un importante resurgimiento del interés por los futuros y las promesas, debido a su uso en la capacidad de respuesta de las interfaces de usuario y en el desarrollo web , debido al modelo de solicitud-respuesta de paso de mensajes. Varios lenguajes principales ahora tienen soporte de lenguaje para futuros y promesas, popularizados de manera más notable por FutureTaskJava 5 (anunciado en 2004) [ 21 ] y las construcciones async/await en .NET 4.5 (anunciado en 2010, lanzado en 2012) [ 22 ] [ 23 ] inspirados en gran medida por los flujos de trabajo asíncronos de F#, [ 24 ] que data de 2007. [ 25 ] Esto ha sido posteriormente adoptado 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 de lógica concurrente, variables de flujo de datos o variables I, ya sea mediante soporte directo del lenguaje o en la biblioteca estándar.
Lista de conceptos relacionados con futuros y promesas por lenguaje de programación
- ABCL/f [ 28 ]
- Alicia ML
- AmbientTalk (incluidos los resolvedores de primera clase y las promesas de solo lectura)
- C++ , comenzando con C++11 a través
std::futurede ystd::promise- C++ compositivo
- Cristal
- Dart (con
Future/Completerclases [ 29 ] y las palabras claveawaityasync[ 26 ] ) - Elm a través del módulo de tareas [ 30 ]
- Haskell mediante bibliotecas
Control.Concurrent.Async(variables I) yControl.Concurrent.MVar(variables M) - Id (solo variables I y variables M)
- Io [ 31 ]
- Java a través de
java.util.concurrent.Futureojava.util.concurrent.CompletableFuture - JavaScript desde ECMAScript 2015, [ 32 ] y a través de las palabras clave
asyncyawaitdesde ECMAScript 2017 [ 33 ] - Lucid (solo flujo de datos)
- Algunos ceceos
- .NET via
System.Threading.Tasks.Task - Kotlin, although
kotlin.native.concurrent.Futureis only usually used when writing Kotlin that is intended to run natively[35] - Nim
- Oxygene
- Oz version 3[36]
- Python concurrent.futures,[37] since 3.2,[38] as proposed by the PEP 3148,[39] and Python 3.5 added
asyncandawait[40] - R (promises for lazy evaluation, still single threaded)
- Racket[41]
- Raku[42]
- Rust (future as
std::future::Future, promise achieved via.await)[43] - Scala via scala.concurrent package
- Scheme
- SqueakSmalltalk
- Strand
- Swift (only via third-party libraries)
- Visual Basic 11 (via the keywords Async and Await)[23]
Languages also supporting promise pipelining include:
List of library-based implementations of futures
- For Common Lisp:
- For C++:
- For C# and other .NET languages: The Parallel Extensions library
- For Groovy: GPars[56]
- For JavaScript:
- Cujo.js'[57] when.js[58] provides promises conforming to the Promises/A+[59] 1.1 specification
- El Dojo Toolkit proporciona promesas [ 60 ] y diferidos de estilo Twisted.
- MochiKit [ 61 ] inspirado en Deferreds de Twisted
- El objeto Deferred de jQuery se basa en el diseño Promises/A de CommonJS .
- AngularJS [ 62 ]
- nodo -promesa [ 63 ]
- Q, de Kris Kowal, se ajusta a Promises/A+ 1.1 [ 64 ]
- RSVP.js, cumple con Promises/A+ 1.1 [ 65 ]
- La clase de promesas de YUI [ 66 ] [ 67 ] se ajusta a la especificación Promises/A+ 1.0.
- Pájaro azul, de Petka Antonov [ 68 ]
- El paquete de promesas de Closure Library cumple con la especificación Promises/A+.
- Consulte la lista de Promise/A+ para ver más implementaciones basadas en el diseño de Promise/A+.
- Para Java :
- JDeferred proporciona una API de promesa diferida y un comportamiento similar al objeto jQuery .Deferred [ 69 ]
- ParSeq [ 70 ] proporciona una API de promesa de tareas ideal para la canalización y ramificación asíncronas, mantenida por LinkedIn.
- Para Lua :
- Las colasEl módulo contiene una API de promesas.
- Para Objective-C : MAFuture, [ 71 ] [ 72 ] RXPromise, [ 73 ] ObjC-CollapsingFutures, [ 74 ] PromiseKit, [ 75 ] objc-promise, [ 76 ] OAPromise, [ 77 ]
- Para OCaml : El módulo Lazy implementa futuros explícitos perezosos [ 78 ]
- Para Perl : Future, [ 79 ] Promises, [ 80 ] Reflex, [ 81 ] Promise::ES6, [ 82 ] y Promise::XS [ 83 ]
- Para PHP : React/Promise [ 84 ]
- Para Python :
- Implementación integrada [ 85 ]
- pythonfutures [ 86 ]
- Los diferidos de Twisted [ 87 ]
- Para R :
- Para Ruby :
- Para Rust :
- futuros-rs [ 95 ]
- Para Scala :
- Para Swift :
- Marco asíncrono, implementa el estilo C#
async/no bloqueanteawait[ 97 ] - FutureKit, [ 98 ] implementa una versión para Apple GCD [ 99 ]
- FutureLib, biblioteca pura de Swift 2 que implementa futuros y promesas al estilo Scala con cancelación al estilo TPL [ 100 ]
- Deferred, una biblioteca pura de Swift inspirada en Deferred de OCaml [ 101 ]
- BrightFutures [ 102 ]
- SwiftCoroutine [ 103 ]
- Marco asíncrono, implementa el estilo C#
- Para Tcl : tcl-promise [ 104 ]
Corrutinas
Los futuros se pueden implementar en corrutinas [ 27 ] o generadores [ 105 ] dando como resultado la misma estrategia de evaluación (por ejemplo, multitarea cooperativa o evaluación perezosa).
Canales
Las promesas se pueden implementar fácilmente en canales : una promesa es un canal de un solo elemento, y una promesa es un proceso que envía datos al canal, cumpliendo la promesa. [ 106 ] [ 107 ] Esto permite implementar promesas en lenguajes de programación concurrentes con soporte para canales, como CSP y Go . Las promesas resultantes son explícitas, ya que se debe acceder a ellas leyendo del canal, en lugar de solo evaluándolas.
Véase también
- Async/await
- Fibra (informática)
- Futex
- Pirámide de la perdición (programación) , un antipatrón de diseño evitado por las promesas.
Referencias
- ↑ Friedman, Daniel; David Wise (1976). El impacto de la programación aplicativa en el multiprocesamiento . Conferencia 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". IEEE Transactions on Computers . C-27 (4): 289– 296. CiteSeerX 10.1.1.295.9692 . doi : 10.1109/tc.1978.1675100 . S2CID 16333366 .
- ↑ Hibbard, Peter (1976). Parallel Processing Facilities . New Directions in Algorithmic Languages, (ed.) Stephen A. Schuman, IRIA, 1976.
- ↑ Henry Baker; Carl Hewitt (agosto de 1977). La recolección incremental de basura de procesos . Actas del Simposio sobre Lenguajes de Programación de Inteligencia Artificial. ACM SIGPLAN Notices 12, 8, págs. 55–59 . Archivado del original el 4 de julio de 2008. Consultado el 13 de febrero de 2015 .
- ↑ Promesas en desarrollo en erights.org
- ↑ Procesamiento de promesas en la wiki de C2
- 1 2 Barbara Liskov; Liuba Shrira (1988). "Promises: Linguistic Support for Efficient Asynchronous Procedure Calls in Distributed Systems". 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 Notices 23 (7).
- ↑ Promesas sólidas con Dojo postergadas , Site Pen, 3 de mayo de 2010
- 1 2 "Promesa" , Manual de Alice , DE: Uni-SB, archivado del original el 8 de octubre de 2008 , recuperado el 21 de marzo de 2007
- 1 2 "Futuro" , manual de Alice , DE: Uni-SB, archivado del original el 6 de octubre de 2008 , recuperado el 21 de marzo de 2007
- ↑ Promesa , derechos E
- ↑ 500 líneas o menos, "Un rastreador web con corrutinas asyncio" de A. Jesse Jiryu Davis y Guido van Rossum dice: "La implementación usa un asyncio.Event en lugar del Future que se muestra aquí. La diferencia es que un Event se puede reiniciar, mientras que un Future no puede pasar de resuelto a pendiente".
- ↑ Control Concurrent MVar , Haskell, archivado del original el 18 de abril de 2009.
- ↑ WaitNeeded , Mozart Oz, archivado del original el 17 de mayo de 2013 , recuperado el 21 de marzo de 2007.
- ↑ Promise , Sunless Sea, archivado del original el 23 de octubre de 2007.
- ↑ Argus , MIT
- ↑ Liskov, Barbara (26 de enero de 2021), Computación distribuida y Argus , Historia oral, IEEE GHN
- ↑ Oro , Udanax, archivado del original el 11 de octubre de 2008.
- ↑ Oleoducto , derechos E
- ↑ Henry Lieberman (junio de 1981). "Un avance del acto 1". MIT AI Memo 625 .
- ↑ Henry Lieberman (junio de 1981). "Pensar en muchas cosas a la vez sin confundirse: paralelismo en el acto 1". MIT AI Memo 626 .
- ↑ Goetz, Brian (23 de noviembre de 2004). "Concurrencia en JDK 5.0" . IBM .
- 1 2 "Async en 4.5: Vale la pena esperar – Blog de .NET – Página principal – Blogs de MSDN" . Blogs.msdn.com . Consultado el 13 de mayo de 2014 .
- 1 2 3 "Programación asíncrona con Async y Await (C# y Visual Basic)" . Msdn.microsoft.com . Consultado el 13 de mayo de 2014 .
- ↑ Tomas Petricek (29 de octubre de 2010). "C# y F# asíncronos (I.): Introducción simultánea" .
- ^ Don Syme; Tomás Petricek; Dmitry Lomov (21 de octubre de 2010). "El modelo de programación asincrónica de F#, PADL 2011" .
- 1 2 Bracha, Gilad (octubre de 2014). "Soporte para la asincronía del lenguaje Dart: Fase 1" .
- 1 2 "PEP 0492 – Corrutinas con sintaxis async y await" .
- ↑ Taura, Kenjiro; Matsuoka, Satoshi; Yonezawa, Akinori (1994). "ABCL/f: Un lenguaje orientado a objetos concurrente, polimórfico y tipado basado en el futuro: su diseño e implementación". Actas del taller DIMACS sobre especificación de algoritmos paralelos . Serie Dimacs en matemáticas discretas e informática teórica. Vol. 18. Sociedad Matemática Americana. págs. 275–292 . CiteSeerX 10.1.1.23.1161 .
- ↑ «Completador asíncrono de dardos SDK de Dart» .
- ↑ "Tarea" .
- ↑ Steve Dekorte (2005). "Io, el lenguaje de programación" .
- ↑ "Uso de promesas" . Mozilla Developer Network . Consultado el 23 de febrero de 2021 .
- ↑ "Facilitando la programación asíncrona con async y await" . Mozilla Developer Network . Consultado el 23 de febrero de 2021 .
- ↑ Hickey, Rich (2009). "changes.txt en 1.1.x del clojure de richhickey" . GitHub .
- ↑ "Futuro – Lenguaje de programación Kotlin" .
- ↑ Haridi, Seif; Franzen, Nils. "Tutorial de Oz" . Mozart Global User Library. Archivado del original el 14 de mayo de 2011. Consultado el 12 de abril de 2011 .
- ↑ "concurrent.futures — Lanzamiento de tareas paralelas" . Documentación de Python . Consultado el 25 de marzo de 2026 .
- ↑ Versión de Python 3.2
- ↑ "PEP 3148 – futures - ejecutar cálculos de forma asíncrona | peps.python.org" . Propuestas de mejora de Python (PEPs) . Consultado el 25 de marzo de 2026 .
- ↑ Versión de Python 3.5
- ↑ "Paralelismo con los futuros" . PLT . Consultado el 2 de marzo de 2012 .
- ↑ "clase Promise" . raku.org . Consultado el 19 de agosto de 2022 .
- ↑ "Future en std::future - Rust" . doc.rust-lang.org . Consultado el 16 de diciembre de 2023 .
- ↑ Mirlo común de ceceo
- ↑ Common Lisp Eager Future2
- ↑ Lisp en paralelo: una biblioteca de programación paralela para Common Lisp
- ↑ Common Lisp PCall
- ↑ "Capítulo 30. Hilo 4.0.0" . Consultado el 26 de junio de 2013 .
- ↑ "Biblioteca Dlib C++ #thread_pool" . Consultado el 26 de junio de 2013 .
- ↑ "GitHub – facebook/folly: Una biblioteca C++ de código abierto desarrollada y utilizada en Facebook" . GitHub . 8 de enero de 2019.
- ↑ "HPX" . 10 de febrero de 2019.
- ↑ "Diapositivas de hilos de POCO" (PDF) .
- ↑ "QtCore 5.0: QFuture Class" . Proyecto Qt. Archivado del original el 1 de junio de 2013. Consultado el 26 de junio de 2013 .
- ↑ «Estrella de mar» . Proyecto Seastar . Consultado el 22 de agosto de 2016 .
- ↑ "stlab es el trabajo continuo de lo que fue el Laboratorio de Tecnología de Software de Adobe. Las bibliotecas de código fuente de Adobe (ASL), las bibliotecas de plataforma y las nuevas bibliotecas de stlab están alojadas en GitHub" . 31 de enero de 2021.
- ↑ Groovy GPars Archivado el 12 de enero de 2013 en Wayback Machine
- ↑ Cujo.js
- ↑ JavaScript when.js
- ↑ Promesas/Especificación A+
- ↑ promesas
- ↑ JavaScript MochKit.Async
- ↑ JavaScript Angularjs
- ↑ Promesa de nodo JavaScript
- ↑ "JavaScript Q" . Archivado del original el 31 de diciembre de 2018. Consultado el 8 de abril de 2013 .
- ↑ JavaScript RSVP.js
- ↑ Biblioteca de clases JavaScript de YUI
- ↑ Clase de promesa de JavaScript de YUI
- ↑ JavaScript Bluebird
- ↑ Java JDeferred
- ↑ Java ParSeq
- ↑ Objective-C MAFuture GitHub
- ↑ Objective-C MAFuture mikeash.com
- ↑ Promesa RX de Objective-C
- ↑ ObjC-CollapsingFutures
- ↑ Kit de promesas de Objective-C
- ↑ Promesa objc de Objective-C
- ↑ Promesa OAProme de Objective-C
- ↑ OCaml Lazy
- ↑ Futuro de Perl
- ↑ Promesas de Perl
- ↑ Perl Reflex
- ↑ Perl Promise::ES6
- ↑ "Promise::XS – Promesas rápidas en Perl – metacpan.org" . metacpan.org . Consultado el 14 de febrero de 2021 .
- ↑ PHP React/Promise
- ↑ Implementación integrada de Python
- ↑ pythonfutures
- ↑ "Referencia diferida" . Documentación distorsionada . Twisted Matrix Labs. Archivado del original el 25 de junio de 2026.
- ↑ Futuro del paquete R
- ↑ futuro
- ↑ Ruby concurrente
- ↑ Gema Ruby Promise
- ↑ Ruby libuv
- ↑ "Gema de celuloide rubí" . Archivado del original el 8 de mayo de 2013. Consultado el 19 de febrero de 2022 .
- ↑ Recurso futuro de Ruby
- ↑ caja futures-rs
- ↑ Biblioteca de utilidades de Twitter
- ↑ "Swift Async" . Archivado del original el 31 de diciembre de 2018. Consultado el 23 de junio de 2014 .
- ↑ Swift FutureKit
- ↑ Swift Apple GCD
- ↑ Swift FutureLib
- ↑ bignerdranch/Aplazado
- ↑ Thomvis/BrightFutures
- ↑ belozierov/SwiftCoroutine
- ↑ promesa tcl
- ↑ ¿Resuelve async/await un problema real?
- ↑ "Patrones del lenguaje Go: Futuros" . Archivado del original el 4 de diciembre de 2020. Recuperado el 9 de febrero de 2014 .
- ↑ "Patrones del lenguaje Go" . Archivado del original el 11 de noviembre de 2020. Consultado el 9 de febrero de 2014 .
Enlaces externos
- Presentación sobre patrones de concurrencia en ScaleConf.
- Generación de valor futuro y potencial en el repositorio de patrones de Portland
- Programación en cadena sencilla con Futures en Python
- Comunicación entre procesos
- Modelo de actor (informática)