0

System-A and System-B are systems that are made using ASDF. They both have system definitions in .asd files and define packages, :system-a and :system-b, respectively.

I want System-A to :use System-B's package in its package definition. I want this so that I can use the symbols of System-B in System-A without referring to System-B's package. Specifically, I want to use symbol rather than system-b:symbol.

Currently, in System-A's package definition, I am trying to :use :system-b. This works to intern libraries that I have imported using QuickLisp, but not for my own systems.

How can I :use :system-b so that I intern the symbols in System-A's package?

audrow
  • 143
  • 1
  • 9
  • 1
    Systems don't have symbols. Symbols are interned in a package. Usually you would define a package with the same name as the system that exports the symbols. – jkiiski Aug 29 '16 at 17:37
  • Thanks, I've clarified the question. – audrow Aug 29 '16 at 18:01
  • There should be no difference between using your own systems and ones installed with Quicklisp. What error are you getting? Can you load `SYSTEM-B` ok? – jkiiski Aug 29 '16 at 18:06
  • It says that `system-a::symbol` is not defined, when `symbol` should be in `system-b`. Must I export the symbols that I want to `:use`? I am under the impression `:use` exports all symbols. By the way, I am using `:use :system-b` in the package definition and `:depends-on ("system-b")` in the `.asd` file. – audrow Aug 29 '16 at 18:23
  • 1
    Yes, you should export all symbols intended to be used from outside the package. The `:USE` in a package definition will only import external symbols. – jkiiski Aug 29 '16 at 18:24
  • Ok, it works. Is there a better way to export all symbols than http://stackoverflow.com/questions/9743056/common-lisp-exporting-symbols-from-packages? Otherwise, what is best practice for making a utilities folder, where I want access to every symbol? – audrow Aug 29 '16 at 18:33
  • Personally I prefer to just export them explicitly, but you could use that too. Or try [cl-annot](https://github.com/m2ym/cl-annot). – jkiiski Aug 29 '16 at 18:39
  • You are very unlikely to want to export all of the symbols in a package. Apart from anything that list is likely to be heavily dependent on the history of the particular lisp instance you are running: for instance if you have compiled a file which is in (in the `in-package` sense) the package you will have a load of entirely incidental noise from the reader (all the local names in all the definitions), while if you just loaded the fasl you (probably) won't. And so on. Instead you need to maintain a list of the symbols you want to be exported, however you do so. –  Aug 31 '16 at 09:21

1 Answers1

0

Here I will show the solutions I've found:


The first is to export the symbols in the package definition. Using my example, in System-B's package definition

(defpackage :system-b
  (:use :cl)
  (:export :symbol1
           :symbol2
           ...))

And in System-A's package definition

(defpackage :system-a
  (:use :cl
        :system-b))

Then, when your are (in-package :system-a) you have access to System-B's exported symbols.


Second, if you have a lot of symbols to export (making a utilities package) you can use the following, found here.

(let ((package (find-package :foo)))
  (do-all-symbols (symbol package)
    (when (eql (symbol-package symbol) package)
      (export symbol))))

Just put this code after all symbols have been created. If using ASDF, in your system definition you can have the last file loaded contain these lines to export all symbols without you having to manually define them.


A third option to export symbols is cl-annot, which among other things, allows you to prefix a function with @export to export it. For example,

@export
(defun foobar ()
   ...)

is equivalent to

(progn
  (export 'foobar)
  (defun foobar ()
    ...))
Community
  • 1
  • 1
audrow
  • 143
  • 1
  • 9
  • 2
    I find `system-a` as a name confusing for a package. A package is not a system. `cl-annot` is plain ugly. Another idea is to use some variant of defun, which exports the symbol. But then it stays an s-expression, and does not use a reader syntax extension. It would also be rare to export ALL symbols of a package by iterating over it. There could be lots of symbols in the package, which are not useful to export. (defun a () 'b) -> why export b? – Rainer Joswig Aug 29 '16 at 20:50
  • 1
    I would not use `do-all-symbols` (which iterates over all symbols in all packages), but `do-symbols` (which iterates over the symbols accessible in a package). – Rainer Joswig Aug 29 '16 at 20:57
  • 2
    `(export (defun foo () ...))` would work too (except for setf functions). Most `def-x` forms return the name of the thing being defined. – coredump Aug 30 '16 at 14:40