When reading from a text file in the same directory as the code doing the reading, most languages allow the user to simply put the name and extension of the file and assume the rest of the path is the same as that of the code. Lisp doesn't seem to have this feature, and half an hour of searching has not yielded a working alternative. As an example, the following code, whose intended function is to simply print the first line of a referenced text file, has the path C:/Users/Owner/Documents/Lisp/Read_Demo/reader.lisp and references a text file with the path C:/Users/Owner/Documents/Lisp/Read_Demo/input.txt:

The file #P"C:/ProgramData/Microsoft/Windows/Start Menu/Programs/LispWorks 6.1 Personal/input.txt" does not exist.

Clearly, Lisp assumes the file I want is in that "LispWorks..." folder, rather than the current directory. Is there any way to achieve the desired functionality without hard-coding the entire path of the file I wish to read from and while still using the OPEN function?

All three major operating systems have a notion of the current directory, and this is where programs will attempt to open files that don't have an absolute prefix (e.g. C: on windows).

Lispworks is clearly (from your error message) using its own directory as its initial current directory.

You have two options:

You can change the current directory for your lisp process, or

You can provide an absolute path

I assume that you use the Start menu to launch Lispworks, this is why Windows picks the directory that it does, if you had opened a terminal (cmd.exe) and changed to your source directory and then launched Lispworks by its path then the initial current directory would be what you want. Alternatively Lispworks will have a function that you can call to change the current directory (sbcl has this as the function SB-POSIX:CHDIR). Common-Lisp doesn't provide a function to change the current directory because it's sooooooooooo old that it targeted some ancient operating systems that had no hierarchical filesystems, and as a result each implementation now has to provide its own. At this point some might point at MERGE-PATHNAMES, but they can go whistle, pathnames are a portability fuster-cluck (again, because long-dead OS had major weirdness, it was under-specified)

If you use ASDF for loading your systems, then having an absolute path is actually very easy:

Thanks for the response! I'm asking about this for a school assignment, and in class it's a bit frowned upon to import external... uh... modules/libraries/whatever-they're-called-in-Lisp. Also the whole "system" thing is confusing me and seems to be more complicated than it's worth looking into. (Also, I may be wrong, but it seems like using this limits where you are allowed to put your files and still makes you explicitly tell Lisp where they are, both of which defeat its purpose.) The functionality I reference in this thread is not required for the assignment, but I just thought (coming from other languages which supported the functionality) that it had to exist in Lisp and surely the language didn't force its users to hard-code entire paths which may change. (Or, as it appears, put in serious effort trying to figure out how to manipulate facilities outside of pure CL.) The gist of your answer to me seems to be 'Lisp evolved weirdly and as a result this functionality just isn't a thing.' I'll just stick with hard-coding for now, but thanks for the help!

In the Lisp universe, the counterpart of the current working directory is the *default-pathname-defaults* variable. It's similar, but better.

When Lisp starts, typically it bounds *default-pathname-defaults* to the current directory.

Suppose I've got directories ~/test/a & ~/test/b & a file ~/test/a/input.txt. If I change my directory to ~/test/a & start SBCL there, it can find input.txt using only the relative path. Now, if I change my directory to ~/test/b & start SBCL there, (open "input.txt") raises an error. Checking the value of *default-pathname-defaults*, I see that it is #P"/home/me/test/b/", as expected. (The leading #P means it's a pathname & not a string.) Now I change the value of this variable:

& read input.txt using relative pathnames. If you care to explain your setup, maybe we could think of a better solution.

As a side note, you shouldn't use the OPEN function, but rather the WITH-OPEN-FILE macro, which takes care of closing the file no matter what.

As another side note, nowadays the code is not organised as scattered .lisp files, but comes neatly packed in ASDF systems. So eventually you'll have to look into them if you want to write something more substantial than "hello world".

Thanks for the thorough reply!About my setup... I work with Lisp both on my school's Macs using Clozure CL and on my PC at home using LispWorks, and I keep my files on a flash drive so I can go between the two.I've tried using *default-pathname-defaults* before, but it always comes up as an empty string because it seems I'm not able to practically "control the directory I start Lisp in." At home, I don't have the option of right-click + Open With for Lisp files, so I just have to open LispWorks from the desktop and open the file from within the program. I believe it has been suggested in this forum that I open the Lisp file with the command prompt in some way, but I don't know how to do that and it seems more cumbersome than the problem it's solving. At school, I can right-click on a Lisp file and open with Clozure CL, but *default-pathname-defaults* is still empty. I don't have admin privileges at school, of course, so command prompt isn't really an option.It seems like no matter what you do, some action has to be taken on the user's end which explicitly defines the directory you're working with. I remember when I took classes that used Java and Python, we'd have programs that referenced files like "input.txt" (without the path because they are in the same directory as the code accessing them), and even when we'd turn assignments in (the code and input are now in a different directory on the teacher's computer, but each are still in a folder together) the teacher would still be able to run the program. This doesn't seem like a thing you can do in Lisp with any of the solutions previously mentioned. If I'm wrong, I'd love to know.(Thanks for the tip about WITH-OPEN-FILE by the way. Also this is just an intro course, so I probably won't be using ASDF systems, but thanks for the heads up.)

jhud wrote:I've tried using *default-pathname-defaults* before, but it always comes up as an empty string because it seems I'm not able to practically "control the directory I start Lisp in."

It should be a pathname, actually, rather than a string. However, it's weird that it's empty. How do you access it?

Typically, in a running Lisp you've got a REPL. The thing you can type expressions in & see the answers. In LW it's built into the IDE, I think. Whatever Lisp IDE must have a REPL. It's in REPL that you can see the value of *default-pathname-defaults* as well as change it using setf.

jhud wrote:At home, I don't have the option of right-click + Open With for Lisp files, so I just have to open LispWorks from the desktop and open the file from within the program.

Launching LispWorks & subsequently opening a file from there isn't the same thing as running a Python script. How do you run Python at home and at school? Using a context menu?