2010-08-30 21 views
7

He estado tratando de encontrar algo que discuta cuándo deberías favorecer el uso de mónadas sobre actores (en escenarios de simultaneidad), pero no he encontrado nada. En particular, me pregunto sobre el uso de las Extensiones reactivas (LINQ a eventos) frente a MailboxProcessor de F #. Por favor, den ejemplos además de cualquier razonamiento filosófico que pueda tener.Mónadas y actores

actualización Para un mejor contexto, las extensiones reactivas implementar la mónada continuación en forma de IObservable/IObserver. No necesariamente estoy diciendo que tengo que usar F #, solo que F # tiene un "modelo de actor" concreto disponible en un lenguaje .NET en forma de MailboxProcessor < 'T>.

Lo que trato de entender es cuándo usar una mónada (en este caso, una mónada de continuación) frente a un modelo de actor para propósitos de concurrencia. Cuando la mónada (según tengo entendido) no introduce estado, el actor tiene su propio estado interno que se modifica según sea necesario para proporcionar acceso protegido.

He visto varios ejemplos del uso de ambos: Rx y node.js (CPS, no es realmente la mónada de continuación) frente a MailboxProcessor de F # y el framework Akka de Scala. Simplemente no sé por qué elegirías uno sobre el otro.

+1

Esto probablemente será completamente inútil para usted, ya que no sé f # y realmente no entiendo su pregunta donde está viniendo, pero me escribió una implementación modelo de actor en Haskell, que hace uso de la mónada stack (un cómputo actor es una mónada Reader/IO): http://hackage.haskell.org/packages/archive/simple-actors/0.1.0/doc/html/Control-Concurrent-Actors.html – jberryman

+0

