This is my Lisp environment.

This is my lisp environment. There are many like it, but this one is mine.@val314159

    Lately, I've been getting back into Lisp for various reasons. Maybe I'll go into the details in another post, but I'm tired of Python, C++, and anything involving Java (scala!). Javascript too, to a lesser extent.

Is lisp great or terrible?

    Can it be both at once? I posit that it can.

Lisp is great

    I won't fill up this space with an explanation of why Lisp is amazing and beautiful, mostly because that's been done so many times at this point. I long for the macro world, and the creation of my own logical devices. I want to receive the trust that system is mine to screw up (if i so dare), and I want to extend that trust to any users of any software I publish.

    Since I agree, there's not much point here. Since you're here reading this, you probably concur.

Lisp is terrible

Let's not curse the darkness, but instead light the lamp of understanding.

    In all fairness, there's probably as much material complaining about lisp on the web as there is praising it. Some are right, some are wrong, others merely misguided.

    But where do we go from here? Can we uncover these dusty gems of history and determine which spells are still magical in the now, and those that belong better tucked in the back of the dustbin?

Some initial observations:

  • Lisp is very old. So very, very old
  • Some things that were once high-level and slow are now low-level and fast.
  • a lot of the "weird" parts have been adopted by other languages.
  • computers in general, and programming in particular, have changed a great deal
  • Common Lisp has remained mostly the same since the 80s.

    It has been decades since "dynamic languages" took over (i.e. the late 90s/early 00s) and yet we STILL DON'T HAVE THE FULL POWER OF LISP.

    Python ain't it. Java's not it. C++, it's not you. Perl, I gave up on you in 2001.

    I've been working with computers for a long time now, and it feels that somewhere around 2005(?) that development got slower and harder, and less fun in general.

    Where's the fun? Can we make lisp fun again?

Let's fix it

    I certainly am not the first, and I won't be the last to say "we need to bring lisp into the modern world." There have been many intrepid explorers on this path, and a real danger is that we throw the baby out with the bathwater. We want to improve lisp, but we don't want to "break" lisp.

    Its been oft-said that lisp is more than a language, it's a language for DSL (Domain Specific Languages). So by developing features, we alter the personality of the language. Python has this same notion. If something is deemed "pythonic", all is well and good with the world. The typical python programmer will be able to use this library with "expected results". After all, surprise is the enemy of determinism.

    So when we add features, we need to be extra careful to be "lispy".

    ... To Be Continued ...


Standard Disclaimer: This is not the only way to do it. It's just the simplest, for me anyway.

    We want just three things to get going:

  • Lisp environment - to execute programs in
  • Quicklisp - the most popular package manager
  • Text editor - to edit the source code
Install SBCL

  • OSX: (using brew)
brew install sbcl  
  • Linux/Debian:
apt-get -y upgrade  
apt-get -y install sbcl  
  • Linux/CentOS:
sudo rpm -Uvh sbcl-1.2.9-1.el7.centos.x86_64.rpm  
Install Quicklisp

    Quicklisp is the de facto package manager for Common Lisp. It serves the same role as PyPi for python, npm for Javascript, Gems for ruby.

curl -O  
sbcl --load quicklisp.lisp --eval '(quicklisp-quickstart:install)' --eval '(let ((ql-util::*do-not-prompt* t))(ql:add-to-init-file))' --quit  
Install your favorite text editor

    Use your favorite editor. It doesn't have to be emacs.

    I use emacs every single day and even I won't tell you to learn it to learn lisp. That's just too much of a learning curve.

  • I am not sure that emacs is the perfect environment for lisping these days.

  • Emacs lisp isn't common lisp, it's diverged significantly. (Newer versions have converged a little, but not enough)

  • SLIME doesn't feel natural to me. Maybe I don't know what I'm missing.

  • There is a newer package SLY that is an update to SLIME.

    • The author states flat-out that SLIME has bitrot.
    • The author has made a number of improvements, it does feel nicer.
    • Still doesn't reach the "natural" level to me.
    • But you need SLIME for the ultimate lisp machine
  • If someone says "you must use Emacs", that person is wrong. Use whatever editor you're comfortable with. "But you need SLIME"

There is (was?) this platonic ideal of a lisp machine where you start out with a square block of marble, and you customize it into your perfect program. the state of the system is the state of memory. it is the responsibility of the environment to save/load this machine state to a non-ephemeral location (disk!)

This is the very definition of a monolithic architecture.

Modern software development cares a lot more about reproducibility. As such, as a project grows in complexity, it tries to split up large projects into sub-project and libraries in order to ease understanding. The crux of this is that now the files on disk provide the ultimate truth.

Write your first script

Here's your first script:


#| -*- lisp -*-
exec sbcl --script $0 $* # |#  
(format t "Hello, world!~%")

You can create this with your editor, or in a pinch, just clip this text:

cat >myscript.lisp <<EOF  
#| -*- lisp -*-
exec sbcl --script \$0 \$* # |#  
(format t "Hello, world!~%")

chmod +x myscript.lisp  

To run, simple do:


Here's the order of execution:

  • The script gets loaded by the shell

  • The script looks at the start of the first line to determine what type of file this is

  • Unless the first line starts with "#!" or a magic number, it's a shell script.

  • As a shell script, we get evaluated line by line.

  • The first line starts with a #, so it's a comment. skip it.

  • The second line starts with "exec" so it will never return.

  • The second line ignores everything after the first # as a comment.

  • "exec sbcl --script $0 $*" gets expanded into a new command that passes its arguments to a script with the name of $0 (the actual filename)

  • since we start with exec, the shell process actually becomes the sbcl process thus never proceeds past this point.

  • sbcl starts up and loads the filename as a script, receiving all the arguments given to the original process.

  • lisp reads the first two lines as a valid lisp comment (since they are).

  • the rest of the file is also valid lisp.

  • Keep on rolling!

This is a very sbcl-oriented way of looking at the world, but you should be able to use this recipe to use almost any lisp.

    ... To Be Continued ...