Reputation:
I'm trying to import some functions from SBCL non-standard builtins to use with a socket. When I do this outside slime, with bare interactive shell + SBCL it works, but not in SLIME.
What I did:
(import 'sb-bsd-sockets:host-ent-address)
(import 'sb-bsd-sockets:get-host-by-name)
or
(use-package :sb-bsd-sockets)
After doing either one, SLIME greets me with an error, saying that I'm trying to import something already in cl-user package. This is a correctable error, which I proceed to correct by choosing the symbols found in sb-bsd-sockets package. No further errors follow.
Then, when I try to compile function:
(defun nslookup (hostname)
(if hostname
(sb-bsd-sockets:host-ent-address (sb-bsd-sockets:get-host-by-name hostname))
nil))
It works. But if I try to compile this:
(defun nslookup-1 (hostname)
(if hostname
(host-ent-address (get-host-by-name hostname))
nil))
Then I get a warning about undefined functions, and an error when I try to call nslookup-1
.
To my surprise, if I try doing this in REPL:
CL-USER> #'host-ent-address
#<STANDARD-GENERIC-FUNCTION HOST-ENT-ADDRESS (1)>
CL-USER>
It "works". I.e. it knows the function, but decides not to use it...
There must be some (special?) way to either import packages into SLIME's REPL, or at least symbols from those packages, otherwise it's very inconvenient to use long names for testing and then to replace them for the actual program...
Upvotes: 3
Views: 1007
Reputation: 139241
import packages into SLIME's REPL
You can't import packages into SLIME's REPL, because such a concept does not exist. A 'REPL' can't import packages.
Symbols can belong to some package. Symbols can be imported into a package. You can also import exported symbols from one package into another.
The reader has a current package, the value of the symbol cl:*package*
. When you interact with Lisp, this package is used as the default package. Whenever you compile a file or type to something like a REPL, this default package is used.
You need to control what kind of package is being used. This is for example why you put an (in-package "FOO")
at the start of a file. You can also type (in-package "FOO")
to a REPL and then *package*
is the package named FOO
.
If you want to use symbols without a package qualifier (foo
instead of bar:foo
), then you either need to set *package*
to this package or to a package which imports these symbols.
So, all you have to do is to make sure that cl:package points to the correct package and if you import symbols, that you import those into the correct package.
Example:
CL-USER 191 > (defpackage "FOO" (:use "CL"))
#<The FOO package, 0/16 internal, 0/16 external>
CL-USER 192 > *package*
#<The COMMON-LISP-USER package, 155/256 internal, 0/4 external>
CL-USER 193 > (defpackage "FOO" (:use "CL"))
#<The FOO package, 0/16 internal, 0/16 external>
CL-USER 194 > cl:*package*
#<The COMMON-LISP-USER package, 155/256 internal, 0/4 external>
CL-USER 195 > (in-package "FOO")
#<The FOO package, 0/16 internal, 0/16 external>
FOO 196 > cl:*package*
#<The FOO package, 0/16 internal, 0/16 external>
Upvotes: 0
Reputation: 14065
If by "correctable error", you mean "name collision", that's an issue you can handle by defining your own packages and using the :shadow
and :shadowing-import-from
clauses. Check Chapter 21 of PCL for details.
Short answer: if you're trying to import a new symbol that's already defined in your current package, you need to do shadowing-import
instead of the standard import
(though you should really be using the corresponding clauses to defpackage
rather than calling those yourself).
For part two, what do you mean by "compile the function"? When I evaluate that second definition of nslookup-1
after shadowing-import
ing the two pieces from :sb-bsd-sockets
, it works fine. Are you sure you're trying to evaluate it in a package where you've already imported the appropriate functions?
Upvotes: 2