Estoy jugando con FRP y me preguntaba cómo se debe manejar públicamente el hecho de que un evento 'ocurra'. Con esto, me refiero a que un programador debería poder hacer lo siguiente dentro de un contexto de FRP:

event.occur(now, 5)

Nunca he visto ejemplos de esto en ningún documento de FRP y no me parece bien. Siento que los marcos de FRP realmente deberían ocultar este tipo de acción y que las ocurrencias de Eventos solo deben ocurrir detrás de escena. ¿Estoy en lo cierto al pensar esto?

Para aclarar, mi enfoque sería tener 'ocurrir' solo accesible para la clase Event en sí. Si se necesita una abstracción para alguna fuente externa (como un mouse), esto podría construirse extendiendo la clase Event. De esta manera, se abstrae toda la lógica que se ocupa de la creación de ocurrencias.

4
seadowg 18 ene. 2012 a las 03:52
Actualicé mi respuesta en respuesta a su aclaración :)
 – 
ehird
18 ene. 2012 a las 06:18
¡Gracias! Me di cuenta de que no había sido lo suficientemente claro :(
 – 
seadowg
18 ene. 2012 a las 06:24

1 respuesta

La mejor respuesta

Bueno, si la biblioteca de FRP expone una forma de vincularse a eventos externos, p. Ej. un marco existente basado en eventos, entonces debe proporcionar una funcionalidad equivalente a esta, o no podría interactuar con el mundo exterior.

Sin embargo, la pregunta es realmente: ¿a qué te refieres con "externo"? El sistema FRP en sí mismo generalmente se considera puro, por lo que la idea de ejecutar código con efectos secundarios como event.occur(now, 5) desde el interior del sistema FRP ni siquiera tiene sentido. Por lo general, por supuesto, se proporciona una facilidad para ejecutar dicho código en respuesta a eventos de FRP , pero esto generalmente no se toma como parte del modelo de programación puro, sino como una facilidad para interconectar la red como un todo con el mundo exterior.

Entonces, en mi opinión, hay dos formas posibles de interpretar esta pregunta:

  1. ¿Debería ser posible desencadenar un evento desde fuera del sistema FRP? - definitivamente sí, ya que es necesario para interactuar con el mundo exterior, pero esto no afecta el modelo de programación de FRP en sí.
  2. ¿Debería ser posible desencadenar un evento desde "dentro" del sistema FRP, asumiendo alguna facilidad para ejecutar código con efectos secundarios en reacción a un evento? - también sí, porque permite el código normal con efectos secundarios causar eventos, pero prohibirlo dentro del código ejecutado en respuesta a eventos parece una restricción muy extraña (y evitable), dado que la intención de la instalación es interactuar con el mundo exterior.

De hecho, es posible causar algo como el n. ° 2 incluso si lo prohíbe explícitamente: considere configurar las cosas para que switchToWindow 3 se ejecute cuando se active el evento buttonClicked, p. Ej. (utilizando la notación reactivo-banana):

reactimate (switchToWindow 3 <$ buttonClicked)

Y di que tenemos un evento

newWindowFocused :: Event Int

La reacción que hemos configurado hace que se active el evento newWindowFocused, incluso si se evita la activación de eventos desde el código interno ejecutado debido a un evento.

Ahora, todo lo que he dicho hasta ahora se refiere solo a eventos "externos": aquellos que no se expresan con FRP puro, sino que se crean explícitamente para representar eventos que ocurren en el mundo exterior, más allá del sistema FRP. Si está preguntando si debería haber una facilidad para causar ocurrencias especiales en eventos puramente definidos , entonces mi respuesta es: ¡absolutamente no! Esto destruye el significado del sistema, porque de repente fmap f (union e1 e2) no significa "ocurre con el valor f x cuando e1 o e2 ocurre con el valor x" , pero en cambio "ocurre con el valor f x cuando e1 o e2 ocurre con el valor x ... o cuando algún código externo decide dispararlo al azar".

Esta facilidad no solo haría que el razonamiento sobre el comportamiento de un sistema FRP no tuviera sentido, 1 también violaría la transparencia referencial: si construyes dos eventos equivalentes a fmap f (union e1 e2), entonces puedes distinguirlos disparando uno y notando que el otro no ocurre. Simplemente no puede evitar esto en todos los casos: imagine fmap g (union e1 e2), donde f calcula la misma función que g; la igualdad en las funciones no es decidible :)

Por supuesto, es completamente posible implementar FRP en un lenguaje impuro, pero creo que proporcionar una forma de violar la transparencia referencial del sistema FRP en sí es algo muy malo, ya que, después de todo, es un modelo puro.

Si lo entiendo correctamente, su solución a esta falla en la API (es decir, exponer occur públicamente, lo que rompe la transparencia referencial de eventos equivalentes, etc., como mencioné anteriormente) sería hacer occur interno a su clase Event, por lo que no se puede usar desde afuera. Estoy de acuerdo en que, si necesita occur internamente, esta es la solución correcta. También estoy de acuerdo en que es razonable exponerlo a subclases si su implementación de eventos externos se realiza subclasificando Event. Eso se incluye en el "pegamento del mundo exterior", que queda fuera del alcance del modelo de FRP en sí, por lo que está perfectamente bien darle la capacidad de "romper las reglas" de esta manera; después de todo, para eso es esencialmente : perturbar el sistema con efectos secundarios :)

Entonces, en conclusión:

No, los eventos no deben exponer esta interfaz.

Sí, tiene razón al pensar esto :)

1 Por supuesto, podría argumentar que los eventos externos hacen esto punto final , ya que todo el comportamiento del sistema depende en última instancia de los "bordes" conectados al mundo exterior, pero esto no es realmente cierto: sí, realmente no puedes asumir nada acerca de los eventos externos mismos , pero aún puedes confiar en todo lo que construyes a partir de ellos para obedecer las leyes de sus construcciones. Ofrecer una instalación de "disparo externo" para cada evento significa que ninguna construcción tiene leyes.

6
ehird 18 ene. 2012 a las 17:23