Initially templates are documents with placeholders… and that is fine for static sites. A program prepares data and a template engine fills the gaps in a template. We have different layers that interact via a fixed interface – common data. It is great because a designer and a programmer are free to organise their areas of responsibility any way they like while they respect the interface.
The idyll is over when we add behaviour. Behaviour is the programmer’s responsibility but it is highly coupled with representation. So we can’t split the layers now and we lose the interface.
I think we should accept that we can’t separate markup and logic and that the idea of templates becomes obsolete. I believe we must follow the divide-and-conquer principle: break our application into parts, mix markup with code into components and use object-oriented or functional decomposition to organise it.
Frameworks that still use template based approach are AngularJS, Knockout, Backbone and others.
2-way binding is an awesome thing when you use it but it is a pain in the ass when you develop a library offering 2-way binding interface. If you aren’t careful enough your users will meet accidental memory leaks, repeated diamond shape problem & observable inconsistent state.
For example Knockout uses a straightforward implementation of the 2-way binding approach that leads to all the mentioned problems.
Separation of technologies doesn’t mean separation of concerns. View and behaviour are coupled and if we put them in different files we don’t avoid the coupling. We must face it and use another ways to deal with complexity.
From a software engineer perspective the best way to handle complexity is
The default ways to do Abstraction and Composition with code are object-oriented design and functional approach. If we put markup into code we can use these well known methods to deal with the complexity of modern web applications.
And as a side effect we get a tool for distributing components for free – all we need is to pack our component as a require.js or commonjs module.
Mixing markup and behaviour doesn’t mean that a designer should constantly edit the code, because a lot of layout can be done through CSS.
Functional programming shines when we talk about data transformations. Let us imagine for a while that we’ve returned to good old times when all web applications are static. If we need to render a list of addresses into a piece of html, we may end with this procedure
renderStackedWidgets is provided by a library and we’ve already implemented the
renderAddress then the implementation of function that renders stacked addresses is very straightforward.
If we fast-forward time to our days this code becomes insufficient because we missed the behaviour. Our list of addresses may be changed over time so we need to update the screen. We need to keep our transformation active all the way, just like in the spreadsheets. With it when you update one cell the others are updated automatically. Modern spreadsheets is a well known example of reactive programming. So we need to add reactivity to keep the code simple. That is exactly what Warp9 does.
I’m a fan of the Star Trek series, so I took the name from its universe. The Warp drive invented after the modern reactive engines, makes it possible to travel faster than light and allows humanity to go where no man has been before. I think it is a good name for a reactive library that avoids common pitfalls of the reactive libraries.
I used a lot of interesting techniques during the development of Warp9. For example I had to maintain an explicit graph of dependencies to avoid accidental memory leaks and I had to propagate the changes through the graph in a breadth-first approach to handle a repeated diamond shape problem.
When I was working on reactive primitives I dived into monads and monoids to support the reduce operation on a reactive lists. I’ve read a lot of articles and the most interesting were about treap, rope and finger-tree data structures and about an incremental regular expressions.
Nevertheless I don’t have an intention to maintain and develop the project further. No, I don’t think it is perfect. For example, if I could start again I would build Warp9 based on React.js to utilize the idea of virtual DOM (just like Om). It is all about time, I’ve done what I wanted and now it is time to learn something new or to do something that would have a bigger impact.