Embracing Redux – or What’s Wrong with Object-Oriented Programming?

Posted on Posted in debugging

Before you ask, I don’t think anything’s wrong with object-oriented programming. But recently I’ve attended an interesting talk at the JAX conference. By the look of it, the speaker, Manuel Mauky, wasn’t happy with object-oriented programming. Instead, he propagated functional programming and Redux.

While I don’t agree with him, I considered his reasoning compelling. I’ll try to summarize it as best as I can.

By definition, object-oriented programming means to combine data with algorithms. To me, this always seemed to be natural. After all, data is meaningless until you know what to do with it. From this point of view, objects join two concepts that belong naturally together.

Manuel tackles things from a different angle. He doesn’t believe that data and behavior belong together. He’s pretty much convinced that the application state should be separate from the functions defining the behavior of the application. We’ll see that this approach has many advantages.

Time

In Manuel’s world, time plays a crucial role. In fact, almost everything programmers deal with boils down to the question what happens to their program in the course of time. How are the data changed by the actions of the programmer or by external events? Putting it into the terms of Redux: how does the application state change over time?

Redux is a framework focusing on the application state and on how the application state changes. So the two central concepts of Redux are

  • the central store containing the application state
  • and several transformations describing how the application state changes when certain events are triggered.

That, in turn, explains why functional programming is so popular among Redux programmers. The rules describing the transformation of the application state are functions. Plus, Redux considers the application state a different domain than the state transformations, which describe the application’s behavior. That’s the natural field of a functional programming language. It’s a lot harder to implement a program separating state from behavior with an object-oriented language. Of course, it’s possible, but it feels counter-intuitive.

Time-traveling debugger

My last adventure into Redux wasn’t a pleasant experience. But there was one feature that almost bought me: the time traveling debugger. As mentioned before, the central idea of Redux is to define an application state. Other than I suggested before, the state doesn’t change over time. It’s immutable. The functions transforming the state create new immutable variations of the old state.

At every point of time, there’s exactly one application state. If we were to store these states, we could traverse the history of our program backward. That’s a tremendously useful feature. How often do you see an error without being able to reproduce it? If you’re running your program with a time-traveling debugger, that’s never going to happen. You can go back in time, reconstructing the steps that led to the error along the way. A couple of years ago I evaluated Chronon. We didn’t use it because we were low on budget, but the first results were encouraging.

Redux takes the idea of a time-travelling debugger one step further. You’re not really interested in arbitrary changes. You’re interested in changes triggered by events, such as the user clicking a button. Storing these events and the corresponding application states is easy. So it’s not astonishing that time traveling debuggers are not only available in the Redux universe, they are even available for free.

Long transactions

Long transactions are another domain showing the power of Redux. Sometimes it’s useful to start a series of changes without having to store each change immediately to the database. If you allow the user to do so, that’s a long transaction. The classic examples are programs like Word or Excel. You can do an arbitrary number of changes, but it won’t be committed to the file system until you hit the “save” button.

Redux makes it easy to implement such a long transaction. Basically, all you have to do is to store the events and to replay them when the transaction is committed. Or to replay the state transformations and to save them to the database. If you want to rollback the long transaction, you simply go back to the original application state.

Serializable application state

I don’t exactly remember why this is an advantage, but Manuel emphasized several times that the application state is serializable. I guess that comes in handy every once in a while.

Knowing where to locate an error (or an application behavior in general)

At this point things get interesting. According to Manuel Mauky, one of the biggest advantages of Redux is that you always know where to locate an error. My own experience was a bit different. I always know where to find the cause of an error in an object-oriented program, but I had my fair share of difficulties finding the same error in a Redux application.

I guess it’s just a matter of practice and convention. I prefer the object-oriented paradigm, so it’s little wonder I get along with it more easily. If someone’s grown up with another tradition, my approach probably seems weird to them. Both paradigms work. It’s mostly a matter of taste which one you choose.

When to use or not to use Redux

I’ll try to give a recommendation nonetheless. Redux has a couple of disadvantages. Among other things, it requires you to write a lot of classes. The object-oriented approach tends to be less verbose.

So Redux pays if you’ve got complex applications with a lot of user interactions. In particular, it pays if you’ve got several windows, each being able to trigger events influence each other window. Facebook is a classical example of such an application. The more UI events you’ve got to deal with, the more I recommend Redux.

However, the typical bread-and-butter application is a lot more straightforward. So the object-oriented model is more appropriate. You can write your program in a much more compact and concise way.

Wrapping it up

It depends on what you want to optimize. The time-travelling debugger is a persuasive argument to adopt Redux. On the other hand, object-oriented programming amounts to writing less code. At the end of the day, it’s a matter of personal taste. Which is more important to you: putting data and behavior together because they don’t make any sense otherwise, or do you concentrate on time and changes over time? Neither approach is wrong, so ask your team which model they feel more comfortable with. You can implement most applications using both paradigms. Currently, Redux is popular because Facebook and others propagate it, but I’d rather you’d ignore such short-term considerations and think in the long term.

Leave a Reply

Your email address will not be published.