Setting up Lisp

A Lisp logo
  1. Basic steps
  2. Use Quickproject
  3. Efficient command line Lisp scripting
  4. Connecting to a Remote Lisp via Swank
  5. Launching an SBCL core dump as a daemon
  6. Lisp Links
  7. Lisp Articles
  8. Basic steps

    Bootstrap SBCL

    Install SBCL that comes with distribution. This will be used to build latest version. For Ubuntu this is

    sudo apt-get install sbcl

    Quicklisp

    Now days I'm using Zach Beane's Quicklisp. Definitely the easiest way to keep packages up to date:

    mkdir quicklisp && cd quicklisp
    curl -O http://beta.quicklisp.org/quicklisp.lisp

    Start up sbcl and load quicklisp. Then:

    (quicklisp-quickstart:install)
    (ql:add-to-init-file)

    Use it to load some packages:

    (ql:quickload "ieee-floats") 
    (ql:quickload '("cl-ppcre" "cl-who" "hunchentoot" "drakma" "uffi")) 

    Create the following filepath:

    mkdir -p ~/.config/common-lisp/source-registry.conf.d
    nano ~/.config/common-lisp/source-registry.conf.d/projects.conf

    and paste the following line into it:

    (:tree (:home "src/lisp"))

    This is where my own Lisp sources generally live. This is read automatically on starting SBCL. Run this in sbcl to include it in current environment:

    (asdf:initialize-source-registry)

    Note: when a package export list gets screwed up the best way to fix it is call delete-package.

    Slime

    Load Slime from quicklisp:

    (ql:quickload "quicklisp-slime-helper")

    Add to .emacs:

    (load (expand-file-name "~/quicklisp/slime-helper.el"))
    (require 'slime)
    (setq inhibit-splash-screen t)
    (setq inferior-lisp-program "/usr/local/bin/sbcl")
    (slime-setup '(slime-fancy slime-tramp slime-asdf))
    (slime-require :swank-listener-hooks)
    

    Add to .sbclrc with the following

    ;;; Use this to enable shebang style scripts like this:
    ;;; 
    ;; #!/usr/bin/sbcl --noinform
    ;; (write-line :Hello, World:)
    ;; 
    ;;; If the first user-processable command-line argument is a filename,
    ;;; disable the debugger, load the file handling shebang-line and quit.
     (let ((script (and (second *posix-argv*)
                        (probe-file (second *posix-argv*)))))
       (when script
        ;; Handle shebang-line              ;
         (set-dispatch-macro-character ## #!
                                       (lambda (stream char arg)
                                         (declare (ignore char arg))
                                         (read-line stream)))
        ;; Disable debugger                 ;
         (setf *invoke-debugger-hook*
               (lambda (condition hook)
                 (declare (ignore hook))
    	    ;; Uncomment to get backtraces on errors ;
    	    ;; (sb-debug:backtrace 20)      ;
                 (format *error-output* :Error: ~A~%: condition)
                 (quit)))
        ;; Load the script file and quit    ;
         (load script)
         (quit)))

    Try the new sbcl. Then start emacs and try slime. Everything should work.

    Notes:

    • Might also need fortran for cl-blapack. sudo aptitude search fortran to find the latest version.
      sudo aptitude install libblas-dev liblapack-dev
    • If using a 64-bit Linux, this might be a backport, so set up the link in /usr/lib/ by hand:
      cd /usr/lib
      sudo ln -s i386-linux-gnu/libgfortran.so.3 .
    • Now I can load org.middleangle.cl-blapack which is needed for lisp-matrix (along with ffa, etc).
      (ql:quickload "org.middleangle.cl-blapack")
      (ql:quickload "lisp-matrix" 
    • If buildling a hunchentoot project on this machine, make sure the reference to swank is accurate:
      (load (merge-pathnames
         "quicklisp/dists/quicklisp/software/slime-20110829-cvs/swank-loader.lisp"
        (user-homedir-pathname)))

    Use Quickproject

    Zach Beane's Quickproject is an easy way to create basic project templates as /.asd, /.lisp and /README files.

    (ql:quickload "quickproject")
    (quickproject:make-project #p"src/lisp/project-name/" :depends-on '(cl cl-ppcre) 

    Efficient command line Lisp scripting

    I got this from Teemu Likonen off the sbcl-help list. The idea is to build a special sbcl core which is stripped of startup junk and use it run your scripts. You can pre-load commonly used libraries into the binary so it doesn't waste time loading them. Here is a simple one:

    sbcl --noinform
    * (require :asdf)
    * (require :local-time)
    * (sb-ext:save-lisp-and-die "sbcl-script" :executable t)
    

    Then write scripts as follows (assuming the core is located /usr/local/bin/sbcl-script:

    #!/usr/local/bin/sbcl-script --script
      (format t "Local time is now ~a~%" (local-time:now))
    

    Connecting to a Remote Lisp via Swank

    Connecting to a local lisp which has swank running is easy: in emacs start "M-x slime-connect". The same thing can be done to connect to a remote lisp via ssh. In one xterm start an ssh session:

    ssh -L4007:127.0.0.1:4005 $inervo

    But don't use it directly. In another local xterm start emacs and remote connect using:

    M-x slime-connect RET 4007

    This maps the local port 4007 to the remote port 4005. Now from a local emacs, launch slime with

    Launching an SBCL core dump as a daemon

    After saving a core dump that is self-starting (i.e. built so it launches the desired start-up function) you can launch it as a daemon using something like this script:

    #!/bin/sh
    # Define environment variables needed by cron
    HOME=/home/jcunningham
    DIR=${HOME}/jcunningham/website
    PATH=${HOME}/bin:${HOME}/usr/local/bin:${HOME}/usr/bin:/usr/local/bin:/usr/bin:
    MAILTO=jcunningham@achilles.olympus.net
    
    cd $DIR
    
    # launch with nohup ./http.sh &
    
    RUNNING=`/bin/ps -A | /bin/grep parceletti.core`
    if [[ ! $RUNNING ]]; then 
    #   $DIR/parceletti.core 1>> $DIR/http.out 2>> $DIR/http.err
     nohup $DIR/parceletti.core &
    fi

    Lisp Articles

    (Sort of a to-do read list.)

    1. Advanced Functional Programming in Lisp