Skip to content

Wolfshead Software Blog

Some Random Programming Thoughts

Archive

Tag: Lisp

Woohoo! I just installed lispbuilder-sdl in about 3 minutes. Fantastic, I just need to remember to do:

(require :cffi)
(require :lispbuilder-sdl)

Plus I guess any other lispbuilder-sdl parts which we want to use.

More later.

I’ve used my Emacs+SBCL installation to process the  Reports from SIMS.net into Student and Teacher user names and profiles for the Moodle installation, plus creating the Courses and assigning both students and teachers to the correct courses. The process involved just shy of 7000 records so I was very happy that everything went so swimmingly. It took roughly a morning to do, most of which was spent massaging the csv files to have exactly the correct formats.

As a sideline I was also able to process the SIMS data to produce class-lists for all of the Maths Sets so that they could be uploaded to MyMaths, which took a grand total of about 2 hours. The main stumbling block being that I had the output file for the script set up as :if-exists :append instead of :if-exists :supersede which meant that no matter how I altered the script to correct it, all I could see was the incorrect initial lines. If I’d noticed earlier, it would have taken me approximately 30 minutes to do all in. Typical.

Tried last night to get my head round CL-PPCRE, the Common Lisp Regex library derived from a PERL library with a similar name. Unfortunately I just ended up going round in circles. I think I need to go back and look at Regexes in another language that I know, as the Common Lisp examples are somewhat sparse.

Yesterday I became increasingly frustrated trying to download and install a library to use with my SBCL installation, a socket library (usocket and another which I can’t remember) in fact. This started me on my quest to work out how packaging works in Common Lisp. Hence my previous posts on make-package and defpackage, although these seem more for my own projects. To install other peoples libraries, asdf-install (which seems to use asdf: another system definition facility) seems to be one way to go.

To install asdf first in SBCL, we need to add the following to our .sbclrc file (I had to create this on Debian Lenny in my home folder):

(require :asdf)

since asdf is incorporated in SBCL we don’t need to download or install anything else. We need to add a local folder to the list of possible sites to install libraries in, I created a .sbcl folder with a sub-folder called asdf-registry in it, then added:

(pushnew "/home/amos/.sbcl/asdf-registry/" asdf:*central-registry* :test #'equal)

to the .sbclrc file. However when I started using asdf-install it ignored this folder and created two new folders called site and systems respectively, and a file called trusted-uids.lisp.

I then added:

(require :asdf-install)

to my .sbclrc file, again as I’m using SBCL this is all that is needed. Restarting my lisp (I closed down emacs, restarted it, and restarted slime – there is probably an easier way to do this but I’m not sure what it is) made asdf and asdf-install be available.

To use asdf-install we can install a library by using one of:

(asdf-install:install :library-name)

(asdf-install:install "http://path.to/library.tar.gz")

(asdf-install:install "/path/to/locally/downloaded/file")

This should result in a query as to whether we want to install the library system-wide or just for our user. As a system-wide installation requires root privileges the second option is likely to be the required one. Then it checks for a gpg key, giving the user the option to ignore it (I must work out how to check the key). Compilation/installation follows.

Once installed we can then use the library in the current lisp session. Once we’ve restarted our lisp we need to load but not install the library which on SBCL can be done with:

(require :library-name)

To install the regex library cl-ppcre we do:

(asdf-install:install :cl-ppcre)

perform a local install, ignore the gpg key and then we’re good to go. After restarting my lisp session all I have to do is:

(require :cl-ppcre)

to be able to access the library.

Most of this post is based on the ASDF-INSTALL tutorial found here.

Which gets me to the point I wanted to be at the other day. There is another ASDF-INSTALL Tutorial which gives details of how to create packages which I’ll look at another time. There are also some instructions in the one linked to above concerning an earlier system for packaging libraries, called mk:defsystem, which I’ll also need to have a look at.

Another way of defining packages is to use “defpackage”m this appears to include all of the previous make-package things, it allows for the definition of functions which need to be exported (the public interface of the package), which functions need to be imported and from where.

To define a package we do:

(defpackage dave)

There are various options we can supply to defpackage which the Hyperspec gives as:

option::= (:nicknames nickname*)* |
          (:documentation string) |
          (:use package-name*)* |
          (:shadow {symbol-name}*)* |
          (:shadowing-import-from package-name {symbol-name}*)* |
          (:import-from package-name {symbol-name}*)* |
          (:export {symbol-name}*)* |
          (:intern {symbol-name}*)* |
          (:size integer)

These allow us to do various things which make-package allows us to do separately.

The Hyperspec for packages is here.

A very basic example is:

(defpackage dave
    (:documentation "Dave's package"))

The other options work in a similar way.

I’ve been reading up on packages in Common Lisp, as getting and using commonly available libraries has been something of a struggle. My current reading indicates that:

(make-package 'dave)

will create a new package called dave.

Whilst:

(in-package dave)

changes the designated package from cl-user to dave.

It took a bit of head-scratching but I finally worked out that the function (well macro really) in-package is part of the common-lisp so if I want to move to a new package I have to make this clear by using either:

(common-lisp:in-package cl-user)

as in-package has been exported from common-lisp (I think) or:

(common-lisp::in-package cl-user)

to indicate the path to the function (think scope in c++ sort of), a path that can include un-exported symbols.

Now to start looking into systems, asdf and asdf-install.