Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is a topic that I think requires a more in depth article, but I'll attempt to justify myself as best I can in the limited space of a comment.

In most languages, related data is generally represented by some manner of closed record, struct or object. In Clojure, this data is represented by open maps instead.

This distinction may seem minor or even irrelevant, but in my view it's the key difference between Clojure and other languages, and the reason why the MVC pattern has never quite fit comfortably in Clojure.

In a language that uses closed records, complex data tends to align itself in terms of fixed hierarchies. Think of how the models in Rails are typically laid out. You have a few dozen models, with a handful of fields each, arranged in some sort of static tree or graph.

In Clojure, data doesn't tend to align itself in the same way. Data doesn't need to be artificially grouped if there's no benefit in doing so; its structure can be much more amorphous.

There's a similar problem at the "view" end. REST tends to assume a hierarchy of resources, when that may not be the best way for the client to get the data it wants, or for the server to represent the data.



> Data doesn't need to be artificially grouped if there's no benefit in doing so; its structure can be much more amorphous.

I'm curious, just because Clojure offers that flexibility to a developer when writing the logic in their app, why does this flexibility need to "interfere" (for lack of a better word) with the design of a web framework?


For the same reason you wouldn't design a web framework in Ruby that doesn't use classes. Technically possible, but you'd be fighting against the design of the language.


In Clojure, this data is represented by open maps instead.

Is Clojure unique here? seems this is the norm for Javascript applications too, that are done mostly with a FP style, instead of open clojure maps you have open JS objects. Most JS SDKs and libraries I have work with is just passing JS objects between them and your code.


Javascript objects have some differences to Clojure maps that make them harder to use in the same way.

For example, you don't have to store functions in objects in Javascript, but the language design encourages it. This is problematic because we can't pull data out of an object without considering the functions that rely on it.

Another issue is that keys are not unique. Two objects might contain an "id" key, for example, that identifies them in different ways. This is problematic if you want to arbitrarily merge objects together.

Idiomatic Javascript might look like this:

    user.orders.total_cost()
But if we want to program in the same way as Clojure, we'd perhaps be writing something more like:

    Orders.total_cost(user["user/orders"]);
Not impossible, but certainly more inconvenient.

The more you force rigid categorisations and behaviour on data, the harder it is to manipulate and organise in different ways. In-memory data is almost always ordered with a hierarchical structure, because that's what closed records gravitate toward. But if we take a look at databases, its rare to find any organised along strict hierarchical lines.


Another issue is that keys are not unique. Two objects might contain an "id" key, for example, that identifies them in different ways. This is problematic if you want to arbitrarily merge objects together.

Don't exactly understand this part, if one of your objects has its unique identifier as "userID" and the other as "invoiceID" you can merge them without conflict or what I'm missing? "id" is indeed use widely in blog examples/tutorials and even books but it's not the norm for enterprise data.


If you ensure that all object keys are uniquely named, then merging objects wouldn't be a problem. But unless you use some sort of naming convention to enforce it, the more keys you have, the more likely it is for naming clashes to occur.


Ok, so this normally tackle in Clojure using namespace keywords correct?


Yep. And the advantage of namespaces over a naming convention is that they can be enforced by the compiler and shortened with aliases.


JS offers classes (or a similar construct pre-ES2015) and you can’t easily merge two objects (there’s the spread syntax, but that doesn’t bring along the prototype).

So you’re mostly rewarded by keeping object «types» seperate


I don’t know, JS is famously a lisp hidden under the C syntax.


and under the rest of the stuff Lisp does not have at its base, like an prototype object system.


It’s interesting though that JS never picked up a Rails alternative.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: