November 10, 2001
Portability 1: Files and Iteration

I'm porting some lisp code from a lisp on windows (ACL) to a different lisp (CMUCL) on unix. Here are a few of the things I've run into while trying to get the code to work. (Most of these things are pretty obvious, some are just simple errors that ACL didn't catch.)

  • Assume filename case might be significant, but don't rely on it. "server/netmon-server.lisp" is not the same file as "Server/netmon-server.lisp" under unix, but it might be under Windows.

  • No hardcoded paths. "C:/projects/netmon/foo/file.txt" should be something like "../foo/file.txt" (but see the next item).

  • Don't use weird namestring tricks like "..". I lied above, it shouldn't be "../foo/file.txt". It should be something like

    (merge-pathnames
      (make-pathname :directory '(:relative :up "foo")
                     :name "file"
                     :type "txt")
      *load-pathname*)
    

    The problem is that "../foo/file.txt" has no standard meaning in lisp. It means something in unix and windows, but even there it makes assumptions about what the current directory must be. (And it's not like every operating system has a concept of "current directory". What would be the current directory on a Mac, huh? I bet you have lots of guesses, but odds are you don't know.)

    (Note that according to the Hyperspec an implementation is not required to accept :up in a directory list, and until recently (October 2001) CLISP did not--but they added support for it promptly after I pointed it out.

  • The termination test for do is not optional. So

    (do (...)
        ()
      ...)
    
    is not allowed. It has to be
    (do (...)
        (NIL)
      ...)
    

    (This one was just a dumb and weird mistake. What was I thinking?)

  • file-length is defined to take a stream argument, not a filename. So to determine the length of a file you have to open it first (which seems strange to me, but is not too much of a hassle).

Posted by jjwiseman at November 10, 2001 02:17 AM
Comments

Hell, I forgot to mention that even "foo/bar.txt" is totally unportable. Is bar.txt a file or a directory? On a Mac the whole thing refers to a single file named "foo/bar.txt".

So, I can't recommend using namestrings at all.

Posted by: jjwiseman on January 22, 2002 06:42 PM

I just noticed that ACL 6.0's implementation notes mention file-length: "Allegro CL allows stream to be a pathname or a string naming a file as well as a stream open to a file (ANSI CL specifies only a stream open to a file). This function returns the size of the file."

So they thought it was weird, too.

Posted by: jjwiseman on January 24, 2002 11:20 AM
Post a comment
Name:


Email Address:


URL:




Unless you answer this question, your comment will be classified as spam and will not be posted.
(I'll give you a hint: the answer is “lisp”.)

Comments:


Remember info?