In MVC web development frameworks such as Ruby on Rails, Django, and CakePHP, HTTP requests are routed to controllers, which fetch objects which are usually persisted to a backend database store. These objects represent things like users, blog posts, etc., and often contain logic within their methods for permissions, fetching and/or mutating other objects, validation, etc.
These frameworks are all very much object oriented. I've been reading up recently on functional programming and it seems to tout tremendous benefits such as testability, conciseness, modularity, etc. However most of the examples I've seen for functional programming implement trivial functionality like quicksort or the fibonnacci sequence, not complex webapps. I've looked at a few 'functional' web frameworks, and they all seem to implement the view and controller just fine, but largely skip over the whole 'model' and 'persistence' part. (I'm talking more about frameworks like Compojure which are supposed to be purely functional, versus something Lift which conveniently seems to use the OO part of Scala for the model -- but correct me if I'm wrong here.)
I haven't seen a good explanation of how functional programming can be used to provide the metaphor that OO programming provides, i.e. tables map to objects, and objects can have methods which provide powerful, encapsulated logic such as permissioning and validation. Also the whole concept of using SQL queries to persist data seems to violate the whole 'side effects' concept. Could someone provide an explanation of how the 'model' layer would be implemented in a functionally prog开发者_运维问答rammed web framework?
Without wanting to bash object oriented MVC frameworks -- I don't know Rails, but Django is an excellent piece of software to my eye -- I'm not sure that Object-Relational Mapping is a particularly good metaphor1.
Of course in an OO language it may seem natural to want to think of tables in terms of objects, but in a functional language it is perfectly natural to think of tables in terms of tables. A single row can be represented easily using an algebraic data type (in Haskell and other statically typed functional languages) or a map (a.k.a. a dictionary; an associative structure mapping keys to values); a table then becomes a sequence of rows, which after all it is even at the DB level. Thus there is no special mapping from the DB construct of a table to some other construct available in the programming language; you can simply use tables on both sides.2
Now this does not in any way mean that it is necessary to use SQL queries to manipulate the data in the DB, foregoing the benefits of abstraction over varios RDBMSs' quirks. Since you're using the Clojure tag, perhaps you might be interested in ClojureQL, an embedded DSL for communicating with various DBs in a generic way. (Note that it's being reworked just now.) You can use some such DSL for extracting data; manipulate the data thus obtained using pure functions; then display some results and maybe persist some data back to the DB (using the same DSL).
1 If you think comparing a technology to the Vietnam war is a bit extreme, I guess I agree, but that doesn't mean that article doesn't do a very good job of discribing why one might not want to sink in the ORM quagmire.
2 Note that you could use the same approach in an OO language and abstract over DB backends in the same way in which it's done in FP languages (see the next paragraph). Of course then your MVC framework would no longer look quite like Rails.
Have a look at the Conjure web application framework for an example of how one might implement an MVC framework in a functional programming language. Conjure uses clj-record for the model layer, which has support for associations and validations.
精彩评论