My Winding Lisp Journey

Switching programming languages is like switching socks for me. I do it almost every day. This is my double edged sword of programming. On one hand I am fairly adaptable to new tech stacks. On the other hand I am master of none. One common thread of switching around a lot has been Lisp. I feel like it is the best syntax for functional programming style. It is concise yet powerful. A lot of people screech in horror when they see Lisp. I think it is a matter of perspective and ensuring you have rainbow parantheses turned on. Lisp to me has a retrofuture aesthetic that keeps drawing me back in. Lisp is borderline ancient technology from the 40's. Yet its simplicity in scope allows it to be constantly reinvented.

Clojure

My Lisp journey started with Clojure. This was fairly early on in my programming career. My sophomore year of college I learned how to program in Java using Processing. Processing is simultaneously an IDE and a library to easily make graphical programs. Eventually I stumbled upon Quil and some of Sam Aaron's other work. Such as using overtone with emacs and supercollider. I was blown away with how he could use code to make live music. If he could make live music with that workflow think of what I could with my own coding? So this got to start using emacs and I had a lot of fun making visualizations that I could get immediate feedback on.

This was my initial introduction to ideas of Functional Programming as well. Devouring Rich Hickey's talks, I became a quick convert. State is the root of program complexity. By limiting it, you make your life easier.

The other thing about Clojure was that it was very data oriented. To this day I think Lisp is the superior functional programming style.

As it turns out, Clojure was an interesting first dive into Lisp. It builds on decades of experience with other Lisp languages and has a lot of opinions of its own. It still has one of my favorite syntaxes. However, syntax isn't everything to me anymore. Eventually I fell out of love with the JVM, and I had accepted that Python was the hegemonic data analytics tool. When Clojure initially came out this had not been set in stone. Oh, and I also stopped doing as much data analytics.

Instead of coding Clojure, I was coding a lot of Java. The tooling was complex, I questioned the reliance on emacs, because it added another gate to get started. boot or leiningen??? It's funny how this was my main priorities.

I did go to a Clojure Conj which was a lot of fun and I got to meet a lot of cool people. Ironically this was right when I had stopped using Clojure.

Guile and Emacs Reborn

For a while, I put away my parantheses. No Lisp, no Emacs. This changed after I got back into emacs when I wasn't satisfied with VSCode. I felt that VSCode did too much when I didn't want it to. I would rather configure emacs lisp than JSON. I started learning more about the Free Software movement and I heard about Guile.

For whatever reason Guile peeked my interest. This was my introduction to Scheme. My initial impressions were that it felt old school and I missed Clojure syntax. What I found interesting, but sometimes irritating, was that it isn't too far removed from Lisp proper. It uses car, cdr, and everything is a linked list. Whereas Clojure mixes it up with vectors and maps from time to time. Scheme captures that simple essence of the Lisp idea in ways that I've come to appreciate a lot. I made a little script that I could use for generating invoices as a freelancer. It read in some JSON and output a nice looking PDF. It was basically a step up from a bash script.

Soon I realized there wasn't really a dedicated package manager for Guile. What I've learned is that the Guile ecosystem mostly revolves around Guix. For good reason. And I find the reasoning for having all packages in the OS package manager persuasive. Stillm it was quite a stretch for me and quickly became inconvenienent. Eventually, I rewrote the script in ruby to be easier to maintain and didn't have any dependencies with Gems. The parantheses were put a while for a while. Off to some other things.

Chicken Scheme

I read Brian Kernighan's UNIX book. It inspired me to start learning C more seriously. One of the first things I made was a simple text editor. I came to the realization that I wanted an extension language like how emacs works. Guile seemed like a natural choice. However, I decided to see what else was out there in the greater Scheme world.

Chicken caught my eye. What a funny name, I loved how they called the packages eggs. Also, what was this about compiling to C? Hmmm, must be decently fast. And it is.

