Ridding ourselves of IO before there is a good replacement

I have been researching FRP for about a year now without finding or discovering an implementation I like. I don’t know if there is one — maybe my standards are just too high. However, it has initiated me into the more general interest of purely functional foundations.

Since I am tired of thinking and want to start hacking again, I am abandoning FRP proper for the time being. But I am continuing in spirit, by continuing with foundations. I will be developing this project in the Frag repository, where I keep my FRP stuff.

The idea of the Frag project is simple: get back to making the software I want to make — mostly games — but shun IO. I.e. the content of these will only be built on semantically meaningful abstractions (which are in turn implemented on IO, of course), but without concern for making it a “perfect” FRP implementation. Said abstractions will go in the Frag project. The main point is to get away from the world of fuzzy, complex operational semantics, replacing it lazily with simple denotational ones.

But this is a foundational project, meaning that once the foundations are replaced, I allow myself to do arbitrary software engineering on top of it. I think this is an important point.

Currently in the repository is a simple Event abstraction. I’m seeing how much I can write with just that, without worrying about modeling conceptually continuous things (like mouse position). Secretly my plan is to accidentally come across a good interaction model which boils down to Event, and is thus inherently meaningful (simplicity can be refined out later).

I’m having trouble foreseeing how I will model eg. network interaction using Events. Graphical games are pretty easy, since conceptually they always exist, and you’re just choosing to view them. I can’t see how network fits into a model like this, since a network program can have side-effects on another computer. Can anyone think of a way that network interactions are about being instead of doing?


8 thoughts on “Ridding ourselves of IO before there is a good replacement

  1. I can’t see how network fits into a model like this, since a network program can have side-effects on another computer.

    The difficulty here may arise from the way you’re framing the question.

    From my perspective, graphics & UI programs are network programs, implementing data marshalling and network transport via rendering, parsing, motor control, screen/speakers, keyboard/mouse, etc. Data originating in one network node (computer or human) leads to behavior/events/side-effects (pick your favorite mental paradigm) in others. I doubt that the comparatively simple and well-understood domain of computer/computer network programs would raise conceptual difficulties not already raised in the setting of computer/human network programs.

    “The beautiful answer is always proceeded by the more beautiful question.” – e.e. cummings

  2. conal: of course! A computer is an interface to a function. I guess I was just handwaving around that so much that I confused myself.

    Jason: well, I was thinking about the type of main, and that it would have to be like Event Response -> Event Request or something like that, which I didn’t like at all. But that was the wrong thing to be thinking about. Programs are functions, so programs don’t interface with the network at all — they’re just functions. If you also have a function representing a remote machine, you can have two programs talk to each other by defining them in terms of each other. More concretely:

    remoteProgram :: Event A -> Event B
    localProgram :: Event B -> Event A
    let as = myProgram bs; bs = otherProgram as


  3. Yes, that’s the idea: interaction is mutual recursion between two or more pure functions, with the run-time system handling the mechanics of marshalling, data transport, and unmarshalling. As always, the RTS handles the nitty gritty imperative stuff so that we can work with simple (hence IO-free) semantics.

  4. Is a timeout handled by the RTS, or does `Event a` have a `Timeout` constructor? How much control flow do we surrender to the RTS? How much network errata do we kick up to the main program?

  5. Event is a set of time-value pairs. I don’t know what Timeout could possibly mean.

    We would probably model the remote program by the Event of packets that we *recieve*, rather than the ones it sent (the times will be different), so Timeout would just be a merge with an Event which occurs in like 20 seconds or whatever.

  6. Yes!

    For any of this interactive stuff (computer/user or computer/computer) stuff to work, I think we’ll want to add another element to your remote/local model above. A principle I’d introduce is that we react only to what is inside of us, never what is outside. For instance, I react to what I hear, not what you say, and to what I see, not what you do. (Going further, I react to what I make out of what I see and hear.) This principle has many implications, particularly in personal relationships. It also applies to FRP, in that it implies a filter/distortion (function) between what comes out of remote and into local and vice versa. One aspect of that filter is time delay.

  7. Luke: In considering an Event type that is compatible with the notion of network failure, I mentioned a Timeout constructor because for any kind of failable event, we must be able to construct a timeout. There is, I gather, more than one way to do it :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s