Why isn't asdf:load-system creating the package - package

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.

Related

How to understand this Common Lisp package behavior?

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

Correct way to use the iterate package in Common Lisp

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.)

symbol lookup error on a command

i'm trying to do some code in a keyboard driver, a 3rd party software that looks like this can run the command i'm trying to do in a plugin file that compiles alongside the daemon that the command needs to be sent to. the command looks like this.
g15_send_cmd (g15screen_fd,G15DAEMON_MKEYLEDS,mled_state);
here's the code i'm working with and trying to run the command in (it compiles as a plugin with the daemon. in the uncompiled source it's
"g15daemon/plugin/g15_plugin_uinput.c"
the file that defines the command is in
(link)
"g15daemon/libg15daemon_client/g15daemon_clinet.h"
whereas with the g15macro (3rd software) is run from outside the daemon for various reasons i don't want to (and pretty much can't) use it, one being speed of execution of commands when keys are pressed.
so the program compiles like this without error it seems. but if the code i specified above activates, the driver(daemon) crashes giving
g15daemon: symbol lookup error:
/usr/lib/g15daemon/1.9.5.3/plugins/g15plugin_uinput.so: undefined
symbol: g15_send_cmd
what did i do wrong or what am i missing here? (and i'm sorry if the code in the plugin file is ugly down by that switch command, but i didn't know how to do any better since i don't know C much at all, all i have behind me are Py and C#)
Edit: the solution was given
but i don't know how to add a linker flag, also since it links to a part of the program being compiled will it even work?
You forgot to link your plugin with g15daemon_client library. The simple way to fix it is to add -lg15daemon_client to the linker flags.

Changing hunchentoot's current package

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)))

CLisp: "use-package" resolving conflicts non-interactively

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:*)

Resources