Is it better to put the defpackage in a separate file when creating packages
Asked Answered
E

3

10

The example below is given in Paul Grahams ANSI Common Lisp as an example of doing encapsulation:

(defpackage "CTR"
  (:use "COMMON-LISP")
  (:export "COUNTER" "INCREMENT" "CLEAR"))

(in-package ctr)

;function definitions here

However in Peter Seibels Practical Common Lisp, link here, he says:

Because packages are used by the reader, a package must be defined before you can LOAD or COMPILE-FILE a file that contains an IN-PACKAGE expression switching to that package. Packages also must be defined before other DEFPACKAGE forms can refer to them... The best first step toward making sure packages exist when they need to is to put all your DEFPACKAGEs in files separate from the code that needs to be read in those packages

So he recommends creating two files for every package, one for the defpackage and one for the code. The files containing defpackages should start with (in-package "COMMON-LISP-USER").

To me it seems like putting the defpackage in the same file, before the in-package and code, is a good way to ensure that the package is defined before used. So the first method, collecting everything into one file seems easier. Are there any problems with using this method for package creation?

Enclosure answered 7/12, 2011 at 13:26 Comment(0)
L
10

I think that using a separate file for defpackage is a good habit because:

  • You don't « pollute » your files with defpackage.
  • It makes it easier to find the exported/shadowed/... symbols, you know you just have to look at package.lisp.
  • You don't have to worry about the order when you use ASDF.

    (defsystem :your-system
      :components ((:file "package")
                   ... the rest ...))`
    
  • Peter Seibel says so ;)

EDIT: I forgot to mention quickproject which facilitates the creation of new CL projects.

REPL> (quickproject:make-project "~/src/lisp/my-wonderful-project/"
                                 :depends-on '(drakma cl-ppcre local-time))`

This command will create a directory "~/src/lisp/my-wonderful-project/" and the following files:

  • package.lisp
  • my-wonderful-project.asd (filled)
  • my-wonderful-project.lisp
  • README.txt

And thus, I think it's good to use the same convention.

Least answered 7/12, 2011 at 15:29 Comment(3)
I think the order thing is the most important reason of those, and there's one other: packages split over multiple files.Trisyllable
I agree with you, except for the case of single-file projects, where you can put package definition in the same file. AFAIK, it is not prohibited by the standard.Knurl
Multiple files and ordering when using ASDF makes sense. The first two points seems more like individual preference.Enclosure
D
1

I tend to use multiple source code files, a single "packages.lisp" file and a singe "project.asd" system definition file for most of my projects. If the project requires multiple packages, they're all defined in "packages.lisp", with the relevant exports in place exported.

Danell answered 7/12, 2011 at 18:2 Comment(0)
V
0

There is this reason for putting DEFPACKAGE in its own file: if you have a large package, then you might have several groups of related functions, and you might want to have separate source files per function group. Then all the source files would have their own IN-PACKAGE at the top, but they would all "share" the external DEFPACKAGE. Then as long as you get the DEFPACKAGE loaded first, it doesn't matter the order you load the other source files.

An example I'm currently working on has multiple classes in the package, and the source files are broken up to be per class, each having a class definition and the related generic function and method definitions.

Verditer answered 2/12, 2014 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.