Thursday, November 19, 2009

Manually installing ASDF packages for SBCL

When I started getting back into Lisp earlier this year, after a bit of reading I quickly found out that ASDF was the more popular method for installing third-party packages. I also quickly found a problem though: simply typing (asdf-install:install 'package-name) doesn't always work, because some packages, while they have ASDF system files written, are not uploaded to - or are not up to date on - the remote site (cliki.net) and thus fail when you try to install it. So when you're out of options and decide to download or checkout the source for the package, how the hell do you install it?

In your home directory you should have a .sbcl directory. Inside this directory you should have two more directories: site and systems. To manually install a package:
  • Unzip/untar/checkout the source code into its own directory inside the site directory. For example, on my machine cl-ppcre is unpackaged into .sbcl/site/cl-ppcre-2.0.1/
  • Create a symlink from the ASDF system file to the systems directory. For example, .sbcl/site/cl-ppcre-2.0.1/cl-ppcre.asd is symlinked to .sbcl/systems/cl-ppcre.asd
That should be it. Now doing a (require 'cl-ppcre) in SLIME locates the ASDF system file in .sbcl/systems/ and loads the library as expected.

Note: If your SBCL doesn't look in systems for packages, you can check the asdf:*central-registry* variable for the correct directory.

Another note: If you prefer to install packages for the entire system rather than just your specific user, ASDF system symlinks live in /usr/local/lib/sbcl/site-systems (assuming you installed SBCL in /usr/local).

Last note, I promise: The obvious shortcoming of manually installing libraries is it won't automatically retrieve dependencies for you :(

Wednesday, October 21, 2009

Twitter shell tools

I've posted my current shell tools for interacting with Twitter here. Still a work in progress, obviously, but it's progressing none-the-less!

Thursday, October 15, 2009

URL Shortening Services

I'm currently brainstorming some ideas on determining who is linking to a domain that I own via shortened URLS (e.g. tr.im, is.gd, ow.ly and similar). Without approaching the owners of the site to purchase that data ;) Basically I'm trying to answer the question "who is linking to my site from Twitter" since Twitter clients all use URL shortening services.

If the URL shortening service sends the shortened URL as a referrer in the HTTP headers, and the web browser should do exactly that, then we can use Twitter's search interface to search on those shortened URLs when they pop up in our access logs. The obvious shortcoming is if nobody clicks on a particular shortened URL, it will never show up in the access logs and therefor we won't know about it.

More brainstorming is needed. And probably some reading.

Thursday, September 3, 2009

SBCL and Command-line Common Lisp Apps

Ok, first things first: read Xach's steps to creating small Common Lisp projects. Without it, I was unable to find anything as straight-forward as that to explain a process for creating Lisp projects. There is a lot of very useful stuff in there.

Second thing: I am not a Lisp expert so this may not be The One True Way to do things.

Finished reading? Good. Ok. Xach's article is not aimed at creating utilities to be run from the command line, but in full Lisp environments, like SLIME. Xach's guide gives you all the information you need as far as laying out your Lisp code and setting up ASDF system files are concerned. The last bits and pieces you need are concerned with the shell environment. So, you will need:

  • Your code (obviously)
  • An ASDF system file (from Xach's article)
  • A Makefile to compile your code to .fasl and a .core (for SBCL)
  • A shell script to run your .core file

The contents of the Makefile for a project named "my-project":
SBCL = /usr/local/bin/sbcl

all:
    $(SBCL) --eval "(require 'asdf)" --eval " \
        (progn \
         (asdf:oos 'asdf:load-op 'my-project) \
         (save-lisp-and-die \"my-project.core\"))"

clean:
    rm -rf *.fasl
    rm -rf *.core

This will compile all of the packages you defined in your ASDF system file into .fasl bytecode files and then save a .core file. Now all you need is a shell script to run the .core:

#!/bin/sh

SBCL=/usr/local/bin/sbcl

$SBCL --core my-project.core --noinform \
    --eval "(progn (my-project:main) (quit))"

And that'll do it! This assumes that your code has an exported defun, 'main', as the entry point for your program. Now run the shell script and your application will run.

Edit: Xach mentioned in the comments that you can use the :executable argument to save-lisp-and-die to create an executable, thus removing the need for the wrapper script above.

This is the build process I use for my little cl-mines game, so you can check out the setup there if there is anything that was unclear.

Wednesday, August 26, 2009

cl-mines - A Minesweeper Clone

I uploaded my Minesweeper clone, cl-mines to GitHub a few days ago. It's just a simple, command-line Minesweeper game. It doesn't really have a proper build process yet.

I've only tested it on SBCL, but there isn't any SBCL-specific code that I'm aware of and it is, by far, not the most complicated piece of Lisp code out there, so it should work with other Common Lisp implementations.

Friday, August 21, 2009

Releasing Some Code to GitHub

I'm going to be releasing a bunch of code to my GitHub over the next few weeks, after I clean up some of it and fix a few design issues and small bugs. This should include:
  • Minesweeper clone
  • Command-line Twitter tools
I may also release my Cellular Automata simlator aswell. However, at the moment, it has performance issues due to the Common Lisp LTK libraries. I have also started designing a Tetris clone (to be written in either Python+PyGame or Perl+SDL). Any updates to that will be pushed to GitHub aswell.

Sunday, August 2, 2009

Cute Perl Gem to Get the Minimum/Maximum Value

Saw this little nugget on #perl@irc.perl.org the other night. It determines the minimum of two values:

[$b, $a]->[$a <= $b]

It takes advantage of the fact that Perl doesn't have a boolean return type for true or false, so the comparison operators return 1 or 0 for true and false, respectively, which are then used by this code to index the array ref.

To get the maximum of the two values, just flip the operator to >=