Page 1 of 1

How to split project into multiple files

PostPosted: Sun Aug 24, 2008 12:18 pm
by klkl
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:
Code: Select all
(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

PostPosted: Sun Aug 24, 2008 2:47 pm
by schoppenhauer
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:
Code: Select all
(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.

Re: How to split project into multiple files

PostPosted: Sun Aug 24, 2008 2:54 pm
by phil
klkl wrote:If I create file1.lisp with:
Code: Select all
(load "file2.lisp")


won't look for file2 in the same directory as file1.


Well this should work:

Code: Select all
(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.

Re: How to split project into multiple files

PostPosted: Thu Aug 28, 2008 4:05 am
by WeYu
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:
Code: Select all
(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:
Code: Select all
(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:

Code: Select all
;; 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

PostPosted: Tue Sep 02, 2008 8:24 am
by marcoxa
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:
Code: Select all
(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

Re: How to split project into multiple files

PostPosted: Thu Sep 04, 2008 3:47 am
by humpolec
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

PostPosted: Thu Sep 04, 2008 4:11 am
by WeYu
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:

Code: Select all
(defun load-relative (filename)
  (load (compile-file (merge-pathnames filename *load-truename*))))


I'm guessing that this should even work in cases like
Code: Select all
(load-relative "foo/bar/file4.lisp")