And user interface widget libraries, which are all about I/O. Even Racket's widget toolkit leverages the superb racket/class encapsulation mechanism.
And user interface widget libraries, which are all about I/O. Even Racket's widget toolkit leverages the superb racket/class encapsulation mechanism.
This makes UI code more declarative and allows you to create things like neat combinators. As an example, it's very easy to write a function like `when' with FRP, which could be used like this (code roughly from a game of life app I wrote):
when (not <$> paused) (step <$ time)
Here `time' is just a stream of events every x milliseconds. So what this code does is create a stream of step events which represent stepping the life simulation forward at each time step, as long as the game isn't paused. `paused' is a value based on a button, but it could easily have multiple inputs.So you get signals and event streams like `paused' and `time' from UI widgets (or the system), and then combine them into new streams that you can plug directly into UI widgets. This then lets the widgets themselves be much simpler structures with not internal state. In essence, this replaces arbitrary mutable state with an explicit dependence on time which leaves less room for making mistakes while also making it easier to write high-level functions like `when'.
There's a ton of other cool things you can do--this is just an example meant to illustrate the sort of abstractions you can use; it is by no means exhaustive!
I've found that FRP leads to much nicer UI code than callback-based OOP.
Superb? The racket class system strikes me as awful/embarrassing. The language at least looks functional in nature, but to do OO they implemented this ridiculous single dispatch mechanism (manually calling "send" no less!). Why on earth didn't Racket end up with a CLOS like system? They could have made anything they wanted, and yet they ended up with a system that will require people to write the Visitor pattern. Shocking.
CLOS-like systems can be built on structs with the racket/generic module and Typed Racket makes multimethods trivial.