wafflejs 4 nov 2015

slides words

Hi! I’m Melinda, and this is the first tech talk I’ve ever given, so I’m really excited.

I’m here to talk about how functional programming can make building JavaScript applications less frustrating and more fun.

Quick disclaimer: unlike the other speakers tonight, I’m not a web professional — I’m actually a bioengineering PhD student, and for my day job I write mostly systems and native code.

But web programming was my first love, and I’ve been a nights-and-weekends JavaScript enthusiast since the 1990s. Back then, the key was to get the rollover menu animations for your Pokemon fan website just right.

But things are more complicated today.

So here’s a typical web user interface.

This is a messaging application, and we’re just looking at the friends list.

Let’s take a second to see:
Can you keep track of this?

These are some things that have happened since we last saw the friends list.

What does the interface look like now?

As front-end developers, our problem is that UI programming is hard, because it’s really complicated to both:

(1) keep track of how variables change over time, and

(2) keep everything updated in the user interface without anything breaking.

And in an actual webapp, many more parts depend on each other.

The ad you see here is influenced by the posts you’ve liked,

and the posts you see here depend on what your friends like.

And all this state is being mutated in real time.

It can get overwhelming.

(tiny scream)

This is where functional programming can help.

What if, for that cool-politician friends list, we didn’t have to list and keep track of each change that happened? And, instead, we could just look at the current, valid values, and render our view as a pure function of the data?

Then we wouldn’t have to worry about how our user got there. Instead, we could just calculate the right thing based on where they are now.

Like this.

On the left there’s the data; on the right there’s the rendered UI.

And that’s exactly what React does.

For those of you who haven’t dug into it yet, React is a wildly popular library for building declarative user interfaces.

It was built at Facebook, but it’s on GitHub and is fully open source.

!!!

The big idea of React is that it lets you make the user interface purely a function of the data.

As developers we just describe how our UI should look for a given state, and React uses sophisticated virtual-DOM diffing algorithms to make this happen while making the minimal set of changes necessary in the DOM. We get a simple, functional approach that’s also fast and cheap.

We don’t have to poke at the UI, observe properties, imperatively add listeners, hopefully remember to remove them when our widget goes offscreen, and so on. These are all fragile and error-prone processes that we’d prefer to avoid.

We just describe what we want, and React figures out how to give it to us. We end up writing a lot less code, less logic, and fewer bugs.

Another thing React’s functionality lets us do is improve our development experience in neat ways. One of these is hot reloading, where we can hotpatch UI code while preserving state.

(brief aside on how beautiful F1 pit stop crews are)

It’s hard to explain why this is cool with words, so let me show you how this works with a tiny app I wrote.

This is the highly original game Twos.

(Don’t judge me, my girlfriend and I have been playing a lot of Threes this week.)

Let's just spin it up — I’m using node and express to serve it to myself on port 9001. Let’s load that over in Chrome here.

But wait, it isn’t here.

Let’s take a look at the code.

Oh — I left out the angle brackets. Let’s type them back in.

Okay, it’s here, cool.

Here I’m using React Transform, which was written by Dan Abramov and plugs into webpack. Every time I touch my source directory, react-transform is hotpatching my code. I’m not refreshing the webpage at all.

So let’s play the game.

But wait, you can’t see what I’m doing. Let’s add a label showing what button I’m pressing.

I type this into my Header component and hit save, and see how it just plugs in?

Let’s play more.

Got to 64, great — but, ugh! What’s that color? I hate it.

Phew, okay, that’s much better.

As I edit my code, I can see how things break, and then get fixed. The UI state gets preserved the whole time.

I don’t need to repeat my actions to get back to where I was. This makes it much faster to iterate, and to catch and fix silly bugs.

All this is possible because render() in React is declarative. It’s a function.

So React’s about state in the view and the controller, but we can go further. What about the model?

Redux is an idea and a library, also created by Dan Abramov.

Like React, it’s open source.

And it’s sort of like the model corollary to React. It’s a replacement for MVC, but much simpler.

If you’ve looked at Facebook’s Flux architecture, it’s partially an implementation of that — just super-slimmed down.

This is the key idea of Redux.

Whereas React makes the user interface a function of data, Redux lets us write every state change as a pure function of a state and an action.

This makes it so state and behavior stay separate. They don’t get entangled — which gives us a simple, predictable model.

This similarly allows for some really powerful debugging tools.

Like time travel! (That’s what it’s called.)

Again it’s easier to show than to tell, but I’ll try to make this shorter.

So this is a clone of the Windows solitaire game.

And you probably know how the game works.

But what is this thing over here?

Well, this is actually showing us the full state of our app at every point in time.

So this was the initial state of our app.

Then I performed an action — what that did is take that old state and apply a function to it (taking an action payload) to get to the next state.

And then I applied another function to the new state to get the next state. And again, and again.

But these are just pure functions.

So I can cancel one of these in-between actions, and it doesn’t screw up the later ones.

Okay, now the time travel part.

Because state is separate from behavior, I can change the program’s behavior in the future and see what it would have done in the past.

So let’s just say I play a little more, and it seems kind of pointless. “Why am I even playing this game?,” I ask. “I wish it at least gave me some points. Like Twos. That’d be better, mmhm.”

Well, I can change our state-altering function to add a score to the data. (I’m cheating a little, the score functionality is written already, but let’s plug it in.)

Now you can see the score at all the states, even in the past.

And I can even say “hey, these scores look a little weak” and go over to the score functions and pump them up a little.

And it updates the scores even in the past. See?

This all looks a little weird here, but trust me, you have to try it.

So what does this mean?

At the end of the day, functional programming is not about cool math, or concurrency, or monads, or category theory. It’s about our ability to understand our programs.

And programming with functions — with tools like React, Redux, Immutable.js (which I didn’t get to talk about), and others with similar ideas — makes it simpler for us to understand the software we produce.

Which is enough.

Anyway, I’m Melinda, talk with me sometime. Thanks for having me!