Thoughts on learning lisp in 2019

Yvan Scher
Nov 2 · 8 min read
Working in his study.

It’s been a few months since I wrote a blog and I wanted to provide an update on what I’m doing. More blogs will come, just in the near future — got a couple drafts floating around.

Working on financial technology at Aiconic

I started a company called aiconic with a longtime friend/colleague from the university of amsterdam (we have a combined background in computer science, math, finance/economics). We build software to help financial institutions solve their problems. I think we’re building up a very fun team here with a varied (but focused) skillset. If you are interested check us out: https://www.aiconic.com/ — we are looking to hire. We have a solid appreciation for lisp and anyone who applies with some background or experience in lisp gets a bit of extra consideration.

Learning assembly, again

In college I did the binary bomb assignment (which i guess you can just do online now?) many computer science majors are familiar with. Since then I haven’t really touched assembly much. I read a book called programming from the ground up by jonathan bartlett. Programming assembly on i386 (centos 6, 32 bit docker image) was really nice. I recommend this book for people who have never programmed before or are just getting into it. Assembly is not complicated and I think it is important for new programmers to understand the foundations of computers, love working with computers and know that what they are using is just a tool like a sheet of paper, an abacus, or a screwdriver (not a magic box).

To run this image:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it --name=dockerasm -v ~/asm1:/root/asm1 -p 5000:80 $CONTAINER_NAME

Reading

Hackers & Painters is a great book; everyone who is interested in the underlying trends of technology should read it. Paul Graham is a great writer — programmer. Reading about lisp and googling stuff like “who is using common lisp” and “what do people think about arc” you get a lot of feedback on what people think about paul graham. He’s at least worth skimming and has clearly thought a lot about many interesting topics. I’ve learned a lot from reading this book and even claims I don’t agree with are really thought provoking.

Other books I’ve been reading: game of thrones, how google works, history of money, elon musk bio, meditations by marcus aurelius, intro to mathematical thinking, infantry attacks, high growth handbook, the martian chronicles, the wizard of menlo park, dune messiah, big debt crises

Learning lisp

Lisp seems very poorly understood (see thread). People give many reasons for why lisp isn’t popular. My thought is that lisp is harder to learn than most other languages. Lisp is essentially just an abstract syntax tree (AST). ASTs are great because they allow you to think of your program in pure, abstract building blocks; this allows a certain “hygiene of thought” that other languages lack. At the same time programming in tree syntax is much harder, it requires recursive thought by default and humans do not naturally think recursively. When I picked up a kindle I started to read a lot more again. Lisp kind of feels like a kindle for programming — picking it up makes me want to program a lot more. I’m shocked that we didn’t learn a bit of it in school. Maybe I should have gone to MIT — oh never mind SICP is taught in python now.

Learning Clojure

I’ve wanted to learn lisp for a while and after a weird experience with clisp (basically i downloaded it thinking it was common lisp — and it’s not really common lisp) I decided to learn clojure, the “premier” lisp variant.

What I like:

1 — The language feels clear compared to other languages and compared to common lisp (cl). For a comparison of clojure to common lisp see part ~26:00 of simple made easy on parentheses overloading. Clojure compared to other languages: the prefix notation of function calls means there is no “order of operations” in clojure. Often in many infix languages you need to figure out what order different operators are applied and often any non trivial code with lots of these needs a bunch of parentheses to work right/safely anyways (x == 1 / 3 + 7 * 5 — makes me nervous). In clojure you will never have to check again and you will know exactly what your code does: (= x (+ (\ 1 3) (* 7 5))).

2 — The JVM is powerful and actively developed by a lot of very smart people who specialized in compiler development. As much as I hate to admit it, java interoperability puts clojure right in the heart of many enterprise systems. Java and its ecosystem are very much alive in the corporate world. Just saying “it runs on jvm” saves days, weeks, or months of discussion with concerned customers. clojure is compiled to bytecode, even on the REPL.

3 — It has a really awesome community making high quality content, guides, libraries, and apps. There is a book called clojure programming which I found very good. They explain not only how to program in clojure but important concepts that determine why it is different from other languages and the benefits of those differences. I read parts of a few other books (practical common lisp, ansi common lisp, brave clojure) — clojure programming which I’ve recommended above was in my opinion the best.

What i do not like:

1 — Stack traces from the JVM look like 100–200 lines of useless trash. the error messages are really uninformative and as a beginner you might expect to spend like 2–3 hours debugging one when really it should take 2–3 minutes. I really did not enjoy this.

