by jlarocco on 5/16/25, 3:57 AM
Coming from Common Lisp, I find both versions are pretty hard to read, and I find Clojure in general difficult to grok. Every example of Clojure I see looks like the author is "code golfing". Why the instistence on such terse, cryptic identifiers? Every other Lisp, going back to the 60s, uses readable text names, and it just baffles me that Clojure decided to go a different way.
The sentence generator in my Markov text generator CL package looked like this:
(defun generate-random-sentence (mtab &key (first (random-elt (first-words mtab))))
(with-slots (prob-table) mtab
(format nil "~{~a~^ ~}"
(loop
:for next-word = first
:then (pick-random-word (gethash next-word prob-table))
:while next-word
:collecting next-word
:until (ends-with-end-sentence-punctuation-p next-word)))))
by roxolotl on 5/16/25, 1:26 AM
I’ve been writing a lot of functional lisp lately for the first time and one thing that’s struck me is how easy it is to refactor. Because a form can always be reduced to its result, you can pluck them out, move them around, and evaluate them at any level of the tree. While this is true of functional programming in general the structure of lisp makes its super easy in a way it’s not in a Haskell or just functional JavaScript.
by noodletheworld on 5/16/25, 12:39 AM
Seems fair, but refactoring is generally tricky and:
1) replacing a func with a simpler recursive func may or may not be ideal.
2) this fills me with no joy when I read it:
> It seems easier to start from scratch as opposed to refactor it. The characterization tests above will help ensuring that the returned hash map stays the same.
Its enormously hmm… what word to use. Ambitous? Foolish? Brave?
Anyway, taking code, writing some tests for it and then rewriting the entire thing so it passes the tests you wrote only barely falls into “refactoring”.
If anyone refactored my code base by simply rewriting from scratch the parts they dont like, I would be upset.
Rewriting things is hard, and its … brave… to think you can just write a few tests and then if they all pass its all good!
That only works in very trivial examples, and really, doesnt show case the strengths of clojure at all.
by gleenn on 5/15/25, 9:50 PM
In general, it's a dream to test and refactor Clojure IMHO. Working with mostly static top-level functions, immutability by default, and mocking when necessary with the use of "with-redefs" makes writing tests easy. Also, the immutability makes it hard to break shared copies of memory which seemed to plague my earlier tangos with large Java code bases and standard OOP practices.
by NightMKoder on 5/15/25, 10:43 PM
Usually the controversial decision for Clojure code highlighting is rainbow parens. This color scheme is horrific and unreadable (on mobile at least).
by 0_gravitas on 5/15/25, 11:43 PM
First few comments are nothing but shallow {rem,sn}arks on the formatting of the site, by users that don't even have the excuse of being recent joiners. If this is how we lead by example then it's no wonder why the quality of content+comments on this site are (imo) on the decline.
by michaelteter on 5/16/25, 1:53 AM
The first thing I would do would be to take some of the inner forms and turn them into functions (single responsiblity). This isn't even Clojure-specific.
Lots of little, simple functions, composed... You can still use the threading at a higher function, but instead of doing the actual work at each step in the pipeline, you call a well-named function which does what that step was doing. Yes, it may feel redundant, but it absolutely improves human comprehension because it reads like clear human instructions.
Tests become much simpler too.
The only two challenges I face with this approach is 1 - naming things, and 2 - organizing. The function names tend to become quite long, since they ideally describe what the function does.
I haven't done this lately, now that the AI tools have become pretty great; I can imagine that an AI tool would be an excellent knowledge base for these many functions, and it would probably be very successful in providing additions or modifications given the clean, clear function names and brief contents.
by billmcneale on 5/16/25, 4:58 AM
> Our mission is to take this code and make it readable:
Anyone else finding some irony in the fact that the provided code is unreadable not because of its structure but because of the highlight colors?
by lenkite on 5/17/25, 8:55 AM
The original code was very readable to me - after I copy-pasted it into a text editor without all the jazzing colors and horribly low contrast.
by IceDane on 5/15/25, 9:53 PM
It's kind of funny that this article starts by showing a completely unreadable code snippet, but not because of the code, but because of the syntax highlighting scheme. There is no version of that code, or any code for that matter, that is readable using that color scheme.
by leelou2 on 5/15/25, 11:17 PM
This article hits on something I've been wrestling with in our codebase. The absence of static typing in Clojure makes refactoring feel like walking a tightrope without a safety net sometimes. I've found that building a solid test suite before any major refactoring is absolutely critical - it's the only reliable way to ensure you haven't broken anything when reorganizing code.
What's worked well for us is treating functions as the primary refactoring unit rather than trying to impose OO-style refactoring patterns. Breaking down large functions into smaller, well-named pure functions has provided the most bang for our buck. We've also found that leveraging spec for runtime validation gives us some of the safety of types without giving up Clojure's flexibility.
The tooling situation has improved significantly too. Cursive's refactoring tools have been solid, and I'd be curious if others have had success with the newer REPL-integrated refactoring approaches mentioned in the article. Has anyone managed to set up effective continuous integration that catches runtime errors in untested paths?
by arijun on 5/15/25, 9:57 PM
> Our mission is to take this code and make it readable
You failed. Between the unreadable text colors and the word wrap, the code is incomprehensible. I cut and pasted it into a plaintext notes app and it was way easier to understand