I wrote a short, inflammatory post a few days ago about Reactive Cocoa not adding much to the tools that we have. This caused a similarly snarky response from a fellow NYC iOS developer, and then a longer, more well-thought-out response as well. I think he deserves an equally clear answer from me. I’d also like to link to this gist, which has a better-written Reactive version of the sample that I quoted.
I want to note to the creators of Reactive Cocoa that I know exactly what it’s like to write something awesome and have random assholes from the internet shit on it. For that, I’m sorry.
For a tool that is loudly heralded as the future, most of the blog posts and code samples focus on how to use the technique, not how it’s better. This is why I published my blog post. My esteemed colleague blogged,
Please, go and try to actually make something with it.”
“Believe me when I say: this was a huge win.”
These aren’t convincing explanations of why one technique is better than another. When we saw AFNetworking, we quickly saw how much better it was then anything we’d used for networking up to that point. When we saw the GCC scoping technique, it was immediately obvious how we would use it to write clearer, better-scoped code. After reading Practical Object-Oriented Design in Ruby, I understood how my previous coding practices were bad and what I needed to do to improve them.
Further, the astute reader of this blog will note that my original post didn’t say delegate callbacks were “easier”, it said “better”. “Better” involves more type-checking. “Better” involves looser coupling. “Better” involves semantic names. “Better” involves more clarity, for which I rely on PEP 20. PEP 20 outlines several rules, such as “Beautiful is better than ugly” and “Flat is better than nested”. The application of these tendencies leads to code that easier to reason about.
Beyond the fact that deeply-nested code is hard to reason about and
rac_liftSelector: is an ugly method, Objective-C in particular is a bad place to shoehorn FRP into. There are two important reasons for this.
Objective-C was designed for objects, and it is extremely good at them. Of all of the object-oriented languages, I find Objective-C very enjoyable to work with. It’s dynamic and flexible like Ruby but maintains order through its compiler and type-checking.
We Objective-C developers seem to have forgotten what objects really are, with this Massive View Controller problem that faces us. Functional Reactive Programming is definitely one way to deal with this problem, but I maintain that programming with real objects is another, perfectly effective way. In addition, object-oriented programming falls more in line with the analyzer and compiler’s expectations, giving us more type safety and double-checking our work.
The other reason that FRP doesn’t work as well in Objective-C is that blocks are really, really bad. The
__weaking dance is incredibly annoying and reminds me of the pre-ARC days, except more complex and specific. It’s possible to write code that wiggles around having to
__strongobjects, but it requires more thought than it really should have to.
There are more signs that working with blocks is hard in Objective-C. Consider the
__blockspecifier. Requiring special behavior to change a primitive or a pointer inside a block shows just how weird this block syntax really is. And that’s ignoring the weird caret (^) and parenthesis rules you have to follow that make me go to fuckingblocksyntax.com every day. These things may change in the future of Objective-C, but Reactive Cocoa is here now.
I have no doubt that FRP is a new, fun, and exciting way to write code. I’m going to give it a deeper look and try to build something with it, as Chris suggested. Whether it’s worth it to start building all apps in it still remains unproven.