So I'm practicing lisp with Project Euler, and I'm collecting little utility functions into a separate file to reduce duplication, and I expect that it might get pretty huge, so I've gone ahead and made a package definition. Here is a condensed version of the file that still illustrates my problem:
(defpackage :euler-util
(:use :common-lisp)
(:export :divisible-by))
(in-package :euler-util)
(defun divisible-by (x y)
(equal 0 (mod x y)))
I can compile and load (C-c C-k) that file into SLIME without any warnings or errors. Now, when I go to use it in another file, I do the following:
(load "util.lisp")
(use-package :euler-util)
(defun euler-1 ()
(loop for i from 3 to 999 when (or (divisible-by i 3) (divisible-by i 5)) sum i))
When I try to compile and load THAT file, I get an error like this:
"USE-PACKAGE # causes name-conflicts in # between the following symbols: EULER-UTILS:DIVISIBLE-BY, COMMON-LISP-USER::DIVISIBLE-BY [Condition of type NAME-CONFLICT]"
Why is this symbol appearing in the COMMON-LISP-USER package, and how do I stop it?
A naming conflict occurs when you try to create or use an identifier that was previously defined. In some cases, naming conflicts generate errors such as Ambiguous name detected or Duplicate declaration in current scope.
A name conflict in use-package between a symbol directly present in the using package and an external symbol of the used package may be resolved in favor of the first symbol by making it a shadowing symbol, or in favor of the second symbol by uninterning the first symbol from the using package.
compile-file
reads all the forms in the file, and only executes forms that expand into the appropriate eval-when expressions. In your example above, the util.lisp file is not loaded until after the referencing file is already read (interning all its symbols in cl-user). use-package is similarly a plain function call that is not evaluated until load time, and that's when you're asking it to make two distinct symbols by the same name accessible in the current package.
One option is to put the load
and use-package
statements in an eval-when
form, e.g.
(eval-when (:compile-toplevel :load-toplevel :execute)
(load "util.lisp")
(use-package :euler))
I think it would be better to define a new package for your project, and put it at the top of your file:
(defpackage #:euler
(:use #:cl #:euler-util))
(in-package #:euler)
Those statements are automatically evaluated at compile time, so there's no need for eval-when
.
Experienced CL authors tend to avoid this problem by defining packages in a specific order, putting in-package
forms in every source file, and by using a system definition facility to compile and load files in the right order.
I use ASDF as a system definition facility. A simple system file could look like this:
;;;; my-project.asd
(asdf:defsystem my-project
:serial t
:components ((:file "util")
(:file "my-project")))
If you put that file somewhere ASDF knows about, (asdf:load-system "my-project")
will then compile and load the files in the specified order.
If you use Quicklisp, one easy way to do it is put the project's directory in ~/quicklisp/local-projects/ and then use (ql:quickload "my-project")
to automatically load it and its dependencies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With