Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Models in Clojure

As a Ruby on Rails developer, when designing/implementing a web application I take essential concepts/entities from the problem domain and implement them as models. Typically, those are classes derived from a base ORM class (e.g. ActiveRecord::Base), they map records from a database table and add contain extra methods that implement business logic related to the model.

Advantage of this approach is that you can quickly find all the business logic related to the object from the problem domain, so that if the model class is not large you can efficiently comprehend how that part of the application works. It also separated from all presentation logic. Besides, thanks to ORM the business logic methods contain little DB-specific code and thus quite clean and easy to read.

Disadvantage is that such classes often grow to an enormous size and thus difficult to understand as a whole.

So my questions are:

  • Do Clojure ecosystem provide some libraries that fulfil a similar function as OOP's ORMs?
  • What is the "Clojure way" to organize such code?
  • What are the advantages and disadvantages of the approach?
  • Some articles / books / talks that explain and justify the approach?
  • Are there some open source (example) applications that showcase the approach?
like image 249
Alexey Avatar asked Oct 03 '13 19:10

Alexey


2 Answers

One of the driving philosophies behind the development of Clojure is to separate complex things to the greatest degree that is reasonable, and to treat data as data and hence to avoid combining data and separate value state and identity.

  • Do Clojure ecosystem provide some libraries that fulfil a similar function as OOP's ORMs? The desire to process data with pure functions that transform one data structure into another causes some clojure programmers to shy away from ORMs though there is no reason you can't use Hibernate in Clojure if you really want to.

  • What is the "Clojure way" to organize such code? I like Amit Rathore's presentation of the topic

  • What are the advantages and disadvantages of the approach? Rich Hickey gives an excellent discussion of these ideas in this classic video
  • Some articles / books / talks that explain and justify the approach? I personally recommend The Joy of Clojure,
like image 114
Arthur Ulfeldt Avatar answered Nov 06 '22 07:11

Arthur Ulfeldt


To put it simply, you don't wrap stuff in an object, you directly program with data structures like lists, sets and maps. So the work that was done ORMs is reduced to converting one data structure to another: for example a user-row->user-record function might convert a list of values that you pop from a SQL database to a map that represents a user in your app's business logic. When you save the user you have to call a reverse function.

I have to say that it is really hard for an experienced OOP programmer to kinda "get" the fact that there's much less ceremony around stuff. Our brains seem to fight this idea - IMHO because it seems too simple and immature for an experienced developer/software architect. :-) I wish I could write more complicated response full of weird terms to sound like a real expert, but I actually can't, because there isn't that much more to add. :-)

By the way, a small but interesting point - the pervasive use of data structures is a practice that is considered wrong in the OOP world. For example you should not store money in a simple tuple [10, "USD"] but rather write full blown public class Money that would encapsulate all the currencies, comparing, rounding etc. But writing tuples is exactly what we do in FP. I remember I had some weird feelings about this coming from the OOP world.

When it comes to organising your code more or less the same rules as in OOP apply in terms of namespaces. You organise the code based on topic as you would in java packages, except that all the functions (that you used to call methods) are now stateless and usually take things like the user record mentioned above as an argument. So instead of foo.barChange() you would have (bar foo) where pure function bar would return a new data structure foo2 instead of modifying state of foo.

That being said one of the benefits of OOP is that not only there has been many applications written using this paradigm, but more importantly there has been multiple generations of approaches tried out (this is how we got to things like todays popularity of DI containers etc...). Functional programming doesn't have this yet. Basically no-one has a proven final manual on how to do architecture of an app in FP. And by the way this is why people are generally discouraged from writing big frameworks and encouraged to stay with data-transforming functions. That way you can always wire it up the way you want it and avoid architectural pitfalls.

like image 8
tillda Avatar answered Nov 06 '22 08:11

tillda