6 ms·
When I discovered lisp several years ago, it was indeed the textbook moment of enlightenment that you've heard about. This book was a part of that introduction
by hellofunk 9y ago
When I discovered lisp several years ago, it was indeed the textbook moment of enlightenment that you'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!)
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've learned does indeed translate to how I work in other languages (even C++, which I also love).
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.
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've written, the verbosity of naming is a clear influence from lisp. And it is an improvement.
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.
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'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.
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've learned that the fence is an awkward place to sit.
- default-kramer 9y agoMy first go at lisp was working through SICP. I loved it. But I couldn't see myself using it for a medium-sized project just because static typing is that valuable to me. Now I'm learning Racket, and Typed Racket feels great so far (despite a few awkward spots). You don't have to sit on that fence; you can switch between typed and untyped code at will.
- flavio81 9y ago>But I couldn't see myself using it for a medium-sized project just because static typing is that valuable to me. See my comment above, you can have static-typing in Lisp with no problem: Type declarations are part of the Common Lisp standard[1], and implementations like SBCL (one of the best Lisp implementations out there, and free) will do static type checking. [1] type declarations: http://clhs.lisp.se/Body/d_type.htm http://clhs.lisp.se/Body/d_type.htm "the" (type specifier for return values): http://clhs.lisp.se/Body/s_the.htm#the http://clhs.lisp.se/Body/s_the.htm#the EDIT: a good example here: https://news.ycombinator.com/item?id=8598149 https://news.ycombinator.com/item?id=8598149
- hellofunk 9y agoAs with my comment about typed racket, I can't really use common lisp in my work, however clojure is very portable and I can use it (as clojurescript) as a first class language on iOS, and Mac, and the web.
- hellofunk 9y agoI would love to use typed racket, but I cannot really use it in the environments I program for, which are largely commercial apps on Apple platforms and mobile. If I could, I would jump to it in a heartbeat.
- flavio81 9y ago>Without type annotations and checked structured data for everything I guess this problem you mention must be Clojure-specific, because in Common Lisp you can declare the data types of the input parameters and all return parameters, and have the compiler (i.e. SBCL) do static type checking; also the compiler can tell you which data types are accepted and returned by your function, by use of the "describe" function. Furthermore, you can define your own types, structs, and classes, and the declarations (and static type checks) will work with them as well.