Hacker News new | past | comments | ask | show | jobs | submit login

As someone who tried Clojure and failed, serious question: Does anyone actually use all these crazy features/patterns that keep getting added/discovered and talked about?

I ask because even though I can imagine someone smart mastering these things and programming faster, I can't imagine a second person being able to understand his code, maintain it, and generally be productive. I imagine the second person losing a lot of time trying to understand what is going on, or even thinking he understood but in reality he didn't and messing things up.

So how do you even form a Clojure team?

It's a mindset change.

Other than macros, which fundamentally alter the flow of code in a very non-standard way, the rest of these "crazy patterns and features" in Clojure are just like the crazy libraries used by typical Java/Ruby/C# developers, only thousands of times simpler. If I came to you and said, "does anyone even use these tens of thousands of libraries in Maven? How do other developers work on this afterwards, they'd have to learn all these new APIs!" I'd likely get a response like, "they'd just be expected to", with a chuckle. The mindset I've seen a lot is that language features are "too hard" to learn and should be avoided, but library complexity is beyond reproach and is rarely questioned.

Clojure the language takes the approach that it's better to provide a dozen simple but incredibly composable tools that can easily replace a lot of duplicated boilerplate in other languages. Like these transducers, in Java/C# they'd likely be one of the design patterns that needs a whole set of classes to make what he shows in a few characters. Would you rather learn to write and read maintain a handful of classes, or just learn what those few characters mean? I don't get paid by the line, and any abstraction built into the language like that is a few more classes I don't have to maintain and possibly implement incorrectly in some subtle way.

Like I said, it's just a mindset change. I know a company that only uses Clojure, and they hire a lot of entry level developers who haven't yet gotten stuck in a mindset that "languages are too hard; libraries are easy". They have great success with that, and their entry level guys are up to speed much faster than those in my shop, using .NET, where they have to learn a new language AND a mountain of boiler plate code using dozens of libraries and frameworks.

> Would you rather learn to write and read maintain a handful of classes

I appreciate your answer, but that's not what I do with libraries. I don't have to read their internals, let alone write them.

I may have communicated that badly. A pattern like transducers is one that everyone needs. Everyone either uses it built into the language or writes it out long form. Design patterns are a way of giving you instructions for writing it out long form. So, you either write it yourself or use it built in.

Some people do not want to learn language tools that will reduce such boilerplate, but those people often are (ironically) happy to learn lots of libraries. Libraries by definition can't remove any more boilerplate than you can, they are just as limited by the language, so often times just save the user some writing, rather than reducing (haha) it across a whole codebase like a built in feature can.

I work in a clojure shop with about 10 other developers. Until very recently, we hired folks with zero exposure to clojure or even function programming. Do we use all the new bells and whistles that Rich and the folks at Cognitect develop for clojure? Yes, but we're not jumping into the existing code base and refactoring everything to use core.async or reducers. Usually, one or two guys will use it in a less public, less critical piece of the infrastructure as a real-world application and then we do a code review with the whole team.

So, how do you build a clojure team, exactly? Don't try to exclusively hire developers who have been exposed to it yet or have masters degrees from elite universities, focus on finding people who love to program, who are genuinely interested in improving their own abilities, but can clearly hold their own in the language they currently use. You will soon have a team of developers who love the challenge of keeping up with what guys like Rich Hickey (and Cognitect) are doing. We have been very successful with this.

Sounds like the job I'm looking for :)

Something I've noticed about Clojure code is that people tend to have taken the effort to express a problem in a concise and logical way, even for very complex problems. I'm not sure if it's just because Clojure attracts people who value good code, or because Clojure provides the tools to do it, but it sure is nice. Better to spend an hour on a 5-line function than a 50-line one, if they accomplish the same thing in the end.

I don't think that 5-line function will be understandable by the next programmer who has to deal with it though. That's my point. It probably involves a Fibonacci or other math trickery that not everyone might have fresh in their minds.

You may be mistaking patterns with 'clever hacks'. If the 5-liner is about writing the shortest possible code, then it certainly isn't beneficial to anyone (except for the original author who has all the fun of coming up with a 'clever' solution). But useful abstractions are a different matter whatsoever.

Just look at Go channels or at reactive programming patterns. If applied to the right problem (i.e. a problem they help solve), they allow you to solve the very problem in a very concise and expressive way.

Having such patterns as a part of the language just makes them more popular and reusable.

And as far as your point, don't you think it's easier to spot a 5-line pattern than a pattern that is spread out over several classes and 200 or so lines of code? It all boils down to this: being able to see patterns or abstractions if you know that and having a common language across the team. Functional 'patterns' are just (arguably) more succinct than object-oriented ones (and it comes from someone who has been programming in C++ and Ruby for nearly 20 years).

In my experience the answer is yes but there isn't necessarily a hurry. I work in a small shop with 3 other Clojure developers who vary in experience from pretty green (I'd dabbled a bunch but have only been writing it professionally for about 4 months) to wizard (people who are going on two years and written the majority of the libraries we use, who are fluent in pretty much everything all the way up the stack). The learning curve for me has been like this:

Stage 1: Deep end. Given a task, I crack open an existing application and spend half a day to a day just trying to read it and figure it out. I struggle with my notions of state and immutability, make and test some changes until I think I have it figured. It's slow and arduous, at this point I'm reading Chas Emerick's book and mostly writing very standard clojure, dipping into and experimenting with things like multimethods and atoms.

Stage 2: Local maximum. I'm comfortable with some of the better patterns to pass around and manage state, make a lot of use anonymous functions, and a lot of my code looks like a let to establish useful local variables followed by a return. I get comfortable with writing programs either from the top down or bottom up, slowly building to a point where everything ties together. I start dipping my toes into core.async.

Stage 3: I get very comfortable with core.async and appreciate channels as a really nice way to separate concerns, you can build a whole bunch of neat little machines with channels. Sometimes I go a little overboard and roll something back to just using functions.

Stage 4: Start writing code where you realize you could use a macro. Macros feel about as hard as stage 1, with careful repl development and scrabbling to build some kind of conceptual framework where the whole thing hangs together. Transducers come out, I read about them and understand them conceptually, and get pretty excited about the use of pipelines, which present a much nicer way to chain channels together (where before you might use a map or write custom functions to do channel transformations, but they don't prove to be very composeable).

That's pretty much where I'm at right now. I'm comfortable, but there's still a lot of stuff I haven't really jumped into. One nice thing about most of these constructs is that if my conceptual grasp is wrong, things usually don't work at all, and that's a good time to ask questions to others.

As far as building a team? If progressing through those stages and having days that are frustrating followed by some big breakthroughs seems appealing, that's probably a good indicator that you'd fit into this sort of environment. When I was dabbling I made some progress and started to understand some of these mechanisms, but sometimes you need a problem staring you in the face that requires some fancy moves to solve to motivate you to push past what you know.

It seems daunting at first, but I sort of think that all of programming is. Practical knowledge can be acquired through experience, but it's expanding how you work theoretically that is the hardest and most rewarding.

Just a datapoint, anyway.

This sentence is important: "There will be more explanations, tutorials and derivations to follow, here and elsewhere." If a team ever adopts transducers, it'll generally be after a lot of explanations exist and has been made easy to understand.

Clojure teams can defend themselves against exotic features like any other team: code review, conventions, etc. If I pull in some weird new feature, others had better be ok with it.

(Obviously, what I'm saying doesn't apply to every team in the world; presumably there's a spectrum of ways to deal, or fail to deal, with this problem.)

In my view, Clojure teams are formed via a political process, like any other programming language adoption.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact