clojure var agent

Diferencias de Clojure entre Ref, Var, Agent, Atom, con ejemplos



(5)

átomos, refs y agentes - algo de iluminación aquí http://blog.jayfields.com/2011/04/clojure-state-management.html

Soy nuevo en Clojure, ¿pueden darme explicaciones con escenarios del mundo real? Quiero decir, dónde usar Ref, Var, Agent, Atom. Leí el libro, pero todavía no podía entender los ejemplos del mundo real.


Cuando leí por primera vez acerca de estos tipos, también tuve problemas para entender dónde podía o debería usar cada uno, así que aquí está mi respuesta sencilla en inglés:

Use una var cuando los datos no cambien. Esto sucede cada vez que usas def o la mayoría de las funciones que comienzan con def defn .

Use un átomo cuando tenga un único elemento que cambie. Un ejemplo podría ser un contador o un vector al que desee agregar elementos.

Use un ref cuando tenga dos o más cosas que deben cambiar al mismo tiempo. Piense en "transacciones de base de datos" si está familiarizado. El ejemplo canónico de esto es transferir dinero de una cuenta a otra. Cada cuenta puede almacenarse en una referencia para que los cambios puedan hacerse atómicos.

Use un agente cuando desee que algo cambie, pero no le importa cuándo. Esto puede ser un cálculo largo o escribir algo en un archivo o socket. Tenga en cuenta que con este último debería usar send-off .

Nota: Aprecio que haya mucho más para cada uno de estos, pero espero que esto te dé un punto de partida.


Escribí el artículo con un resumen de la diferencia entre ellos y ayudo a elegir cuándo usarlo.

Estado compartido: cuando se usan vars, átomos, agentes y refs?

Espero que ayude a las personas que buscan respuestas sobre ese tema.

Algunos atajos del artículo después de la sugerencia de @tunaci:

Vars

Los Vars son globales para cada hilo.

No cambie los vars después de crear. Es técnicamente posible, pero es una mala idea por muchas razones.

Átomos

Compartir acceso al estado mutable para cada subproceso. El cambio ocurre sincrónicamente. Vuelva a intentar cuando otro hilo cambie el estado durante la ejecución.

No use funciones ni funciones idempotentes con ejecución a largo plazo

Agentes

Compartir acceso al estado mutable para cada subproceso. El cambio ocurre de forma asincrónica.

Refs

Refs funciona de forma similar a las transacciones de base de datos. Escribir y leer son proteger en dosync. Puede operar en muchos refs seguros en la transacción.

Y diagrama de flujo cuando use cual:

Mire la imagen en el sitio web, porque algunas actualizaciones siempre son posibles.

Es complejo y un tema largo dar una respuesta completa sin copiar y el artículo pasado, así que por favor, perdóname, te redirijo al sitio web :)


Las referencias son para el estado que debe sincronizarse entre hilos. Si necesita hacer un seguimiento de un montón de cosas diferentes y algunas veces necesitará hacer operaciones que escriban en varias de las cosas a la vez, use refs. Cada vez que tenga múltiples piezas diferentes de estado, usar refs no es una mala idea.

Los átomos son para estados independientes que deben sincronizarse entre hilos. Si nunca necesitará cambiar el estado del átomo y cualquier otra cosa al mismo tiempo, usar atom es seguro (en particular, si solo hay un estado en todo el programa, puede ponerlo en un átomo) . Como ejemplo no trivial, si intenta almacenar en caché los valores de retorno de una función (es decir, memorizarla), usar un átomo probablemente sea seguro: el estado es invisible para todo lo que está fuera de la función, por lo que no tiene que preocuparse acerca de un cambio de estado dentro de la función arruinando todo.

El punto principal de los agentes es que se ejecutan en un hilo diferente. Puede obtener el valor del agente y decirle que aplique una función a su valor, pero no sabe cuándo se ejecutará la función ni a qué valor se aplicará la función.

Los Vars son para cuando necesitas almacenar algo por subproceso. Si tiene un programa de subprocesos múltiples y cada subproceso necesita su propio estado privado, ponga ese estado en una var.

En cuanto a los ejemplos del mundo real, si proporciona un ejemplo de lo que está tratando de hacer, podemos decirle qué usar.


Recomiendo mucho "The Joy of Clojure" o "programación de Clojure" para obtener una respuesta real a esta pregunta, puedo reproducir un breve recorte de las motivaciones para cada uno:

comience viendo este video sobre la noción de identidad y / o estudiando aquí .

  • Las referencias son para el acceso coordinado sincrónico a "Muchas identidades".
  • Los átomos son para acceso síncrono descoordinado a una única identidad.
  • Los agentes son para acceso asincrónico no coordinado a una única identidad.
  • Los Vars son para identidades aisladas locales de subprocesos con un valor predeterminado compartido.

El acceso coordinado se usa cuando dos identidades necesitan cambiar juntas, el ejemplo clásico es mover dinero de una cuenta bancaria a otra, necesita moverse completamente o no moverse en absoluto.

El acceso no coordinado se usa cuando solo una identidad necesita actualizarse, este es un caso muy común.

El acceso sincrónico se usa cuando se espera que la llamada espere hasta que todas las identidades se hayan resuelto antes de continuar.

El acceso asincrónico es "disparar y olvidarse" y dejar que la identidad alcance su nuevo estado en su propio tiempo.