I thought that this argument didn't stand anymore, because web components would meet that demand with support for bindings or something similar. Unfortunately, I was wrong: web components can do many things, but synchronizing state and UI is not one of them.
It's here that both articles kinda agree (I and agree with them): whenever you go beyond trivial, you need some structure that helps to abstract the solution that you are creating for the problem you're solving. Programming languages by themselves give some structure, but that's not enough. It's been quite some years that programming languages don't come bundled with heavier frameworks that allow for more complex applications to be developed. I believe that's deliberate: even though there are patterns that can be found in many frameworks from many languages, the users of these languages like the freedom to tinker with different abstractions.
The important innovation of the last years is explicitly separating these two concepts: the user interface's logic state, which is (somewhat) independent of the way it's presented and the specific components you use; and the user interface itself (eg: the components or HTML tags). When you split these two concepts you create (or expose?) the need for state-UI synchronization, because the user interface has its own internal state (controlled, for example, by the operating system or the web browser).
This separation is not new. It exists since at least the 1980s when the MVC pattern was adopted by Smalltalk. The novelty is that separation becoming mainstream (which is something good). Having the user interface logic isolated in a class without concrete UI dependencies makes testing easier (especially unit tests) and forces the developer to think about the user interface more abstractly.
For me, the definition of "framework", what differentiates it from a "library", is inversion of control (IoC). Instead of your code calling some external code, it's the external code that calls your code. The base of the application' structure is not your own code, but the code of the framework. You're given extension points and slots where you put your code, and the framework calls your classes and functions as the user interacts with your application. That allows us to "shift up a gear", to abstract more of the implementation because it hides questions that permeate the application as a whole: access control, sessions, database connections, logging, debugging, profiling, templates and user interface rendering, uploads, forms, validation, etc.
As someone that has used many frameworks, has created more than one framework and has tried to develop without frameworks, I can say that frameworks are really necessary. My experience building "small customer registries" that in time turned to be "little monsters" is exactly that: code reuse through functions and classes, then libraries with more abstract components, then finally inversion of control – in other words, a framework. Even when I tried to get develop with no framework, I ended building a micro-framework because the programming language by itself didn't provide the abstraction level I needed.
There's a saying in some not-so-mainstream programming languages circles stating that "design patterns (eg: Facade, Singleton, Observer) are only required when the language is not rich enough to describe these behaviors natively". I never found a language, be it object-oriented, functional, logic, concatenative or of any other kind, that allowed one to dismiss each and every pattern.
Maybe it's impossible to create a programming language that natively offers all features needed to discard design patterns and frameworks. Or maybe that's the next step: a language that offers, natively, inversion of control. I'm not sure how that would work (maybe something similar to AOP - aspect-oriented programming), but I think it's something to consider: the language would be indistinguishable from the framework.
What do you think?
Congrats on landing here. Next step is to sign up.
Level up every day