Live data from Hacker News

Abstract Clojure

juxt.pro

1–10 of 43 posts

Re: Abstract Clojure

#2
Great pointers, I started learning Clojure for a hobby project and was initially put off by the lack of ‘frameworks’ like nextjs or rails, but after effectively piecing my own stack together from components like Reitit and Integrant I’m really glad I didn’t use a framework.

I actually feel like I understand everything that happens in the system now, and when problems arise I can REPL in and hunt them down with confidence.

Though I don’t use Clojure professionally, I’ve definitely become a better developer just from playing with it, a contrast to JavaScript where I feel like learning it actually lowered my iq…

Re: Abstract Clojure

#3
I also recommend the book "Grokking Simplicity" by Eric Normand for a longer exploration of functional software design (not Clojure-specific). The linked blog post uses Clojure examples, but this approach to software design is universally applicable (especially in functional programming!).

Re: Abstract Clojure

#4
I'm not sure I agree here. There's not too much value in testing these two or three lines of code in the get-article handler. And the passing around of compositions of higher order functions can get confusing. There are cases where an approach like this is warranted but I would say that there needs to be a significant level of complexity before this makes sense.

Having a protocol for your data layer and an in memory implementation of that for testing can make sense, especially when your real data store is expensive to bring up, but I would try to minimize the number of seams like this in my system. Each one introduces cognitive overhead due to indirection, so you should use them judiciously.

Re: Abstract Clojure

#5
> One of the trade-offs with this approach is that it results in additional wiring; functions must be passed their dependencies and wired together to form a system. The indirection means we can no longer jump to the definition of get-article-by-id in the server namespace.

That seems like a huge loss. I feel like that approach could be great for business logic maybe? There's the "business logic as a library" technique that works well for this, and allows for easy testing.

Re: Abstract Clojure

#6
post #5

> One of the trade-offs with this approach is that it results in additional wiring; functions must be passed their dependencies and wired together to form a system. The indirection means we can no longer jump to the definition of get-article-by-id in the server namespace. That seems like a huge loss. I feel like that approach could be great for business logic maybe? There's the "business logic as a library" technique…

Doesn’t it also make the stack traces more difficult to read as well?

Re: Abstract Clojure

#7
Nice article. I have to admit living in the dark ages, Clojure wise. I don’t even use Protocols, just simple functions and I love the simple built in data structures. I was comparing my Clojure and Common Lisp libraries for using OpenAI’s GPT3 APIs last night. I usually use CL, but I notice how much cleaner the Clojure version looked (I should refactor the CL version).

Clojure is such a practical language.

Re: Abstract Clojure

#8

I'm not sure I agree here. There's not too much value in testing these two or three lines of code in the get-article handler. And the passing around of compositions of higher order functions can get confusing. There are cases where an approach like this is warranted but I would say that there needs to be a significant level of complexity before this makes sense. Having a protocol for your data layer and an in memory…

Yes - sometimes you can go too far in the quest for abstraction. I've seen a ton of over-enterprisey people build gorgeous abstractions with perfect testability and dependency management, only for it to be used only ever in one context in one way. I lean towards WET first before extracting an abstraction, if that.

Re: Abstract Clojure

#10
If you use Integrant like they suggest, you don't need to do any of that for testability. You can just use the code you had originally and have a test function that just creates an Integrant system with all fake dependencies. Then you can just reuse that test function in every test, occasionally overriding one of the fake dependencies.
Post reply on HN