More power and flexibility. Less plumbing. Less moving parts.
MFlow is simply the most high level, most advanced and fun to program web framework. MFlow uses Haskell magic to counteract the wicked magic of the inversion of control, where the web server call the application in unpredictable ways, and the programmer has to figure out what happens and reconstruct the context by hand. The Web programmer work is terrified by an explosion of events, configurations, plumbing, lookups and identifiers dispersed in different methods, files, formats and configurations. MFlow restore web programming to his intuitive and natural way again by bringing the programmer a safe and predictable context with all his data and context available in a single piece of code where all that happens is in front of his eyes.
Everything in MFlow that seems sophisticated is to solve a user problem, not a way to hide with fancy names the inherent flawed nature of the MVC model when used in real web applications.
MFlow Web applications are much like console applications. You just write an ordinary sequential program with inputs, outputs and control statements where the inputs and outputs are web pages. MFlow will run the sequence forward and backward depending on your input to find the appropriate location in the sequence to respond your query.
MFlow works in the same way people would read a cooking recipe: Each person look for instructions forward or backward until they find the correct point in the sequence appropriate for his state in the cooking process. To know his state, the people remember the name of the steps already done, but not the details of each step. That is exactly what MFlow does. All is pure tracking, backtracking and event logging.Other frameworks try to do it with heavy page state or execution state snapshots That is too bad for scalability and this has limited the acceptance of this model for large scale web applications.
Since the navigation is coded as a normal procedure under the navigation monad, any navigation sequence can be reusable. Deployment and configuration is reduced to zero. The elements can work together if they type-check. In the examples you will see different ways to combine components: either widgets inside widgets, different widgets in a page or complete application flows called as normal procedures in a program.
To invert back the inversion of control of web applications and turn web programming into ordinary, intuitive, imperative-like, programming, as seen by the programmer.
At the same time, to maintain for the user all the freedom that he has in web applications. Back buttons and bookmarked URLs must work.
For scalability-sensitive applications, to avoid the fat state snapshots that continuation based frameworks need to cope with these two previous requirements. State replication and horizontal scalability must be possible.
For REST advocates, to maintain the elegant notation of REST URLs and the statelessness of GET requests.
For expert haskell programmers, to reuse the already existent web libraries and techniques.
For beginner programmers and for Software Engineers, to provide with a high level DSL of reusable, self contained widgets for the user interface, and multipage procedures that can work together provided that they statically typecheck, with zero configuration.
MFlow solves the first goals using an innovative approach. The routes are expressed as normal, monadic haskell code in the navigation monad. Local links point to alternative routes within this monadic computation just like a textual menu in a console application with print and read can redirect to one or other code depending on the user input. But unlike in the case of a console application the user ever has te option of press the back button and go back go to the menu back again. Any GET page is directly reachable by means of an URL.
At any moment the flow can respond to the back button or to any RESTful path that the user may paste in the navigation bar. If the procedure is waiting for another different page, the navigation monad backtrack until the path partially match. From this position on, the execution goes forward until the rest of the path match. Thus, no matter the previous state of the server process, it recover the state of execution appropriate for the request. This way the server process is virtually stateless for any GET request. However, it is possible to store a session state, which may backtrack or not when the navigation goes back and forth. It is up to the programmer to decide.
When the state matters, and user interactions can last for long, such are shopping carts, it uses a log for thread state persistence. The server process shut itself down after a programmer defined timeout. Once a new request of the same user arrive, the log is used to recover the process state. There is no need to store a snapshot of every continuation, just the result of each step. As a result, the overhead of state synchronization with persistent storage and among machines is light. The memory footprint is also low since the timeout-recovery mechnism clear the idle processes from memory.
It is data cache within the STM monad (Software Transactional Memory). Serialization and deserialization of data is programmer defined, so it can adapt it to any database, although any other database interface can be used. Default persistence in files comes out of the box for rapid development purposes.
Persistent allow MFlow to ease the connection to different SQL databases and other NoSQL databases such is MongoDB.
To combine widgets, applicative combinators are used. Widgets with dynamic behaviours can use the monadic syntax and callbacks.
It is designed for applications that can be run with no deployment within runghc in order to speed up the development process. see this.
Widget requirements for automatic installation of scripts, CSS and server flows.