clojure terminology future promise

¿En qué difieren los futuros y las promesas de Clojure?



terminology future (4)

Tanto los futuros como las promesas se bloquean hasta que hayan calculado sus valores, entonces, ¿cuál es la diferencia entre ellos?


En primer lugar, una Promise es un Future . Creo que quieres saber la diferencia entre una Promise y un FutureTask .

Un Future representa un valor que no se conoce actualmente pero que se conocerá en el futuro.

Un FutureTask representa el resultado de un cálculo que sucederá en el futuro (tal vez en algún grupo de subprocesos). Cuando intenta acceder al resultado, si el cálculo aún no ha sucedido, bloquea. De lo contrario, el resultado se devuelve inmediatamente. No hay otra parte involucrada en el cálculo del resultado, ya que el cálculo lo especifica con anticipación.

Una Promise representa un resultado que será entregado por el que promete al prometido en el futuro. En este caso, usted es el prometido y el que promete es aquel que le dio el objeto Promise . De forma similar a FutureTask , si intenta acceder al resultado antes de que se cumpla la Promise , se bloquea hasta que el anunciante cumpla la Promise . Una vez que se cumple la Promise , obtienes el mismo valor siempre e inmediatamente. A diferencia de FutureTask , hay una otra parte involucrada aquí, una que hizo la Promise . Que otra parte es responsable de hacer el cálculo y cumplir la Promise .

En ese sentido, un FutureTask es una Promise te hiciste a ti mismo.


Respondiendo en términos de Clojure, estos son algunos ejemplos del screencast de Sean Devlin :

(def a-promise (promise)) (deliver a-promise :fred) (def f (future (some-sexp))) (deref f)

Tenga en cuenta que en la promesa está entregando explícitamente un valor que seleccione en un cálculo posterior ( :fred en este caso). El futuro, por otro lado, se está consumiendo en el mismo lugar en que se creó. El some-expr presumiblemente se lanza tras bambalinas y se calcula en tándem (eventualmente), pero si permanece sin evaluar en el momento en que se accede, el hilo bloquea hasta que esté disponible.

editado para agregar

Para ayudar a distinguir aún más entre una promesa y un futuro, tenga en cuenta lo siguiente:

promesa

  1. Tú creas una promise . Ese objeto prometido ahora se puede pasar a cualquier hilo.
  2. Continúa con los cálculos. Estos pueden ser cálculos muy complicados que involucran efectos secundarios, descarga de datos, entrada del usuario, acceso a la base de datos, otras promesas, lo que quiera. El código se parecerá mucho a su código de línea principal en cualquier programa.
  3. Cuando hayas terminado, puedes deliver los resultados a ese objeto prometido.
  4. Cualquier artículo que intente deref su promesa antes de que haya terminado con su cálculo se bloqueará hasta que haya terminado. Una vez que haya terminado y haya deliver la promesa, la promesa no se bloqueará más.

futuro

  1. Tu creas tu futuro Parte de tu futuro es una expresión para el cálculo.
  2. El futuro puede o no ejecutarse concurrentemente. Se podría asignar un hilo, posiblemente de un grupo. Podría simplemente esperar y no hacer nada. Desde su perspectiva, no puede decirlo .
  3. En algún punto, usted (u otro hilo) deref el futuro. Si el cálculo ya se ha completado, obtendrá los resultados. Si aún no se ha completado, bloquea hasta que lo haya hecho. (Presumiblemente, si aún no ha comenzado, la deref significa que comienza a ejecutarse, pero esto tampoco está garantizado).

Si bien puede hacer que la expresión en el futuro sea tan complicada como el código que sigue a la creación de una promesa, es dudoso que sea deseable. Esto significa que los futuros son realmente más adecuados para cálculos rápidos en segundo plano, mientras que las promesas son realmente más adecuadas para rutas de ejecución grandes y complicadas. Además, las promesas parecen, en términos de cálculos disponibles, un poco más flexibles y orientadas hacia el creador de la promesa que hace el trabajo y otro hilo que cosecha la cosecha. Los futuros están más orientados a iniciar automáticamente un hilo (sin la sobrecarga fea y propensa a errores) y continuar con otras cosas hasta que usted, el hilo de origen, necesite los resultados.


Tanto Future como Promise son mecanismos para comunicar el resultado del cálculo asincrónico desde Producer a Consumer (s).

En caso de Futuro, el cálculo se define en el momento de la creación futura y la ejecución asíncrona comienza "ASAP". También "sabe" cómo generar un cálculo asincrónico.

En el caso de Promise, el cómputo , su hora de inicio y la invocación asíncrona [posible] están desacopladas del mecanismo de entrega. Cuando el resultado de cálculo está disponible, Producer debe llamar a deliver explícitamente, lo que también significa que Producer controla cuando el resultado está disponible.

Para Promesas, Clojure comete un error de diseño al usar el mismo objeto (resultado de llamada promise ) para producir ( deliver ) y consumir ( deref ) el resultado de la computación . Estas son dos capacidades muy distintas y deben tratarse como tales.


Ya hay respuestas excelentes por lo que solo se agrega el resumen de "cómo usarlo":

Ambos

Crear promesa o futuro devuelve una referencia de inmediato. Esta referencia bloquea en @ / deref hasta que el resultado del cálculo sea proporcionado por otro hilo.

Futuro

Al crear un futuro, proporciona un trabajo sincrónico por hacer. Se ejecuta en un hilo del grupo ilimitado dedicado.

Promesa

No das argumentos cuando creas una promesa. La referencia debe pasarse a otro hilo ''usuario'' que deliver el resultado.