Comment by weavejester
15 years ago
This is a difficult question to answer, because it ultimately boils down to the philosophical differences between Clojure and Ruby.
Clojure favours discrete components that do one particular job. For instance, protocols were introduced to Clojure to provide efficient polymorphism, and they do not attempt to do anything more than this.
Ruby is an object orientated language, and tends to favour grouping together a wide range of functionality into indivisible components. For instance, classes provide polymorphism, inheritance, data hiding, variable scoping and so forth.
The advantage of the Clojure approach is that it tends to be more flexible. For instance, in Sinatra you can write:
get "/:name" do |name|
"Hello #{name}"
end
And in Compojure, you can write:
(GET "/:name" [name]
(str "Hello " name))
Superficially they look very similar, but their implementation is very different. The Sinatra code adds the enclosed block to a hash map in the current class, whilst the Compojure code just returns an anonymous function. The Clojure approach sacrifices some convenience for greater flexibility. For instance, in Compojure I can write:
(context "/:name" [name]
(GET "/email" []
(str name "@example.com"))
(GET "/greet" []
(str "Hello " name)))
Because each route is discrete and independent of any larger construct, I can easily take routes and use other functions and macros to group them together.
I may be wrong, but I don't think there's an easy way of doing this in Sinatra, because routes are bound to a class when they are created.
Thanks. I kinda see where that might lead. It feels much like Rails' nested routes.
There are a ton more questions I'd love to ask, but I feel like I'm taking the thread off topic, so I'll go investigate Compojure a bit more on my own.