Hacker News new | past | comments | ask | show | jobs | submit login
Clojure at a Bank – Clojure Code Immaturity (pitheringabout.com)
111 points by Adrock on Nov 4, 2012 | hide | past | favorite | 23 comments



I came to Clojure after learning Scheme. One would think going from lisp to lisp would be an easy task, but the languages are so different. Clojure is an incredibly rich language, which is why so many blogs talk about how after 6+ months, the team is still trying to grasp all it has to offer. I started by rolling my own over and over again, only to discover a data structure or technique that erases 50 LOC and opens up a whole new world of program reuse. I have zero idea how someone coming from Python, Java, or Ruby would handle the transition, but I imagine it would be very messy at first.

I'm not sure why the team used single-letter names. Using non-descriptive arg and function names (if he did that too?) is about as anti-lisp as it gets.

I wonder if this blog, and other blogs like this, do a disservice to the growth of Clojure. Not only is it apparent that using a lisp and immutability is completely alien to the teams adapting it, they seem to take a very long time to ramp up into it, and the conclusion is always the same: they are still slipping and sliding, but at least they aren't breaking their noses anymore. At the same time, these blogs are informative of what companies are likely to get into and it should help stymie the surprises and perhaps keep the noise down for a while, so maybe it helps with growth by attracting those that are really willing to hack it. The author, as most are, is forthcoming with the early mistakes and surprises. This is most certainly to be expected when transitioning to any language, but it doesn't seem like there are many languages where bloggers feel inclined to dote on the initial shock outside of Clojure. It is a wonder that they don't complain about the lack of frameworks a'la RoR/Django and other things one would figure they'd want before diving in. Was it the lack of structure that made them go for it in the first place?


I'm not sure why the team used single-letter names

I find myself doing this quite a bit. I think the reason is that it's so pervasive in the core.clj code. Take the documentation for update-in below:

  (update-in m [k & ks] f & args)
    'Updates' a value in a nested associative structure, where ks is a
    sequence of keys and f is a function that will take the old value
    and any supplied args and return the new value, and returns a new
    nested structure. If any levels do not exist, hash-maps will be
    created.
After having looked at a lot of clojure doc, those single letter names make sense to me (k = key, ks = keys, f = function). I use the same style when writing "core-like" functions, but anything remotely application specific is descriptively named.


That makes sense. I was under the impression that they were using it for their program-specific items. Using single letters for common things like k, v, f, args, etc seem more "universal" to other languages than using (defn f [a b c d e] ...).

Of course, he didn't show us any of the funky code he was talking about, but I get this impression from the line about using single letter names instead of highly descriptive names.

I should also take the time to look at the Clojure Core one day. Thanks for reminding me to put that on my to-do list.


Clojure Corey's worth reading, but know that it is considered to be extremely non-idiomatic. Several reasons:

1. Bootstrapping. Some functions are defined somewhat verbosely because the higher order functions are defined later.

2. Performance. By definition, everyone uses core, so core is on everyone's critical path. Therefore, core must sacrifice idiomatic code and brevity for performance. You should make the same tradeoffs only after measuring.

3. Evolution. Clojure has gained features and, since stability is valued, core doesn't get revamped to utilize them without greater justification.


> It is a wonder that they don't complain about the lack of frameworks a'la RoR/Django

No it isn't, because all the basic things needed are there ... Ring, Compojure, ClojureQL, etc... If those libraries where missing, then you'd see people complaining.

On the other hand this does highlight the advantage of using Clojure. Being a pragmatic functional programming language, it's easy to work with and combine small and simple modules, instead of needing a framework that includes the kitchen sink.


I write both rails and clojure.

There's no good clojure web framework for the fat stuff rails is good at, and it doesn't have the same level of plugin maturity, not by a long shot. That's years away. Clojure's good as an API server for a RIA, but it's probably less productive than rails for many use cases. The tools just aren't there, it takes years for tools to get that good. While the java integration is good, using clojure as java glue isn't so fun.

