DEV Community

Kasey Speakman
Kasey Speakman

Posted on • Updated on

Why Clojure?

The language is the compiler. What could go wrong?

If you are braced for a hard sell of Clojure then be at ease. Instead I am going to document what interests me in the language. And why I am starting to use it in a hobby project.

Ideas

I was initially attracted to Clojure because it is a Lisp that embraces functional programming. You can probably find a million articles about the benefits of functional programming (immutability and pure functions) so I won't rehash that. But why Lisp?

For me it is the malleability. The language is the compiler. I have the power to add new capabilities to the language for my problem space, without waiting on language developers. For example, other programming paradigms -- including object oriented and functional -- have been implemented on top of Lisp. This malleability wasn't a feature on the backlog that the language developers had to spend millions of man hours to code. It is due to the nature of Lisp code being just lists of data. I probably will not be adding any fundamentally new features to the language itself, but this also means that my everyday business code has a lot of capability at its disposal.

Lofty ideas only get me so far. I also need practical reasons to undertake such a time investment.

Dynamism

For many years I have used statically typed languages. I like types. They bring order to the chaotic universe. But sometimes types can become a little tyrannical.

I usually write our architectural plumbing code, because I am old and I didn't repeat my first year's experience too many times and the team entrusts it to me. In this kind of code I use a "context" type. It keeps settings and operation details (the user, their organization, and so on). This chunk of data gets transformed multiple times (ex. before/after user auth) as it makes its way through the system. At some point, I realized that I was spending a lot of time doing Type Tetris rather than running the plumbing. And now I cannot unsee that, and I notice it in other places as well.

There is a lot to be said for finding joy in solving the problem rather than finding joy in the tools used in solving the problem. As I get further in my career, I keep trending toward the first one.

Precise types

Hang on, but you just said...

I like types. They are quite useful. For example, at the borders of a system to define data between systems. So I was put off by the idea of going to a completely dynamic language. Then in my research I ran across a fascinating article called Typed Lisp, A Primer. I am not very familiar with Lisp, so some of it went over my head. But the main message I received was that types in Lisp are just functions which check qualities about the data.

That means I can opt into types. It also means that types can be far more precise than what we get with statically typed languages. For example, I can define a type that is not just an integer, but an integer in a specific range. And I can require incoming data to conform to that by declaration.

So I still get to have types where I want them and in a more precise form. And I can have dynamism where it benefits me.

Clojure's typing library is called Spec.

Conclusion

The laws of the universe dictate that there is no perfect tool, so I am confident that I will discover trade-offs in my journey through Clojure. But I find it incredibly useful to see problems from different perspectives. And I expect that learning Clojure will add some new lenses for me to look through.

I'll try to keep you posted on what I learn.

Top comments (7)

Collapse
 
ysangkok profile image
Janus Troelsen

At least in Python, I find that the "opt-in to types" model doesn't work well. For example, libraries like Mongoengine are so dynamic that the returned type effectively depends on a dict. Dicts can be too (TypedDict), sure, but it doesn't happen in practise.

So why not do it the other way around? Haskell has Data.Dynamic.

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

Thanks for the comment and suggestion.

I believe Clojure's coding model is rather different than python's and can manage opt-in typing pretty well, from what I have seen. (We shall see.) It also resonates with what I do in F#. F# is statically typed but as with most languages, types match the underlying machine, not precise enough to exactly match the parameters of specific use cases. So I filter all requests through an extra validation function before proceeding, similar to Clojure's approach to typing.

The other alternative is to create a wrapping type to represent the more specific version of data, and have that type's constructor block creation unless data matches constraints. However, I find that approach to have a lot of overhead in dealing with the wrapping type. So I do not use it.

Regarding Haskell. Even if I use dynamic myself, it seems unlikely (from some prior research) that libraries I want to use will. Plus it seems to be common for some of the major libraries and samples to code on top of category theory abstractions. So any new person I bring on must first back-fill theoretical math knowledge before they can do meaningful work. (And memorize whatever custom operators the library chose to use.) I am all for them learning the math if they want, but it feels too much to require as a first step. (Last few hires had no prior experience, and we like it that way.)

Collapse
 
slifin profile image
Adrian Smith

Spec for information modelling, clj-kondo for static analysis (which recognises Java's type hints)

Most people forget there is a Java type system there in Clojure that can be checked statically for mistakes

Regarding information modelling, information is more dynamic than most people realize:

"If your program deals with information, these are among your primary problems: information is sparse,
incrementally accumulated, open/ extensible, conditionally available, formed into arbitrary sets in
different contexts, merged with other information etc"

Which is why we need something more flexible than sum/union/maybe types for specification, spec 2 should hopefully be a very good system for this

youtube.com/watch?v=vK1DazRK_a0

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

Great video, by the way. Love the comparisons of jQuery and React, and the evolution of state in React. Lots of good stuff in there.

Collapse
 
cappe987 profile image
Casper

Interesting article. I too am a huge fan of types and static typechecking. I dislike Python and JS for that reason. But Clojure has really piqued my interest. I haven't tried it yet and I still have my doubts regarding the dynamic nature of it. I will probably try it once I have time, I'm somewhat looking forward to it.

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

This talk has a pretty compelling explanation about types with spec. The link starts 9 minutes in where he begins to address typing. Quick background: he explains "systemic generality" earlier in the video. But it is basically instead of specific types, in Clojure you use maps (dictionaries with named keys) and vectors (lists) for everything.

Collapse
 
johnkazer profile image
John Kazer

I've started with clojurescript and loving it. Just wish had more time to really test it out with a serious app.