Ideally, I was hoping to start a more in-depth discussion about the pros and cons of "programming in the large" in Clojure than just waxing poetic about Clojure/Lisp's capabilities in the abstract :)
Yes, much of the initial excitement around Clojure comes from the feeling of "Wow, I can do so much with so little code". But at some point, all projects grow. I'm thinking that by now, there may be enough people using Clojure in large projects and on large teams to offer some good feedback about how well that works. My Clojure codebase is somewhere around 2-3kloc and I already feel like I'm bumping up against some frustration when it comes time to refactor, maintain, and extend the code, all while keeping up with ongoing changes to libraries, contrib structures, and Clojure versions. I want to hear war stories from those with even larger code bases than mine. Has it proven to be a major hassle on large projects to avoid circular dependencies in the modules? Are the lack of debugging tools, documentation tools, and refactoring tools holding you back? Anyone miss static typing? One of my main gripes is that some of Clojure's built-ins return nonsensical results (or nil), rather than errors, for certain classes of invalid inputs. To me, one of the main benefits of functional programming is that debugging is generally easier, in large part because failures usually occur within close proximity of the flaw that triggered the failure. Erlang, in particular, has really promoted the idea of "fail fast" as a way to build robust systems. But Clojure's lack of a "fail-fast" philosophy has burned me several times, with hard-to-track-down bugs that were far-removed from the actual cause. The larger my code grows, the more this annoys me, reminding me too much of my days tracking down bugs in imperative programs. One specific example of this is get, which returns nil whenever the first input isn't something that supports get. For example, (get 2 2) produces nil. This becomes especially problematic when you pass something to get that seems like it should support get, but doesn't. For example, (get (transient #{1}) 1) produces nil, when there's absolutely no reason to think that (get (transient #{1} 1) would behave any differently from ((transient #{1}) 1). -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en