Real Life™ + UI programming = FRP (or why Elm is awesome)

 Input

A piece of software that requires and reacts to user interaction is akin to a car. I’m no car guy - but when I press on the accelerator, my car’s velocity increases. When I hit the brakes, the brakepad hit my tires and the car begins to slow down.

I imagine slamming the brakes in a car is direct, short trip for the electrical system. When brakes are in ‘slammed’ state, the brakepad are hitting the tires. This makes sense & there’s no mental hurdle to jump to understand it.

In simple terms of input: I as the user am inputting ‘brake’. I get a car that is slowing down. In other words - whenever the brakes are down, the car is slowing down. Whenever the steering wheel is turned to the left, the wheels are turned to the left. It’s tempting to say that my input determines the state of the car, but I don’t think that’s ambitious enough.

The input is the state of the car. They aren’t just related, they are equal.

What an elegant way of thinking about input - whether input be time elapsed, clicking a button, the dimensions of a window. The state of [whatever] can be described simply by its input.

 Input Sucks

Programmers hate real life user input.

Think back to your first ‘Hello world!’ that took user input from the cmdline… remember your scanf or gets? Remember thinking, “what if they don’t input a number?”…“what if they have to redo it?”…“what if they want to undo it?”… such a headache.

So many things can go wrong - especially when there are multiple methods of giving input to a program (at the same time!?!?).

The browser basically handles this in the following way:

CheckLoop:

Is there an event? -> alert any listeners

CheckLoop

These listeners are usually implemented in Javascript (see the Observer pattern). You define a function that waits for a click event - when one occurs, the function wakes up and handles it with the definition you wrote.

This would be fine, but web applications, ultimately, deal with the DOM. They deal with the nice buttons and windows you see. The DOM is the state of your application. These windows and buttons need to change based on the things you click and the window you resize, for example.

Let’s examine these two examples.

The browser loops: a click occurred.

The myClickListener() wakes up - it understands you clicked on a button and updates the DOM accordingly - a window disappears as a result.

The browser loops again: a window resizing occurred.

The myWindowListener() understands the new dimensions of the window and changes elements’ sizes accordingly.

 I would not buy a Javascript car

This is important - the Javascript we just examined explicitly handles input from the user. It takes an event and changes the DOM as the developer sees fit.

Bringing back the car analogy - if Javascript (I know it’s the browser’s fault, not JS) was a car, it would work like so: I press down on the brake. A mechanism called JS in the car recognizes that I pressed down on the brake. It then applies the brakepad to the tires in response. Thanks!

But why all the extra complexity? Why any extra complexity? Oh, but did I mention that Javascript can only handle one event at once? So if you have a click event being handled at t = 0 taking 10 seconds, and a window-resizing event comes in at t = 5, the window-resizing event can’t run until click event is fully handled.

The Javascript car would then wait until I take my foot off the brake to register that I had turned left, and then JS would turn the tires to the left - a pretty shitty car.

 Describe the state

Javascript and the current browser model do not describe the state of the DOM (application). If you breakpoint Javascript during runtime of your application, you will have to examine the DOM to see the current state.

If you want to step backward to see some state in a time previous to now, you have to undo code execution on the DOM.

Not only does this single-minded event execution strategy make it difficult to handle multiple events, it makes examining and reasoning about the code/state pure torture.

What if we could create a system like the original car I talked about? A system in which the unique and important input systems are directly connected to the pieces of the state (car) that they manipulate.

A system where the code doesn’t handle input, it describes the state. In this perfect world, resizing a window doesn’t trigger an event that can change elements’ dimensions… the window’s dimensions are dynamically implanted in the code that describes the state of the application. When the window dimensions change, the state of the application is changed along with it.

Another, maybe simpler example: number of mouse clicks. Our old, Javascripty model would implement a click listener. Whenever woken up, it would increment some text field on the DOM by one. Sucks!

Our shiny new model will simply describe that text field as corresponding to the number of mouse clicks sent into the system, and the two will always be in sync.

 Perfect?

In this perfect world, our input truly and directly describes the state of our application. There is no middle ground - the streams of input have a direct line to the car. A turned steering wheel means turned wheels.

I don’t know what a perfect world is - but something like this does exist.
It’s called Elm.

What kinds of benefits does this give you?

 Notes & Disclaimers

The next post will probably about streams ‘n stuff.

 
5
Kudos
 
5
Kudos

Now read this

Distributed Hash Tables: Introduction

This post assumes you have ~ 1 or more years of programming or Computer Science experience. I’d say if you’re comfortable with hash functions & some basic network ideas, there’s something here for you. This series of posts is... Continue →