[Phil Trelford ] (http://twitter.com/ptrelford) también ha creado una implementación de [Rx using actors] (http://minirx.codeplex.com/), por lo que parece que, dependiendo de lo que esté haciendo, usted podría implementar actores usando mónadas o mónadas usando actores. –

+1

Otra pieza de "podría no serle útil". Una vez me han señalado que el objetivo principal de Rx no es introducir la concurrencia sino abordarla. Mientras que uno puede considerar al agente F # como una forma apropiada de introducir concurrencia. –

Respuesta

0

Voy a responder a mi propia pregunta y decir que debe usar ambas. Esto se basa en Don Syme's post. Un MbP usa el cálculo Async para hacer su trabajo, y el Async es una mónada de continuación consciente de hilos. Parece que puedes usarlo solo para algunos usos, pero el MbP definitivamente lo requiere.

Realmente no me gusta esta respuesta, y me gustaría que alguien respondiera con una mejor explicación de cuándo usar cada una.

Actualizado:

Ver MiniRx, que es ahora, aparte de FSharpx, para una implementación de una mónada de estilo Rx implementado utilizando MailboxProcessor. Como MailboxProcessor se implementa por sí mismo utilizando la mónada async, estas piezas realmente funcionan juntas. Son solo diferentes medios de abstracción.

1

Disculpe mi novato ya que estoy aprendiendo F #.

Me intriga ver el uso de RX en lugar de un MailboxProcessor, si tiene enlaces a materiales relevantes.

Con mi entendimiento limitado; Escogería Mbps en mi propio código ya que los eventos son un poco complicados de configurar en F # (por lo que puedo sacar de este artículo: MSDN). Y necesitas eventos para que RX se enganche en ¿verdad?

Donde como con un MbP todo lo que necesito es una unión de mensajes discriminada, una lista de funciones que deseo que se ejecuten cuando se recibe un mensaje dado. Y el procesador de buzón que maneja esto.

Todo esto se ve bastante limpio en el código. Puedo montón mi MBP de juntas en un módulo entonces mi módulo de "objeto" se parece a

  • Registro
  • mensaje DU
  • Envoltura con unos captadores y definidores que publican los datos a la MBP

Para mí, esto parece mucho más ordenado de lo que sería si escribiera mi código con eventos como se describe en ese artículo de MSDN al que me he vinculado.

Aunque soy solo un F # junior, así que podría estar a millas de distancia con mis cálculos y es un look-& -me gusta más que una elección de idoneidad para el propósito (ya que no estoy calificado para hacer eso llamar, todavía)

+0

Dependiendo de cómo exponga sus eventos, puede hacer tan poco como declarar un evento y devolverlo como un IObservable, con el método Trigger() llamado dentro del método Subscribe, así que no creo que los eventos sean tan malos. Los MbP tienen sus propios requisitos. –

+0

@jdoig Lo que describió es más o menos el patrón estándar para el uso de MbP. Aquí hay varios ejemplos: http://fssnip.net/tags/Agent – 7sharp9

+0

Tenga en cuenta que incluso puede generar observables a partir de varios métodos estáticos incorporados. No creo que alguna vez necesites configurar ningún evento y el código sería más Rx idiomático/funcional. –

4

No estoy seguro de que la pregunta tenga sentido como fraseada: hay muchas mónadas diferentes (por ejemplo, la mónada de identidad, la mónada de lista, la mónada de opción, ...), la mayoría de las cuales no tienen nada para hacer con concurrencia. Además, sería útil saber más sobre el escenario particular al que se enfrenta: "concurrencia" es un tema poco claro. Dependiendo de lo que intente lograr, los flujos de trabajo de F # async (que se basan en la mónada Async) pueden ser su mejor opción.

Si está utilizando F #, recomendaría no usar LINQ-to-anything directamente, ya que esas bibliotecas tienen una sensación muy extraña cuando se accede a través de F #. Sin embargo, podría crear agradables contenedores F # (como los módulos existentes Seq y Observable). Además, para los tipos monádicos, puede crear un constructor de expresiones de cálculo (por ejemplo, puede crear un constructor utilizando las Extensiones reactivas que le permita usar expresiones de cálculo para compilar IObservable s).

+0

Estoy familiarizado con las opciones. Tengo curiosidad sobre por qué y cuándo debes elegir una sobre la otra. Esto puede ser una preferencia, pero pensé que trataría de obtener una mejor comprensión. Para algunas envolturas F # a Rx, revisa mi repositorio bitbucket: http://bitbucket.org/riles01/fsharp.reactive –

+1

Parece que estás comparando una que tiene una tienda de respaldo que se puede llenar independientemente del cálculo (MbP), contra uno que no (Seq/Observable). Estas son situaciones muy diferentes y serían específicas de la aplicación. – 7sharp9

-1

¿Aceptarías respuestas del mundo de Scala?

Si buscan "una alternativa puramente funcional al modelo de actor", por favor ver este gran post del blog de Pablo Chiusano

pchiusano.blogspot.ro/2010/01/actors-are-not-good-concurrency-model.html (archivados aquí: http://archive.is/NxNLc)

y algunas referencias a continuación:

http://noelwelsh.com/programming/2013/03/04/why-i-dont-like-akka-actors/

Los actores no Componer Ak Los actores de ka no se escriben útilmente El sistema de tipo es la razón por la que usamos Scala.

https://opencredo.com/akka-typed/

Por desgracia, la API actual adolece de algunos inconvenientes, que son en buena medida asociada con la falta de seguridad de tipos

http://doc.akka.io/docs/akka/snapshot/scala/typed.html

Estado de este proyecto y relación con Akka Actors Akka Typed is th El resultado de muchos años de investigación e intentos previos (incluidos los Canales tipificados en la serie 2.2.x) y está en camino hacia la estabilización, pero madurar un cambio tan profundo en el concepto central de Akka llevará mucho tiempo

Un efecto secundario de esto es que los comportamientos ahora se pueden probar de forma aislada sin tener que empaquetarse en un Actor, las pruebas se pueden ejecutar de forma totalmente sincrónica sin tener que preocuparse por los tiempos de espera y fallas espurias.Otro efecto secundario es que los comportamientos muy bien pueden estar compuestos y decoradas

Composable application architecture with reasonably priced monads

El concepto de "estilo que pasa la función" de Heather Miller podría ser clave para un modelo de programación funcional distribuida.

SF Scala: Heather Miller, Function-Passing Style, A New Model for Distributed Programming