Skip to content
Back to the collection

A history of Clojure

Rich Hickey

2020 · Proceedings of the ACM on Programming Languages

Read the paper
HN score
0
Mentions
8
Readers
7
Months
8
What’s in a score?

From the abstract

Clojure was designed to be a general-purpose, practical functional language, suitable for use by professionals wherever its host language, e.g., Java, would be. Initially designed in 2005 and released in 2007, Clojure is a dialect of Lisp, but is not a direct descendant of any prior Lisp. It complements programming with pure functions of immutable data with concurrency-safe state management constructs that support writing correct multithreaded programs without the complexity of mutex locks. Clojure is intentionally hosted, in that it compiles to and runs on the runtime of another language, such as the JVM. This is more than an implementation strategy; numerous features ensure that programs written in Clojure can leverage and interoperate with the libraries of the host language directly and efficiently. In spite of combining two (at the time) rather unpopular ideas, functional programming and Lisp, Clojure has since seen adoption in industries as diverse as finance, climate science, retail, databases, analytics, publishing, healthcare, advertising and genomics, and by consultancies and startups worldwide, much to the career-altering surprise of its author. Most of the ideas in Clojure were not novel, but their combination puts Clojure in a unique spot in language design (functional, hosted, Lisp). This paper recounts the motivation behind the initial development of Clojure and the rationale for various design decisions and language constructs. It then covers its evolution subsequent to release and adoption.

Metadata: Crossref. Abstracts retain their original authors’ rights.

In the conversation

Original HN comments, with labels from simple text rules. A label describes the whole comment and may miss context or irony. Read the discussion to make up your own mind. About the labels

8 selected excerpts · 8 total mentions

raspasov
Neutral mention · rule
> first-class maps, vectors, arrays, sets, counters, and more That's my mistake; this line was intended to be a sub-bullet point of the previous line regarding CRDTs. > the language already allows you to have protocols everywhere The core data structures, for example, are not based on protocols; they are implemented in pure Java. One reason is that the 1.0 version of the language lacked protocols. All that being said, it remains an open question what the full implications of the protocol-first idea are. > You can write your code using transducers or opt in for laziness in Clojure now. So it's a matter of choice of tools, rather than a feature of the language. You 100%…
Read the full comment
can. Unfortunately, many people don't. The first thing people learn is (map inc [1 2 3]), which produces a lazy sequence. Clojure would never change this behavior, as the authors value backward compatibility almost above everything else, and rightly so. A transducer-first approach would be a world where (map inc [1 2 3]) produces the vector [2 3 4] by default, for example. This was mentioned by Rich Hickey himself in his "A History of Clojure" paper: https://clojure.org/about/history https://dl.acm.org/doi/pdf/10.1145/3386321 (from paper) > "Clojure is an exercise in tool building and nothing more. I do wish I had thought of some things in a different order, especially transducers. I also wish I had thought of protocols sooner, so that more of Clojure’s abstractions could have been built atop them rather than Java interfaces."
Shoop
Neutral mention · rule
> I suspect this is the real reason Clojure was created, I bet Rich was just really bored. Rich has written about the history and motivation behind Clojure here: https://dl.acm.org/doi/pdf/10.1145/3386321
eduction
Neutral mention · rule
That’s incorrect. Only refs+dosync use stm. https://clojure.org/reference/refs Not atoms. From Hickey’s History of Clojure paper: “ Taking on the design and implementation of an STM was a lot to add atop designing a programming language. In practice, the STM is rarely needed or used. It is quite common for Clojure programs to use only atoms for state, and even then only one or a handful of atoms in an entire program. But when a program needs coordinated state it really needs it, and without the STM I did not think Clojure would be fully practical.” https://dl.acm.org/doi/pdf/10.1145/3386321 Atoms do an atomic compare and swap. It’s not the same thing.
tastyminerals2
Neutral mention · rule
I have to admit, several years ago, a colleague of mine advised me if not to try Clojure but at least to read the "History of Clojure": https://dl.acm.org/doi/pdf/10.1145/3386321, which I never did. But one day I decided to watch Rich Hickey - Greatest Hits https://changelog.com/posts/rich-hickeys-greatest-hits... I then read the "History of Clojure", and then jumped into learning it. This is probably one of the most fun languages to build with and one of the most beautiful ones. If not syntax-wise, rather in a way it allows you to express your thoughts via good design and composition that so nicely tickles your brain. If you are still searching for that one shiny tool, and none of them clicks, maybe try Clojure. It's one of the most concise and yet powerful languages I've seen.
mamcx
Neutral mention · rule
I don't like lisp, not code in lisp; not even a line.. and I have read TONS of lisp stuff. Why? The #1 reason: The lisp people have a lot of cool things to teach. One of the most obvious examples: https://www.infoq.com/presentations/Simple-Made-Easy/ So, you can learn enough of Lisp or APL or oCalm or Haskell to tag along with somebody smart on the field (that use certain lang, maybe for very good reasons, maybe is just what he like) and understand stuff. Most of the real gems are kind of easy to learn with the most basic understanding of a language. --- A lot of times, is THAT kind of people that have the better insights of why certain lang matter. Continue with the…
Read the full comment
example of Rich Hickey: https://dl.acm.org/doi/abs/10.1145/3386321 --- You can translate a lot of ideas from a lang to other, as the most basic and simply benefits. Is just the case that certain langs fit the minds/goals/niches better, so is there where to look for better answers...
eduction
Neutral mention · rule
I see your overall point which is a good one and I know this is a nitpick, but I thought Rich’s core solution to the cost of immutable data structures was to find a way to get the cost down by extending some existing research by Phil Bagwell. From https://dl.acm.org/doi/pdf/10.1145/3386321 “I then set out to find a treelike implementation for hash maps which would be amenable to the path-copying with structural sharing approach for persistence. I found what I wanted in hash array mapped tries (HAMTs) [Bagwell 2001]. I built (in Java) a persistent implementation of HAMTs with branching factor of 32, using Java’s fast System.arrayCopy during path copying. The node arrays…
Read the full comment
are freshly allocated and imperatively manipulated during node construction, and never mutated afterwards. Thus the implementation is not purely functional but the resulting data structures are immutable after construction. I designed and built persistent vectors on similar 32-way branching trees, with the path copying strategy. Performance was excellent, more akin to O(1) than the theoretical bounds of O(logN). This was the breakthrough moment for Clojure. Only after this did I feel like Clojure could be practical, and I moved forward with enthusiasm to release it later that year (2007).” Or you tell me what I’m missing. Big fan of your work in core.async if this is the same hangari.

Keep following the thread.

More in Programming languages

More from the same topics.

2017arXiv

The Case for Learned Index Structures

Tim Kraska, Alex Beutel, Ed H. Chi +2

Indexes are models: a B-Tree-Index can be seen as a model to map a key to the position of a record within a sorted array, a Hash-Index as a model to map a key to a position of a record within an unsorted array, and a BitMap-Index as a model to indicate if a data record exists or not.

19 mentions14 months
5HN score