On Jul 3, 2:26 am, Mark Engelberg <mark.engelb...@gmail.com> wrote: > 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).
I have done 4 projects, one was with another person and ranked ~1k(a lot of java calls). The others were done solo and ranged from ~300 to ~500 lines. Now that I think about it, that (fail-slow/returns nil) also really annoys me but, that normally only pops up when I have lots of side effects chained (which make the code a lot harder to test, and it generally leads to a lot more code being written before it's tested). Otherwise, I iteratively build things on the repl, this coupled with unit tests forces a bottom up approach and partially because of that the code I write is generally a lot more maintainable than java code. I would definitely like to hear from people with more experience to understand if, how and why things change as the projects get larger (in team size and code size). -- 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