I think most are related to easiness, and so not recognized as an advantage by many Clojure acolytes (see: Rich Hickey's Simple Made Easy talk). Others are a consequence of shared state; also not recognized as a positive in Clojureland (rightfully so in most cases).
Here's my list:
- Database migrations
- Fast TDD (for some sub-Gary Bernhardt definition of fast) with access to the app environment.
- content negotiation
- Authentication with Devise and Omniauth
- Easy built-in support for caching
- Easy built-in support for background queue systems
- Easy support for one-off or occasional scripts with access to the whole app environment (rake tasks)
- Pry (yes, Clojure has awesome REPL powers, but Pry is so easy to use, and you have access to the whole app environment (no loading / switching namespaces or abuse of user.clj))
There's probably some solution to each of these. But all require you to find/know the options, and be able to evaluate which is best for you ("all REAL devs . . ." sure, sure). For Rails, all of these are available to you in the Rails Guides, except for Devise+Omniauth, which has an extensive wiki and tons of StackOverflow answers.
Thanks, that's a good list, and I see the problem.
Out of interest, what makes Pry easier to use? I'm not sure I understand the comment about having access to the whole app environment. In the Clojure REPL you do as well...?
When I reflect on the ease of use question, I realize most of my frustrations with the Clojure REPL have actually been with trying to use it within an editor (Vim, Emacs, and Atom so far). And particularly with getting a ClojureScript REPL through those tools. That's not something I try to do with Pry, being content to use it from the terminal, so maybe not a totally fair comparison.
The app environment thing is mostly about having to switch between a lot of namespaces and/or to make sure they're all loaded upon starting the REPL. With Rails+Pry, you can work with any class in your app immediately. It also lets you put breakpoints in your code, where executing the code in a running process throws you into a REPL at that point, with all the local context up to that point of execution. Also, if you make code changes, you simply type "reload!" in the REPL and everything's up to date. I have a bookmark to read Stuart Sierra's post about his workflow to try to get a grip on how to come close to something like that in Clojure.
Have you tried using Cider under Emacs? Or Cursive? Both of those have debuggers that allow you to add a breakpoint in your code and then evaluate arbitrary expressions. They also allow you to step through each form and see the return value.
There are also a few projects for adding in debug REPLs, but those seem to have fallen by the wayside lately, perhaps supplanted by debuggers.
You might also want to talk a look at Duct (https://github.com/weavejester/duct), which is my ongoing and still early attempt at solving some of the framework problems with Clojure. If you create a template via Duct, like so:
lein new duct foobar +site +cljs
Then you some of the things you're asking for. The namespaces of your application are loaded when you start `lein repl`. You get a `(reset)` function that reloads your code, restarts your application and pushes those changes dynamically to the browser. You also get a ClojureScript REPL that hooks into the browser.
There are also generators, migrations, database support etc., but currently all inferior to Rails. I'm probably going to be working on the generators next, as they need attention.
Here's my list:
- Database migrations
- Fast TDD (for some sub-Gary Bernhardt definition of fast) with access to the app environment.
- content negotiation
- Authentication with Devise and Omniauth
- Easy built-in support for caching
- Easy built-in support for background queue systems
- Easy support for one-off or occasional scripts with access to the whole app environment (rake tasks)
- Pry (yes, Clojure has awesome REPL powers, but Pry is so easy to use, and you have access to the whole app environment (no loading / switching namespaces or abuse of user.clj))
There's probably some solution to each of these. But all require you to find/know the options, and be able to evaluate which is best for you ("all REAL devs . . ." sure, sure). For Rails, all of these are available to you in the Rails Guides, except for Devise+Omniauth, which has an extensive wiki and tons of StackOverflow answers.