I've set up a hunchentoot project with quickproject per Xach's instructions. In-package is run at the top of the file, and hunchentoot is started later in the file. The REPL is switched to my package also, but it is evident that hunchentoot is not running in my package. This causes some disparity between tests in the REPL and the browser. For example there is a function that looks up some stuff in an alist, but hunchentoot gets NILs from it because it is using symbols from another package.
I am aware from the answers to this related question that I can wrap every piece of code that interns symbols in something like
(let ((*package* (find-package :package-name)))
...)
which will set the *package* var to the correct package for the duration of the enclosed code.
Putting this in every function that needs it feels to me like a messy hack.
Intuition says that I should be able to start hunchentoot like this:
(let ((*package* (find-package :package-name)))
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242)))
So that it makes its whole run with *package* set to the value that I prefer, thereby ensuring that any interning done by a call from the webserver is done in my package. It doesn't work. Hunchentoot ends up interning things under cl-user, possibly due to using a macro like WITH-STANDARD-IO-SYNTAX as in the link above.
Even if I can persuade hunchentoot to do what I want, is there a reason why my 'messy hack' is still the better thing to do?
This is not a Hunchentoot specific question, but relates to Common Lisp packages in general.
What you are seeing is that in your code, the *PACKAGE* special variable is not bound to your own package. IN-PACKAGE changes *PACKAGE* only at compile and read time. When a function in your package is called at run time, *PACKAGE* is not re-bound and needs to be bound explicitly.
When you are using INTERN or FIND-SYMBOL, it is often best to specify the package as argument. Alternatively, you can bind *PACKAGE* yourself.
Try LOADing this file to see:
(defpackage :foo
(:use :cl))
(in-package :foo)
(defun test ()
(print *package*))
(in-package :cl-user)
(foo::test)
Common Lisp code does not 'run' in a package.
There are a few operations which use a default package. Like reading a symbol from a text stream:
CL-USER 1 > *package*
#<The COMMON-LISP-USER package, 56/64 internal, 0/4 external>
CL-USER 2 > (read-from-string "FOO")
FOO
3
CL-USER 3 > (describe (read-from-string "FOO"))
FOO is a SYMBOL
NAME "FOO"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The COMMON-LISP-USER package, 57/64 internal, 0/4 external>
or like finding a symbol:
(find-symbol "FOO")
These operations depend on the value of the variable cl:*package*.
To make sure that these operations (reading symbols, finding symbols, interning symbols, ...) are doing what you expect, you may want to:
set or bind the *package* variable to the package you want to
explicitly pass the package to operations. You can call (find-symbol "FOO") and have *package* set to some package. But you can also call (find-symbol "FOO" my-package) by passing the respective package as an argument.
Summary: Common Lisp code does not 'run in a package', but it uses the variable *package* as a default package for package-related operations. You need to set or bind this variable when you use this mechanism.
When Hunchentoot runs in multi-threaded, its acceptors and handlers are processed in child threads made with bordeaux-threads on non-Lispwork CL implementation. The reason of the situation you asked is that the current packages of child threads become COMMON-LISP-USER.
To get the result you want, you can make child threads' current packages same as calling thread's with implementing START-THREAD generic function corresponding to ONE-THREAD-PER-CONNECTION-TASKMASTER taskmaster.
Note that you use latest Hunchentoot which has START-THREAD generic function, I use of version 1.2.19.
(in-package :hunchentoot)
(defmethod start-thread ((taskmaster one-thread-per-connection-taskmaster) thunk &key name)
(let* (;; calling thread's current package
(package-name (package-name *package*))
;; initial special bindings passed to bordeaux threads
(initial-bindings `((*package* . (find-package ,package-name)))))
;; making child thread passing initial special bindings
(bt:make-thread thunk :name name :initial-bindings initial-bindings)))
Related
I am new to Common Lisp. Even more when the topic is packages and systems. I am working with a program and something intrigues me. Btw, I am using SBCL and Slime (Emacs).
Being on the top-level (CL-USER) I can do:
CL-USER> (application-name/file-name::%function-on-parenscript)
This works! Then, I change to be inside the package:
CL-USER> (in-package :application-name)
Ok. So, I thought that after being inside the application name:
APPLICATION-NAME>
I would be able to do just:
APPLICATION-NAME> (file-name::%function-on-parenscript)
However, this does not work. It just works if I do:
APPLICATION-NAME> (application-name/file-name::%function-on-parenscript)
1 - Why is the application-name necessary if I am inside application-name?
2 - Why sometimes I need to use :: and other times I use just : to call things?
Common Lisp packages are there to solve namespaces problems. But they really intrigue me.
application-name/file-name and application-name are two distinct packages that are similar in names only for human readers but are otherwise unrelated.
Symbols are either written with a package prefix or not. The package is the part on the left of the colon or double-colon when there's a package prefix.
The double colon is a way to refer to symbols that are not exported from the package (they are private).
A single colon is for symbols that are exported.
If the symbol you want to refer is "accessible" in the current package, for example because you are "using" it's package and it is exported, then you can write the symbol without a package prefix
See Programming in the Large: Packages and Symbols for details
On my Windows XP box with sbcl-1.4.14 I've installed the ASDF using
(load "C:\\Program Files\\clisp-2.49\\asdf\\asdf.lisp")
(require :asdf)
(push "C:\\Documents and Settings\\mayhem\\lisp\\iterate\\" asdf:*central-registry*)
On SLIME
(require :iterate)
(iterate (for i from 1 to 5) (collect (* i i)))
gives The variable I is unbound error
If I do (in-package :iterate), the code above works fine but this time familiar functions such as exit and other functions which I've defined in .sbclrc cease to work, they give The function ITERATE::EXIT is undefined type of errors, for example.
If I do (use-package :iterate), then it gives [Condition of type NAME-CONFLICT] error.
So I began to use the package like this:
(iterate:iterate (iterate:for i from 1 to 5) (iterate:collect (* i i)))
But I think you'll agree that it's a bad style.
How to use the iterate correctly?
Note: I've seen the post about the very similar problem but it didn't help. There aren't many posts or articles about this particular problem.
You need to say (use-package :iterate) before you try to refer to unqualified symbols from the iterate package.
What has happened in your case is this.
You've loaded the iterate system into the running Lisp, creating a package called "ITERATE".
In the "CL-USER" package you've typed (iterate ...), and the reader has worked out that it needs to find or create a symbol whose name is "ITERATE" and which is accessible in the "CL-USER" package.
There is no such symbol, so it creates a new one, CL-USER::ITERATE.
This is not ITERATE:ITERATE so you get an error from the evaluator as it's trying to evaluate the arguments to a function (which doesn't exist, but it doesn't know that yet). In fact the error you're getting is while it's evaluating the first argument in the (for i ...) subform.
Now you say (use-package :iterate) to tell the system to add the "ITERATE" package to "CL-USER"'s search list.
Now there's a conflict: should iterate refer to the existing CL-USER::ITERATE or the newly-accessible ITERATE::ITERATE? (And there are some other conflicts too, probably).
So the system signals an error, and there should be some useful ways to proceed from that, one of which is probably 'unintern all the conflicting "CL-USER" symbols', but you didn't take that option, I suppose.
So now everything is messed up.
And the answer is: use the packages you want to refer to unqualified symbols from before you try to refer to those symbols unqualified.
(Also: Windows XP? I'm impressed by your retroness.)
When printing out object names which are interned in one package, but referenced from another package, the print name will include the full package name. For example, the following interaction interns the symbol X in PKG1, and prints its value from CL-USER:
* *package*
#<PACKAGE "COMMON-LISP-USER">
* (defpackage :pkg1 (:use :cl))
#<PACKAGE "PKG1">
* (in-package :pkg1)
#<PACKAGE "PKG1">
* (defvar x '(a b c))
X
* (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">
* pkg1::x
(PKG1::A PKG1::B PKG1::C)
Sometimes for diagnostic/debugging reasons, I would like to printout external symbols without their package prefixes. In this case the printout would then look like (A B C). For complicated or nested objects where you know what the names mean, the package prefixes can make the printout hard to read, especially if there are multiple packages. Can the prefixes be temporarily suppressed for printout?
No, but you can elide the prefixes of one package by temporarily binding *package* to it for the printout.
Example:
(let ((*package* (find-package :pkg1)))
(print pkg1:*x*))
Since *package* is globally dynamic, this affects everything called inside (i. e. in the dynamic extent of its invocation) this let form but doesn't affect anything outside.
I'm trying to to use asdf's functionality to run my test suite from the repl but when using quicklisps quickload if fails on the first attempt to load foo and success on the second.
(in-package :cl-user)
(defpackage :foo-system
(:use :cl :asdf))
(in-package :foo-system)
(asdf:defsystem :foo
:components ((:file "foo")))
(asdf:defsystem :foo-tests
:depends-on (:foo)
:components ((:file "foo-tests")))
(defmethod asdf:perform ((op test-op) (system (eql (find-system :foo))))
(asdf:load-system 'foo-tests)
(foo-tests:run-tests))
It makes sense because when I compile the asd file the error appears to be in the second form of the asdf:perfom defmethod. The error, replacing nclack by foo, is:
../../nclack/nclack.asd:36:27: read-error:
READ error during COMPILE-FILE:
Package NCLACK-TESTS does not exist.
Line: 36, Column: 27, File-Position: 1034
Stream: #<SB-SYS:FD-STREAM
for "file /Users/PuercoPop/quicklisp/local-projects/nclack/nclack.asd"
{1005DB11A3}>
which matches the (foo-tests:run-tests) line. So it appears to be that 'loading' a system is different from compiling its forms? Or why is the package not defined after loading the system? Any ideas? I'm at a loss.
When you compile-file this:
(defmethod asdf:perform ((op test-op) (system (eql (find-system :foo))))
(asdf:load-system 'foo-tests)
(foo-tests:run-tests))
the first step is to read the entire form. Reading includes interning of all symbols found. However, at read time, the form has not executed, so the system foo-tests is not yet loaded. Since that system includes the package foo-tests, and that is not loaded yet either, you cannot intern any symbols into that package at read time of this form.
That's why compile-file gives the error shown when trying to read the form.
It seems to me that you would need to (funcall (find-symbol "RUN-TESTS" #:foo-tests)).
First:
If you define a new package FOO-SYSTEM and use the package ASDF and then use the asdf symbols still with the prefix, then you kind of defeated the using of the package. Why use it, when you prefix the symbols anyway?
It is hard to say what the error is, since we don't see a backtrace and don't see the files.
Anyway, you need to make sure that a package is available during compilation of a file. For example compiling a DEFPACKAGE form may not change the compile-time environment. You need to execute the DEFPACKAGE form. You also need to make sure that the package definition gets loaded during a load system operation.
If the package does not exist, you need to make sure that it exists.
I'm trying to use parenscript in GNU common lisp to compile a lisp file into a javascript one.
I find that using the PS symbol macro "#" doesn't work if I try to use its prefix ("ps:#"). However, if I use the REPL and run (use-package :ps) before I try compiling the lisp file, everything works as expected (and I don't have to use the prefixes).
The problem is that the PS package contains clashing symbols, e.g:
*** - (USE-PACKAGE (#<PACKAGE PARENSCRIPT>) #<PACKAGE COMMON-LISP-USER>): 2 name conflicts remain
Which symbol with name "CHAIN" should be accessible in #<PACKAGE COMMON-LISP-USER>?
The following restarts are available:
PARENSCRIPT :R1 #<PACKAGE PARENSCRIPT>
COMMON-LISP-USER :R2 #<PACKAGE COMMON-LISP-USER>
ABORT :R3 Abort main loop
I can resolve this interactively by choosing :r1, but when I try to put this step in my script it just bails (since it's non-interactive, it doesn't give me a choice of what restart to use)
I'd love to say (in my script) "just use the PS version of all clashing symbols", but I can't figure out how to do so.
It would also be okay if I could say (as one might in python), "from PS import chain, #, (etc)" - specifying each symbol I want to import manually.
Instead of working in the COMMON-LISP-USER package, make your own with DEFPACKAGE:
(defpackage #:my-awesome-program
(:use #:cl #:parenscript))
(in-package #:my-awesome-program)
; your code here
COMMON-LISP-USER might include all sorts of implementation-specific symbols.
You can also use SHADOWING-IMPORT to get individual symbols, overriding what might already be currently visible in the package, e.g.
(shadowing-import 'ps:*)