Should events be volatile from the outside?

I play with FRP, and I was wondering how the act of "happening" in public should be handled. By this, I mean that a programmer can do the following in the context of FRP:

event.occur(now, 5) 

I have never seen examples of this in any FRP docs, and it doesn't seem right to me. I believe that the FRP framework should really hide this type of action and that event events should only happen behind the scenes. Am I correct in this?

To clarify, my approach would be to “happen” only to the Event class itself. If an abstraction is required for some external source (for example, a mouse), this could be constructed by extending the Event class. Thus, all the logic associated with the creation of emergence is abstracted.

+4
source share
1 answer

Well, if the FRP library provides a way to bind to external events - for example, an existing event-based infrastructure - then it should provide equivalent functionality or cannot interact with the outside world.

However, the question is valid: what do you mean by "external"? The FRP system itself is usually perceived as clean, so the idea of ​​having a side effect like event.occur(now, 5) inside the FRP system doesn't even make sense. In the general case, of course, it is possible to execute such code in response to FRP events, but usually this is done not as part of a pure programming model, but as a means for the network as a whole to interact with the outside world.

So, in my opinion, there are two possible ways to interpret this question:

  • Is it possible to trigger an event from outside the FRP system? - definitely yes, because it is necessary for interaction with the outside world, but this does not affect the programming model of FRP itself.
  • Is it possible to initiate an event from the "internal" FRP system, assuming that to perform a side effect in response to the event? " - also yes, because resolving the normal side is efficient code that raises events, but prohibits it inside the code executed in response to events, it seems a very strange (and workaround) limitation, given that the object's purpose is to interact with the outside world.

In fact, you can call something like # 2, even if you explicitly forbid it: consider setting it up so that switchToWindow 3 executed when the buttonClicked event is buttonClicked , for example. (using reactive-banana notation):

 reactimate (switchToWindow 3 <$ buttonClicked) 

And say we have an event

 newWindowFocused :: Event Int 

The reaction that we set up raises the newWindowFocused event, even if events are fired from the internal code executed because of the event.

Now all that I have said so far concerns only "external" events: those that are not expressed using pure FRP, but are clearly designed to represent events that occur in the outside world, outside the FRP system. If you ask if there should be an object to trigger special events in purely defined events, then my answer is: absolutely not! This destroys the meaning of the system because suddenly fmap f (union e1 e2) does not mean “happens to fx when either e1 or e2 happens to x ”, but instead happens to fx when either e1 or e2 happens to value of x ... or when some external code accidentally decides to run it. "

Not only could such a tool not talk about the behavior of the FRP system, which is essentially meaningless, 1 it would also break referential transparency: if you build two events equivalent to fmap f (union e1 e2) , then you can distinguish them by firing them and noticing that the other is not happening. You simply cannot prevent this in all cases: imagine fmap g (union e1 e2) , where f computes the same function as g ; equality in functions is not decidable :)

Of course, it is quite possible to implement FRP in an unclean language, but I believe that giving the opportunity to violate the link transparency of the FRP system itself is very bad, because it is, after all, a clean model.

If I understand correctly, your solution to this shortcoming in the API (namely, exposing occur publicly, which violates the referential transparency of equivalent events, etc., as I mentioned above) would make occur internal to your Event class so that it does not could be used externally. I agree that if you need to occur internally, this is the right decision. I also agree that it is wise to subclass it if your implementation of external events is done by subclassing Event . This falls under the “external glue of the world”, which goes beyond the framework of the FRP model itself, so it’s completely normal to enable it to “break the rules” in this way - after all, which is essential for this: breaking the system with side effects :)

So in conclusion:

No, events should not expose this interface.

Yes, you think it is right :)

1 Of course, you can argue that external events make this complete halt, since all the behavior of the system ultimately depends on the "edges" connected to the outside world, but this is not entirely true: yes, you cannot really assume anything about the external events themselves, but you can still rely on everything that you build from them to obey the laws of their construction. Offering an “external firing” facility for each event means that no design has laws.

+6
source

Source: https://habr.com/ru/post/1391560/


All Articles