Yes, I really do need 700 LEGO bricks in order to flip that light switch…
Program note: This essay is timed to the release of the draft-complete beta of Modern Front-End Programming with Rails. They won’t all be about the book, promise. (There will be one or two more about the book). There will be more Entropy Essays in the future about testing, object-oriented design, pairing, and so on…
Something interesting happened as I was finishing up the book.
I wrote a piece of code and enjoyed it.
I mean, I enjoy writing code all the time, but the reason why I enjoyed this bit of code… it’s worth looking at.
Let me back up. The sample code in the book is a small Rails app with particular focus on two pages: a filterable list of events that is implemented in Stimulus, and a React implementation of very stripped-down venue diagram for purchasing tickets to those events.
At the very last minute, I decided to add an appendix to show what the Stimulus page would look like in React and vice-versa. I wanted to compare the code and the design decisions involved in using the other framework. (And I also had an ulterior motive, which is that I’m hoping to write up basically the same sample problem in other frameworks and wanted to see how that might go).
My basic opinion about the two frameworks is that Stimulus is really good for simple things and also pretty good for more complex interactions, but that it has its own structure and trying to reimplement React in Stimulus will eventually get painful (not that I didn’t try…). I think React is most interesting when you think of it as enhanced HTML, but that it has a lot of incidental complexity and that complexity becomes hard to manage at larger scale.
Anyway, I did the Stimulus one first, implementing the purchase page as one Stimulus controller covering most of the document. Stimulus style would normally have multiple small controllers rather than one big one, but I thought that the interdependencies of the page would make multiple controllers a challenge.
Moving on to the React version. React has a somewhat more boilerplate than Stimulus. The original ERB needs to be translated to JSX, there’s a small Redux reducer to manage shared data, the React app has to be loaded. It’s not a lot of stuff (the whole thing is just over 500 lines of code), but it’s more stuff than the Stimulus code had, and it felt like a bit of a slog as I was doing it.
But. When I did get the data model connected, there was a moment where everything Just Worked. And I’m not going to lie, that felt fantastic. Even on this small project, on this problem that not only had I totally made up, I had also already solved.
I started thinking about what, exactly, felt great about that moment.
I think part of it was just the way the work was structured. In Stimulus, you need to explicitly define the mechanism for changing the screen when state changes, but in React you define the relationship between state and screen and React automatically changes the screen for you when the state changes. So even though the setup work is more complicated, doing React after doing Stimulus feels like the reactive magic in React makes the code work, like, one step before it should, if that makes sense.
There is also very long standing relationship between complexity and programming. Making complex things work is very satisfying. I love watching Rube Goldberg machine videos, they are great ways to flip a light switch or whatever. For as long as I’ve been programming, there’s always been a strain of thought that suggests that the more complex the solution, the smarter the developer, and which really valorizes complicated solutions. And, you know, some problems are really complicated and really need complicated solutions.
The thing about that Rube Goldberg feeling of satisfaction, though, is that it’s kind of a trick. Making that first part of the code work, making it click together, it feels like the satisfying sound of a car door closing. It makes you think like the hard part is over and that it’s smooth sailing from here on out.
Of course, it’s not smooth sailing. The complexity is still there, and is just waiting to make your life difficult again when you need to change it. Imagine changing the requirements on a Rube Goldberg machine to flip a different light switch… On the plus side, when you solve that problem, it’ll feel really satisfying too.
It’s just really hard to correlate subjective feeling of accomplishment with actual code quality. A really good design makes it feel like you have no hard problems to solve, and doesn’t always give you that same satisfying feeling.
After I did the React and the Stimulus page, and after I turned them in for distribution, I realized something about the Stimulus logic.
Even the Stimulus version of the React page might be too complicated.
I think (haven’t tried it yet) that with TurboLinks, a lot of the page could be done as a plain server-side page. I didn’t implement that in the book (at least not yet), because on the one hand many readers will already know how to do that, and on the other hand the book example is supposed to be a simplified proxy for a more-complex real world problem, and it feels like kind of an unfair short-cut for the book’s educational purposes to treat it that way.
But I’m still annoyed I didn’t think to do it that way first. And I wonder if it was because, even knowing all this about complexity, I still wanted to build a Rube Goldberg machine, even just a little one, just for how it feels to solve it.