The trip to modern declarative software
It's a known fact that in our community there are always a constant discussions about the best patterns to use when building an App. But I find the discussions about MVC, MVVM, Viper, MVP or whatever new fancy word somebody has come up with today become, at some point, kind of useless. At the end, all of them are quite similar, and all of them are good for some situations and bad for others. If you base your software architecture in separation of concerns you can give it the name that you want.
What I really enjoy is when I see some more profound changes on the structure of an app. One of the more interesting ones is moving from imperative to declarative programming. This is also quite a trend nowdays, so, as any other trend, maybe it only has a temporary impact, but it seems that is here to stay. The best part is that these ideas are not new, but rather reincarnations of old concepts invented in the beginnings of computer science.
Declarative programming has many different ways of manifesting in application development. With this post I want to put my ideas in order on how I see the evolution of this ideas in a personal context.
You can start small by using functional constructs in your imperative code, like map, filter, reduce… this will already improve the legibility and understanding of your code in a local scope. Then you may start structuring more of your code in pure functions that take advantage of it. This is a good start but once you grasp this concepts, you will start seeing the advantages of this change of paradigm and only applying this part falls quite short.
Functional and Reactive
Next step is trying to get rid of state in a world where state is what we need. Seems contradictory but is important to understand that the only thing we care about is to give to the user those changes of state, we don't have any interest in taking care of all the state necessary.
As an aside, you can see how this is quite the opposite of those ideas manifested when you want to care about the machine, about performance, about what the hell is going on in reality. So here you have me, defending two different approaches to software. As always, I love to understand all the different ways of building software, so all of this fits quite well with me :P
Back to the getting rid of state. One solution is using Functional Reactive Programming (or at least, what the majority of us understand by that name). It is a big topic but basically it merges functional programming with a push based model, bringing together declarative style constructs and functional composition to describe the manipulations that we want to do to the data.
This is really good to include in our imperative apps and have the state changing problem kind of solved. For most of the Apps built nowadays I really think that this should be a must.
But we still have to deal with the big stateful monster that is UI, at least in the form that the majority of platform frameworks are built. For that we need, again, declarative ways of building UIs.
Autolayout was a good step in that direction for the layout part of the UI, although time as proven that StackViews or Flexbox are much simpler to use in the majority of cases.
But layout is only one part of the problem, the other is actually building the view hierarchy and rendering it. For that you can use approaches inspired by React. Declare your view tree in a single render function and just call that every time something changes. The interesting bit, and what made React really worth it, is that the render function only returns a structure representing the view hierarchy, it doesn't actually render it. That structure passes through a diff algorithm that generates the minimum set of actions to trigger on the actual UI to transform it to the new required state.
This is made even more interesting with things like GraphQL where you not only define the view hierarchy but also the data that each component of the hierarchy needs.
Predictable state container
The next step, and where this trip ends for now, is putting all of this pieces together with something that keeps the current state of the app, that knows how to change it in a well understood and decoupled way, and that tells the UI to change when appropriate. This is what frameworks like Redux, or the Flux architecture, try to do.
This is similar to the concepts explained by the Elm Architecture. The Elm architecture is quite interesting and the best of it is that it quite naturally emerges from the Elm language itself. Is quite a natural way of building reusable pieces of software in that language. A true source of inspiration.
Be open minded
For most people this are hard changes to understand and they even sound like nonsense. People may like Rx to build the network layer, they may use it basically to deal with callbacks in a nicer way, but don't understand the principles behind it and don't even want to see how it can help in the rest of the application. They just like that it solves the callback hell and deals with concurrency for you. But this is only one small part of everything it can help you with, you just have to accept the change and be open minded. Although, admittedly, this is the big problem with some people.
Going crazier with React like UIs and Redux like patterns is something that not everyone will agree that is the way forward. I'm not saying is the panacea, but people often refuses the idea immediately for any use case. As always there are tradeoffs to take into account, but I really believe that these are better approaches to the kind of software that we build nowadays. Maybe they are not the final answer, but they seem much better that what we have right now.
The strong opinion against big changes is nothing new in our communities. And it also has a good reason. We built our software on top of SDKs that gives us anything we need to built an App. Maybe some of us will argue that what the iOS SDK or the Android SDK give us is not enough to build proper software that can be maintained and quickly changed. But for other people that is nonsense, they just need UIViewControllers and a storyboard and the app is pretty much done. Although may be true, this thoughts and the fact of having these SDKs easily in their hands makes the progress of native development evolve very slowly. How many times have you heard that X thing is not gonna be widely used until Apple adds it in their frameworks? That's a sad but totally understandable truth.
A good example of this can be easily seen following Chris Eidhof, he is an inspiration on applying functional patterns into our Apps. But when people sees all those objects wrapping ViewControllers and implementing the code of an App in the AppDelegate by just passing parameters and functions to generic constructs… people just refuses those ideas. And it's sad, because if more people explored those kind of things, maybe we could build Apps much faster.
But then I keep thinking how Microsoft has basically popularised Rx (not to mention MVVM or MVP) dedicating time in software research projects where things like Rx come to live. I only wish Apple could spend some amount of time in that camp. Don't get me wrong, the Apple SDKs are probably the best SDKs I've seen but I would like that they keep making things better for us, the developers.
As I said, I think this general concepts are here to stay. You know me, I don't really appreciate all the effort being put into JS, and after trying it I still think is a big messy ecosystem even if they want us to believe that is awesome :P (seriously, just getting ready to write some code required toons of things)
But I don't really care about the specific frameworks. What really matters are the ideas.
Remember, be open minded and make our community move forward.