Clojure's strengths are speed, safety via immutable data, and being concise. It's great for a web server if you legitimately have a case where rails is too slow (you probably really don't though). Clojure's also great for non-web programming tasks.


My current project on which I've been working for the past 2 years is built on top of Python/Django and adjacent tools.

The thing I experienced is this - once you outgrow the primary use-cases for a monolithic framework, all of that nice packaging and conventions and modules that play well with each other - start getting in your way, soon to be replaced by custom implementations of whatever you need and all that time you saved initially will be extra time you have to spend to strip out those functionalities, in addition to the time take for building those same things from scratch.

I also worked with Rails btw - for instance you can find like a gazillion plugins for authentication and yet none of them did what I wanted on one project I had, so I had to implement my own authentication logic, after spending hours trying to tweak such a plugin first. That same project needed storage of files on S3, including pictures. Again, there are like a gazillion plugins for that, but none of them did what I wanted. So again, I had to implement it by myself. After trying endlessly to tweak Paperclip or others.

For this project I'm working on the admin interface was initially bootstrapped on top of Django's Admin. Which eventually became a liability and had to be replaced completely. The Django's ORM is also becoming a liability - because it couldn't handle queries for complex scenarios that were unrelated to "objects", so right now the project also makes use of SQLAlchemy - and I'll probably have to pull Django's ORM completely from the project, because the project is also doing sharding right now and I want to expand that to most tables and I can't work with a connection object that's a singleton, not to mention that the "objects" exposed will end up being completely different than the schema used in the DB table, so the object-mapping that Django's ORM does will stay in my way.

In the end, if I need to sum up the things that are still from Django in this project, there are surprisingly few things left.

So if you think about it, for small projects frameworks like Django/Rails are too heavy and for large projects they kind of get in the way and it's better off to start from scratch, importing components as needed, because that way you'll build abstractions that are suited for your domain and that will last longer.


Yes, I found Clojure frameworks, handlers and middleware to be lightweight and easy to use. I'm amazed at how well structured and easy to set up a Clojure web stack can be. Still working my way through the different libraries, and enjoying it.


" I started by rolling my own over and over again, only to discover a data structure or technique that erases 50 LOC and opens up a whole new world of program reuse. I have zero idea how someone coming from Python, Java, or Ruby would handle the transition, but I imagine it would be very messy at first."

This is a good point and keeps happening to me. Otoh, there are a lot built in (and so a lot not to reproduce accidentally). clojure/core has > 500 symbols in it[1]. Is there a systematic way to learn what is 'built-in' to Clojure vs waiting till one stumbles across specific items?

[1] (count (ns-publics 'clojure.core)) --> 580

(on the version of Clojure on my machine -> 1.4.0)


Do the puzzles at www.4clojure.com and be sure to "follow" the top 20 or so users. Once you solve the puzzle, you're shown the solutions of those users that you follow. I learned a lot of neat tricks that way!


The cheat sheet's groupings can make finding things easier.

http://clojure.org/cheatsheet


I read [1] and discovered some stuff there, but it's a bit hard to find new things there when you don't have application for them. In this case [2] really helped me - I subscribed to some top-solving users and after solving a problem I learned alternative approaches.

[1]: http://clojuredocs.org/quickref/Clojure%20Core

[2]: http://4clojure.com/


> Was it the lack of structure that made them go for it in the first place?

Here are the first two posts that discuss their decision:

http://www.pitheringabout.com/?p=693

http://www.pitheringabout.com/?p=749


Personally, I think "rolling your own" is the best way to learn things. Only when you understand things, when they are really internalized, use the built-ins.


Completely agree with learning the clojure core functions. It helps significantly when working with clojures data structures to know whats available.

I also made the newbie mistake of writing simple hash mapping functions that were already well implemented. The problem is coming from Ruby,/Java you're not intuitively aware of the standard functions compared to going from one OO language to another.


Therefore when we jumped both feet into Clojure we unconsciously brought with us the belief that comments just weren’t needed

I used to be in the "code tells a story, no comments needed" camp. In large part because two of my three university courses had automatic marking system which detracted points if comments exceeded a certain percentage of text mass. Habits!

Gradually I've been finding myself commenting more and more in my code. In FP (mostly F#) code I almost always end up with some incredibly information dense set of lines that needs at least some defense of its existence.

Having spent some recent weekends reading the sources of id-software games[1] I've started to really think about the approach to comments in imperative code too. I've started commenting lots and then cutting it down later. If anything, it helps me reason about my code better.

On a totally separate tangent, I feel like the kernel of most of my FP code for data processing is essentially array programming like APL / J, just way way way more verbose.

[1] https://github.com/id-Software


I don't trust myself to know - while I'm writing code - how well I or anyone else will understand it cold. So if I'm in any doubt at all I leave a comment. Sometimes I do go back and remove them - refactoring has to include comments.

Whenever we discuss this topic there are usually some defensive sounding remarks about the fact that inaccurate comments are much worse than no comment. This is certainly true but I don't share the conclusion that the only reasonable answer is to never leave a comment. I guess if that is already what you do, then its probably easier to conclude it is correct.


> In large part because two of my three university courses had automatic marking system which detracted points if comments exceeded a certain percentage of text mass

That sounds like a horrible system. Why'd they ever do that? The grading systems I have seen do the inverse, requiring certain amount of comments. That of course leads students writing gibberish just to fulfill the comment quota, but even that is better than penalizing for commenting.


There speaks somebody who has never spent their evenings wading through terribly project submissions with > 70% comments.

The 'why' would be that there's an entire class of newbie developer who write opaque code, and use the comments as an excuse not to write code clearly.

I see too many developer with the general attitude 'This code is opaque - it needs a comment', where I vastly prefer 'This code needs a comment, how can I make it less opaque.'.


Disappointing as this article has an inappropriate title, it contains nothing relevant to a "bank".


This is the third of a series of posts about introducing Clojure at an investment bank.

The first and second posts are here

http://www.pitheringabout.com/?p=693

http://www.pitheringabout.com/?p=749

Tangentially, the 'swedish colleague' the author brought in to help with the transition to Clojure is the immensely talented Hakan Raberg (sorry don't know how to type umlauts etc on my keyboard) , who is a good friend and worked with me at ThoughtWorks before he went indie.


Yes, to me the title suggested the article was about the immaturity of Clojure Code (as in not ready for prime time) and it was only upon reading it that I realized it was about the immaturity of the OP's Clojure code as he began his Clojure journey.

It was a nice read. I liked the frankness - no claims to overnight Ninjitsu mastery - and yet I get the feeling it's all pretty solid.


Except that the codebase being written about is in production at an investment bank.




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

Search: