3

I've set up quicklisp (with latest SBCL) and done

* (ql:quickload "draw-cons-tree")

and I get the reply

To load "draw-cons-tree":
  Load 1 ASDF system:
    draw-cons-tree
; Loading "draw-cons-tree"

("draw-cons-tree")

I check my quicklisp directory and I see it's been downloaded, essentially exactly these contents. So how do I actually use draw-cons-tree in the SBCL REPL that I have opened? The github sites says:

* (draw-tree '(a b (c nil 1)))

should produce

[o|o]---[o|o]---[o|/]
 |       |       |      
 A       B      [o|o]---[o|o]---[o|/]
                 |       |       |      
                 C      NIL      1      
NIL

but I'm just getting

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {10005385B3}>:
  The function COMMON-LISP-USER::DRAW-TREE is undefined. 

What am I missing here? My only other real experience with quicklisp has been slime, which had a specific .el file to call in Emacs to get slime going. Do I need to drill down into the directory

~/quicklisp/dists/quicklisp/software/draw-cons-tree-20131003-git/draw-cons-tree.lisp

and load the beast each time I want to use it? I tried that and, strangely for me at least, I get a list of WARNINGs of redefined functions, one is draw-tree. So my REPL knows about draw-tree but doesn't? What am I missing here?

147pm
  • 2,137
  • 18
  • 28
  • 3
    The system `draw-cons-tree` defines a package named `DRAW-CONS-TREE`, which exports a function named `DRAW-TREE`. To call the function, you must either use the package qualified name for it, ie. `(draw-cons-tree:draw-tree ...)`, or import the function name into the current package (eg. by using `(use-package :draw-cons-tree)`). – jkiiski Apr 04 '19 at 05:40

1 Answers1

11

Quicklisp loads a system, which may add zero, one or more packages to your environment. Sometimes the names of those packages are easy to guess, like when you install system cl-ppcre, you have a package named "CL-PPCRE" from which you can run things. Sometimes you must read the documentation to know how to use a system you installed.

But in case you are looking for a specific function, then you can use apropos:

CL-USER> (apropos "draw-tree")
DRAW-CONS-TREE::%DRAW-TREE
DRAW-CONS-TREE:DRAW-TREE (fbound)
:DRAW-TREE (bound)

Here, there is one exported symbol, either call it with its name fully qualified:

(DRAW-CONS-TREE:DRAW-TREE ...)

Or use the package first, so that the symbol is accessible from the current package:

> (use-package "DRAW-CONS-TREE")
> (draw-tree ...)

Alternatively, define a new package that uses the package, or go in that package with in-package to have access to its symbols, etc.

See Programming in the Large: Packages and Symbols.

coredump
  • 37,664
  • 5
  • 43
  • 77
  • 1
    I will read the Seibel chapter. However, I killed my sbcl repl, restarted -- but had to do another `(ql:quickload "draw-cons-tree")` to get `draw-cons-tree` back. Interesting. I thought `(ql:quickload "draw-cons-tree")` installed it and made any subsequent repl find it. I guess I'm used to Emacs doing a `(require 'xyz)` JIT behind the scenes. – 147pm Apr 04 '19 at 15:47
  • @147pm quickload fetches the system under the quicklisp/ directory (so that subsequent quickload don't fetch it again), then loads the system *in the current environment*" (restarting Sbcl, like restarting Emacs, clears the runtime state). Emacs has a special "autoload" feature that make "require" now what file to load; Modules, a.k.a. the require/provide approach that also exists in CL is not recommended anymore; ASDF is a better replacement (quicklisp relies on ASDF). Typically you just describe your own ASDF system "foo", notably its dependencies, and just call (ql:quickload "foo"). – coredump Apr 04 '19 at 16:14