I was messing around with making the text editor but eventually got sidetracked. Part of this side track was that I wanted to start my own blog. I needed a blog engine. It is like a rite of passage for a programmer to make their own blog engine. It can't be that hard right? Famous last words and a few months go by with a fully featured blog engine and no blog posts to show. Once I completed this project I took a break from Chicken for a bit. I was busy with work stuff at the time, and needed to focus on that.

Despite liking Chicken, there were some things I wasn't exactly happy about. Debian was still on Chicken 4 andt became a source of frustration. Chicken 5 hadn't been out that long and it seemed the ecosystem had some catching up to do.

I put down the parantheses once more.

Janet

Then Janet came along and got me excited about Lisp's again. Finally, what I wanted. Scheme but with Clojure syntax. I made a few applications with it.

At this point, I thought I found the Lisp I was going to get behind.

It felt very natural coming from my Clojure background. Unfortunately, it isn't a very faithful port. It has some syntax quirks that I don't agree with. It also has weird mutable behavior for some functions/data structures without the ! on the function name. This leads to a frustrating debugging experience where core functions aren't doing what you thought they were supposed to.

Similarly, to the blog engine in Chicken. Once I finished the project I was using it for, I took a break from it. Parantheses put down once again. Most likely, I will come back to Janet. For now, I'm happy being back with my quirky yet predictable Chicken Scheme.

Back to Chicken Scheme

Randomly, I had a sudden urge to program in Chicken Scheme. I cant give a good reason why. It was a feeling, an aesthetic reason. Sometimes the branding around a techology will really speak to me. Chicken is one of those.

At the same time I wanted to do something with Gemini, the resulting project is called geminegg. I'll be following up the release of that with a blog post most likely.

There is something about quirky languages that captures my attention. I can't help it. I love the feeling of riding the line between goofing around and actual producitivity. Chicken Scheme lets me do that.

I don't think there are any professional Chicken Scheme developers in the world. As in getting paid full time to work on Chicken Scheme. There aren't many people getting paid full time to do Lisp in general. It really is this weird subculture. Where the converts constantly praise how much better you will be and yet also can't help but carry out holy war level of infighting with other Scheme dialects. Yet, for this very reason, Lisp has persisted and thrived for a while. More specifically, Chicken Scheme has been around for 20 years and it all hobbyist run. I think that says something. Something about the language that makes developers come for more.

Honestly, I've found myself coding in Chicken for hours. Usually, I will start and stop much more with other programming languages. I love how I can implement a feature in usually less than 10 lines of code.

The language has a lot of modern conveniences, and yet it keeps around some retro ideas. Most of the development and sharing is done via mailing list. Some of the packages are still in Subversion. I recently had the pleasure interacting with both of these when I submitted a patch to a Subversion repo via the mailing list.

The fact that Chicken Scheme code can be compiled or interpreted I find to be really cool, and actually sometimes very useful. In my array of different programming languages I would place Chicken Scheme somewhere between Python and Go for use cases. Despite that Chicken Scheme is typically just compared to other Schemes of Lisps.

Galaxy Brain?

I can't tell if I've become more agnostic or more opinionated. Nowadays, I try to always pick the right tool for the job. Luckily, a decently fast Lisp is usually the right tool for the job. I still am in awe on little LOC's I can implement something as opposed to other languages. When I use other languages I see the lisp influence. Usually., I just want to use Lisp anyways. This post was an attempt to document how my tastes have changed. My outlook on programming in general has changed, and so have which languages I feel like are suitable.

To say that I always have rational choices for why I do things would be a lie. A lot of the time I can't shake a feeling, like I said earlier, an aesthetic feeling. The tool calls to me and I have to answer. So far on my winding journey these parantheses have kept me good company.

P.S - I can't believe I went through a whole blog post about Lisp without mentioning the REPL. I guess it isn't as big of a deal to me. Almost every language has one nowadays.

More Posts