This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

How to split project into multiple files

7 posts · 8259 views

I'm trying to write my first lisp program and I've got a problem how to split it into multiple files. I can't figure out how to make CL automatically compile and load a few files.

If I create file1.lisp with:
(load "file2.lisp")
won't look for file2 in the same directory as file1.

I also tried defpackage, but packages aren't loaded automatcally either. Is there a simple way do do that? (writing ADSF files seems way too much for a hello-world program)

Re: How to split project into multiple files

I am not sure if I understand what exactly you want. If it gets on your nerves to always "load" all the files again, you might want to use Core-Images (under SBCL you can create these with sb-ext:save-lisp-and-die). If you always want to load some file on startup, you can put the load-command into the rc-file (~/.sbclrc, ~/.eclrc, etc., under linux, depending on the implementation you use). If you want a Package, maybe an .asd-File is the best. ASDF may be mighty, but for a simple "hello world"-application, you dont need to use all of it. The basic structure is simple:
(defsystem "your-project-name"
  :description "Some Description"
  :version "..."
  :author "you"
  :license "quak"
  :depends-on (#:package1 #:package2) ;you probably wont need this
  :components ((:file "file1") (:file "file2") (:file "...")))
As most of these arguments are optional, it should be easy to use it. If this file is in the same directory as "file1", etc., then you should be able to load it using asdf.
Sorry for my bad english.
Visit my blog http://blog.uxul.de/

Re: How to split project into multiple files

klkl wrote:If I create file1.lisp with:
(load "file2.lisp")
won't look for file2 in the same directory as file1.
Well this should work:
(let ((*load-pathname* *default-pathname-defaults*))
  (load "file2"))
but probably isn't recommended practice.
klkl wrote: I also tried defpackage, but packages aren't loaded automatcally either. Is there a simple way do do that? (writing ADSF files seems way too much for a hello-world program)
I agree that ASDF is a lot of work for a hello-world program but if it really is a simple program, you might consider just using one file. It would keep things a lot simpler in the short term while you play with the language.
Phil - http://phil.nullable.eu/

Re: How to split project into multiple files

klkl wrote:I'm trying to write my first lisp program and I've got a problem how to split it into multiple files. I can't figure out how to make CL automatically compile and load a few files.

If I create file1.lisp with:
(load "file2.lisp")
won't look for file2 in the same directory as file1.
If you just want to keep it simple and don't want to mess around with asdf etc, you can just do like this:

Define the helper function load-relative:
(defun load-relative (filename)
  (load (compile-file (format nil "~A~A" 
                                            (directory-namestring *load-truename*)
                                            (pathname-name filename))))
and then create a script "load-my-app.lisp" that contains:
;; These can be placed into a separate file, like "load-deps.lisp"
(require :dep-1)
(require :dep-2)
(require :dep-3)

;; This can be put into a separate file too, like "packages.lisp"
(defpackage foo ... ) 

(load-relative "file1")
(load-relative "file2")
(load-relative "file3")
Some notes:
  • load-my-app.lisp should not be compiled, it's a script.
  • *load-truename* contains the full path of the file currently being loaded

Re: How to split project into multiple files

WeYu wrote:
klkl wrote: ...
If you just want to keep it simple and don't want to mess around with asdf etc, you can just do like this:

Define the helper function load-relative:
(defun load-relative (filename)
  (load (compile-file (format nil "~A~A" 
                                            (directory-namestring *load-truename*)
                                            (pathname-name filename))))
It is a good practice to create pathnames using MERGE-PATHNAMES and friends. Creating pathname strings and hoping they'd work is not advisable.

Cheers
--
Marco
Marco Antoniotti

Re: How to split project into multiple files

I have a question: ASDF lets you specify dependencies for your files, but is it a problem if my files have circular dependencies?

Re: How to split project into multiple files

marcoxa wrote: It is a good practice to create pathnames using MERGE-PATHNAMES and friends. Creating pathname strings and hoping they'd work is not advisable.
Right, the load-relative function should probably look something like this:
(defun load-relative (filename)
  (load (compile-file (merge-pathnames filename *load-truename*))))
I'm guessing that this should even work in cases like
(load-relative "foo/bar/file4.lisp")