2 — Java interop/library support is really seamless but the downside of this is that every once in a while some sexpr you write spits out some kind of java object which seems to not work the way you expect. It really breaks my focus to have to debug this java bullshit while programming in lisp.

3 — Emacs is a pain, I cant even make the configurations in the braveclojure book work. It also has a steep learning curve with alot of commands. after some time trying to get it working I just decided use atom with a couple plugins: proto-repl, lisp-paredit, parinfer, rainbow-delimiters. they are super easy to install and the key bindings in paredit are intuitive for slurping/barfing stuff in and out of parentheses.

4 — Sometimes lein or proto repl breaks and throws weird errors (like that it can’t find the “create” function — what? how does one debug that? i had this exact problem) and it’s really frustrating. I’ve also tried alternatives like deps.edn but it doesn’t always work quite right. Supporting java interop is nice but it has added some significant complexity. This is a complicated diagram to have understand to just … import some stuff. This in my opinion makes it very unfriendly to beginners and a bit of a time waster in general. I’m sure as you encounter these issues and internalize knowledge about how to solve them you waste less time, still — it bothers me.

5 — The clojure ecosystem seems perfectly content to waste my time. For example if I want to profile my code in python I basically just import cProfile cProfile.run(“some_func()”). It “just works.” If I want to profile my code in clojure i need to figure out that the library i need is tufte (not clojure.contrib.profile — a library i cant figure out how to install/use, not timbre whose profiling is deprecated and moved into tufte), then i need to try to deal wit the fact that the example on tufte’s github doesn’t work. Even once I try it out in repl, the (p) wrapper for the profile returns nil….so…how the heck am I supposed to wrap different parts of my code whose results i need to keep? In a functional language this should be a question answered in basic example 1 — maybe I’m just a moron. In the end I just use (time) and my code takes a minute to run on a csv, my python implementation takes < 15 seconds for the exact same task. I cannot figure out why because I cannot profile the code. Sigh — bottom line: it doesn’t “just work.”

Clojure resources: 4clojure interactive problems, great talk by rich hickey, simple made easy, comparisons across lisps, amperity github, overview of clojure benefits

Learning common lisp

I decided to give a real common lisp implementation a roll as well and started working through ansi common lisp by paul graham. I downloaded sbcl, which is a stable, completely opensource for public or private profit, actively developed branch of common lisp (with releases in late 2019). It is easy to install and use. You can buy ansi common lisp; I suspect it is also available as a pdf online. Common lisp is a very mature, stable, and has a ton of libraries for doing stuff. The community has a bad reputation which is weird because alot of people I meet online seem great and very helpful. Programming in common lisp feels really fun; it feels more fun than programming clojure. The language just kinda flows and may be a a more manageable step into lisp for many programmers (instead of learning lisp + rigid functional programming in one go — just learn lisp). Another greate resource is the guide to the bel langauge. It’s not just a map covering details of bel but a nice and very straightforward explanation of many lisp concepts. Overall I think common lisp is good and I will likely be using it for some projects soon.

Useful resources for common lisp: simple lisp reference, fukamachi’s github, common lisp cookbook, companies using lisp, quicklisp install page, great discussion of CL and other lisps, incredible python — CL comparison, portacle: sbcl + emacs + quicklisp, shinmera’s github, lisp resources (lispnyc), writing modern lisp in 2017, why lisp macros are cool, vsevolod dyomkin’s site, vd’s blog, in production lisp at grammarly, history of lisps

What’s up next?

Read On Lisp by paul graham, a more advanced lisp text.

Do SICP in Racket scheme(as the gods intended). They even have a special version of racket for doing sicp that probably more closely matches the MIT Scheme language it was originally taught in. It is a beautiful language and comes to me recommended by friends I respect.

Read peter norvig’s (godfather of ai + respected lisp programmer) book called PAIP.

Mess around with arc. An unfinished lisp originally released in the 2000s and built on top of Racket.

Mess around with an implementation for bel. A recently released lisp by paul graham with implementation details unreleased.

Conclusion

Clojure: It’s a really cool language with a stable core — but there are some issues that make it difficult to get into and sometimes it feels hard to do what you want to do and slower than you would want it to be.

Common Lisp: CL is very fun to program with. It’s very stable and mature ecosystem. If you use sbcl + portacle getting started is basically 5 minutes. I definitely recommend common lisp as an entry point to lisp.

You can see my projects and hear updates about what is happening by subscribing to my (occasional) newsletter. Have a good day.

Yvan Scher

Written by

Computers

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade