Recommendations for Next-Level Clojure
Summary: There are many classics of functional programming that can help you take your thinking to the next level. My recommendations are for making you think in a new way.
You're able to write programs in Clojure and you've even finished a few projects. You feel like you've got a handle on the language. (Congratulations!) But you're stuck about where to go next. There don't seem to be many resources for upping your skill.
One great thing about Clojure and Lisps in general: it's not about the language. Yes, there's some detailed stuff you have to learn, like how to use the data structures, details of destructuring syntax, etc. Those are like your lego blocks. But once you've got that down, it's not about learning what language features you need for what problems. You've got your legos and it's up to you to put the legos together in new ways.
This is also the downside of Lisps. If you're not good at making new things with lego blocks, where do you turn to learn how to do it? Really, you study the masters and learn what they've done.
I know that it's hard to grow in non-mainstream languages. Mainstream languages have lots of books, lots of stylists, lots of exploration about how best to structure your code. For instance, you can read Design Patterns for an intermediate level Object Oriented Design perspective which will take you pretty far down the road to becoming an advanced OO programmer. Where are all of the functional programming books?
Well, they're out there. The functional programming path will depart from the merely practical. You won't learn how long to make your methods or how to name them. Some of the things you'll learn are not practical at all. But you will learn general truths and principles that help you see the world in a new way.
Here are some recommended books:
SICP teaches the fundamental abstraction capabilities of Lisp-like languages. It will teach you a framework for understanding the abstractions of other languages. And it teaches the difficult idea higher-order programming. That means programming with functions as arguments and return values.
By the end of the book: you'll have a new appreciation for the relationship between code and data. You will also learn the how and why of abstraction.
Common comment during reading: "My entire CS education was a waste."
If you're curious about how to design a Lisp, this book is amazing. Lisp, being one of the oldest high-level languages, has a long history. In that history, versions of Lisp have been written and rewritten so many times, by so many people, that the design space has been very well explored. This book doesn't give a historical perspective, but instead systematically walks through the different design decisions that you will face while implementing your own Lisp. It's mind-expanding stuff for those interested in language design.
By the end of the book: you will see the parts of any language as arbitrary choices and understand how they relate.
Common comment during reading: "Lisp is a field of study in itself."
This book is about the old style of artificial intelligence that wasn't statistical. Instead, it was about rule engines, logic, and pattern matching. It's a study in data-driven programming, which basically means bootstrapping a language (DSL?) inside of Lisp. For instance, at the end you write a small Prolog interpreter. You'll learn how to recognize problems that are complex enough to warrant building their own language to solve them.
By the end of the book: you'll know how to build DSLs that aren't merely for convenient syntax but instead give you new expressive power.
The oddest thing happens with this kind of knowledge. You can write a program to solve a problem with let's s ay 500 lines of code. Or you could write an interpreter for a language in 100 lines of code, then the solution to the problem in one or two more lines in your new language. Such is the power of linguistic abstraction.
Common comment during reading: "I could replace myself with a short interpreter."
4. On Lisp
Before Paul Graham started his startup incubator, he was a well-respected Lisp popularizer. On Lisp is the best book on macros that I've read. It's Common Lisp macros, but the principles are applicable to Clojure. This book goes well-beyond convenience macros that just provide better syntax. It dives into some fairly complex macros, my favorite being the delimited continuation macro, that are similar to how the go macro works in core.async.
By the end of this book: you'll be able to write such complex macros and won't want to use macros for mere syntactic sugar.
Common comment during reading: "I will never again write code in a language without macros."
I haven't actually read this, but I have been recommended it before.
I hesitate to recommend this book because functional programming has a reputation of being impractical, abstract, and mathematical. But the more experienced functional programmers I talk to, the more I realize that it is very common to master this kind of thinking. You won't want to implement them directly in your production code. But by putting your brain through the paces of solving these puzzles, you will have a better appreciation for the power of lambdas.
By the end of this book: you'll be able to develop systems of mostly small, composable higher-order functions.
Common comment during reading: "Where does the work happen?"
These are my recommendations. What are yours?