Counting Clojure Code
aaroniba.netWhen I first started learning Clojure I was surprised at how concise it actually is. I was so used to scanning imperative code in huge jumps, that the conciseness caught me completely off guard and I would scan functions without even taking it in. Every.Single.Word matters in Clojure, there is literally zero boilerplate. So I agree that counting nodes is actually not a bad way to measure how much the code base grows over time.
> I also count lines when choosing libraries. When you depend on a library, the library code becomes your code in a way. [...] If two libraries do roughly the same thing, but one has far fewer lines, I will usually prefer the smaller library.
This is a little odd imo. Far more important when choosing a library are other aspects like its maturity, activity, interface width...
In fact, the goal in choosing a library should be to minimize the probability that the "code becomes yours." You should be looking for a strong and stable abstraction, first and foremost.
I think this heuristic is using lines-of-code as a proxy for simplicity, in the simple-vs-easy sense. All other things being equal, and presuming the difference is architectural rather than an artifact of a too-clever coding style, I would tend towards the shorter library too.
Fair enough. In my experience it is rare to need library X and to have such an array of choices that LOC suddenly becomes the differentiator.
I've never turned to LOC directly myself, but I have occasionally had to choose between 2 or 3 lone-wolf Clojure libraries to do a thing, and picked the one that seemed to have the sharpest focus or the most coherent implementation, which is usually the shorter one.
> All other things being equal...
...but they're not. Perhaps one time in 50 you'll find a topic so well worn that you have choices between multiple mature, stable libraries with good APIs that lets you dig into the source code to see how nice it is (by whatever metric) to decide if you want to use it.
Perhaps what, json parsers?
I can barely think of any other examples.
It's a completely pointless metric.
The beauty of the API is far more important than looking into the implementation to see how it was written.
Heck, the library could be one giant regex on one line, but if the api is:
...there's no way you'd want to touch that library.void *libfoo_random_meaningless_name(void *n, ...);I very much doubt the elegance of the implementation is a metric that should be used to pick a library; there are far more important metrics to look at.
I agree there are many considerations when choosing a library, but conciseness does come up. For example, I was recently impressed with how concise http-kit is. The author seems proud of it too:
http://www.http-kit.org/http-kit-clean-small.html
You and I probably just have different values on this matter. Your comment implies that conciseness is merely "nice", so I'm guessing you just don't value that aspect of code as highly as I do.
We'll have to just disagree.
I place zero value on the detail of the implementation of a library; only on the API that I use.
It's like picking a radio at the shop by opening each of them up and inspecting the quality of soldering and board schematics.
...yes, you'll get a better radio if you do, but if you're furnishing a kitchen, you'll spend the rest of the month opening appliances and looking inside them instead of building your kitchen.
I guess it depends what you're doing.
/shrug
Yes. You put it better than I did.
TL;DR; He wrote a tool that accurately counts the number of lines in a Clojure project (e.g. ignores comments, etc) and also counts the number of nodes in said project's AST.
I think an interesting metric would be number of AST nodes per line, maybe even providing the top N most complex lines, where complexity is number of nodes per line.
I find that some languages (Scala and Perl come to mind) tend to encourage extremely dense one-liners that have way too much going on with many tiny little temporary variables and symbols all crammed into a short amount of space.
A tool like this, if added to a linter could help discourage that sort of programming.
It would be humorous, but instructive, to have something like this for Java that parses it and dumps out metrics about the tree size for a project - AST node count and static depth, where possible to tell.
>Obviously
``` (f a b c) ```
> is the same "amount" of code as
> `(f a b c)`
Yes, obviously! But they do not take the same number of lines - one is three lines and the other is one line.
It's sort of funny to me- number of lines doesn't paint the picture we want it to... so let's change the metric! Our code is special, anyway.