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

Reply via email to