Monday, January 7, 2013

announcing trivial-project-pathname

I have been copy-pasting the same code over and over and decided to wrap it up in trivial-project-pathname, which is a very simple Common Lisp library for resolving pathnames relative to some directory, usually the sources.

The typical use case looks like this: I am working on, say, some data analysis and I have the following directory structure:

data/where data files are kept
latex/LaTeX sources
lisp/Common Lisp code, including ASDF system definition
plots/plots (potentially generated from Lisp)

I want to be able to write something like

(analyze-data-and-save-plot (project-path "mydata.csv" :data)
                            (project-path "myplot.pdf" :plots))

and have the data read from data/mydata.csv and the plot saved to plots/myplot.pdf.

This is how I would do it using this library:

(project-pathname:define project-path (:asdf "myproject" '(:relative :up))
  (:data "data/")
  (:plots "plots/"))

This finds the directory for the .asd file, takes its parent directory, and then defines a function that maps symbols to subdirectories.

Unless otherwise specified, NIL, the default for the optional parameter, would map to the base directory. You don't even need to use subdirectories, you can just

(project-pathname:define project-path2 (:asdf "myproject"))
;;; and then use
(project-path2 "my-data-file.csv")

You can also use *load-truename* to define *base-directory* in the .asd file as recommended by Zach Beane and then define

(project-pathname:define project-path (:directory *base-directory*))


  1. Hi Tamas!
    project-pathnames look a lot like logical pathname translations, am I missing something?

    1. Good question. I am not an expert on logical pathnames, but I am under the impression that they do something similar, but much more complex and restrictive at the same time. I could be wrong, because I didn't devote a lot of time to logical pathnames, and I am still not clear on what the standard requires and what part of them is implementation-dependent (eg case). In any case, I wanted something with simple and well-defined semantics — I am under the impression that logical pathnames are a mystery to most CL programmers, and I am included in that camp. Can you point to a good tutorial? CLHS is really, realy obscure on this feature.

      Also, I should correct the examples, "data/" etc is not portable.

  2. One big problem with code deployment, specially in implementations such as ECL that allow for standalone executable production from ASDF files, is precisely delivery of project files. It would be nice if project-pathnames provided a means to register all pathnames at boot time in the standalone executable and merging it with the new asdf-bundle features in asdf to create a fully packaged application out of the box... just my 2c