The Land of Lisp
When I discovered lisp several years ago, it was indeed the textbook moment of enlightenment that you&#x27;ve heard about. This book was a part of that introduction for me (along with Practical Common Lisp). After working in C-like languages, I had no idea that programming could work this way as in lisp, the idea of code and data being inseparable, I even had dreams at night about run-time data structures getting expressed as quoted lists! (I kid you not!)<p>It is now several years later and I have earned my living ever since by working in another lisp, Clojure. And I have indeed learned a lot along the way and what I&#x27;ve learned does indeed translate to how I work in other languages (even C++, which I also love).<p>However -- it is not all roses and nicely-flavored toothpaste after a savory feast. There is one aspect to lisp programming that, by virtue of its dynamic typing, I still find myself struggling to reconcile. No matter how much I marvel at what I can do in one or two lines of lisp, I do still often find myself making dumb mistakes that a compiler would catch instantly. Without type annotations and checked structured data for everything, it can also be hard to remember what a function does, or what its variables represent, when you read the code later.<p>One aspect of this that has made a big difference is naming -- how you name things in lisp and dynamic languages is a skill in its own right that helps guide the readability of code in the absence of types. When I look at C++ code I&#x27;ve written, the verbosity of naming is a clear influence from lisp. And it is an improvement.<p>The other feature that occurs more often is in-line documentation. It is a joy to read Clojure programs (the good ones, anyway) where every (non-trivial or meaningful) function has a little paragraph summarising what it does. This is just good in any language, but somewhat essential in a dynamic one.<p>Finally, run-time contracts and things like Clojure.spec come about to help fill the void of static typing. The problem I have there is that you add back into your code a fair amount of the verbosity that was removed in the first place by using a dynamic language (just look at Clojure.spec&#x27;s lengthy annotations for a function signature, and I find myself wondering... why god oh why?). At which point, I then wonder why not just go back to using a static language.<p>So using lisp taught me perhaps one final, frustrating lesson: there are just great things about both dynamically typed and statically typed languages, and I&#x27;ve learned that the fence is an awkward place to sit.