back

by iLemming·3mo ago·view on hn ↗
> it doesn't support OOP

That is only accurate if OOP means "inheritance-based class hierarchies with mutable state" - which is one narrow definition of it. Clojure has solid OOP support, just not in the class-hierarchy-first sense.

1 comments
In this context, what I mean is "Clojure seems like a more interesting example because inheritance-based class hierarchies with mutable state are a footgun and it lacks them; I wonder if that will help LLMs be any more effective in the language." :)

But I am curious about your favorite OOP-y tools in Clojure. I know it has flexible dispatch, it has a notion of agents that are a bit like objects in how they encapsulate state... but it's been a long time since I really used Clojure and I don't have a clear picture of what the best OOP-y idioms in Clojure look like or what makes them good to use.

Care to explain a bit more?

Clojure is opinionated about state and identity, not about paradigm in general. It will accommodate whatever paradigms as long as you respect its model of how state gets managed. But try to smuggle some pervasive mutability and you'll feel resistance. Immutability and explicit state management are non-negotiable defaults, and most paradigms fit comfortably within that constraint. Clojure bends well toward:

- Functional (its primary identity)

- Data-oriented (how you model your domain)/data-driven(how you control behaivor)

- Polymorphic/interface-driven (protocols, multimethods)

- Logic-style (via core.logic) - mostly unused

- Reactive/event-driven/actor-like concurrency (core.async, manifold)

- There's another paradigm vector (Spec/Malli), but it frankly has the gap in the terminology landscape. It's neither Dependent Typing, nor Gradual; not quite Contract-based Design; not Refinement Types (typically a static concept); calling it Schema Validation really undersells it - implies just input checking. It does something genuinely novel in combination. There isn't a single established term to capture all of that.

Where the language resists:

- Classical OOP with mutable stateful objects - you can do it via Java interop or careful use of atoms+records, but the language actively nudges you away. It won't feel natural and you'll be fighting the grain.

- Imperative/procedural style - possible, but again, why?