The correct way to define packages using asdf: defsystem and quickproject

I'm starting with Lisp, trying to figure out how to use the Lisp package system properly when learning LTK GUI programming using SBCL 1.0.55.0.debian and Limp 0.3.4 (and if it matters Debian Wheezy), I installed ASDF using the dispatcher aptitude packages (cl-asdf and cl-common-lisp -controller packages), then I installed Quicklisp using the instructions on the Quicklisp website ( http://www.quicklisp.org/beta/index.html ) (and not from Debian repository) and then I installed LTK with (ql:quickload 'ltk) in the SBCL console.

hello-1.lisp (directly from the LTK tutorial):

 (defun hello-1() (with-ltk () (let ((b (make-instance 'button :master nil :text "Press Me" :command (lambda () (format t "Hello World!~&"))))) (pack b)))) 

If I compile it directly in the new SBCL Lisp image, I get a message that WITH-LTK and PACK are undefined functions, and 'BUTTON is an undefined variable.

So, I found out that I need to download 'ltk first and then use in-package .I to be able to run it, I must first use (ql:quickload 'ltk) and (in-package :ltk) in the SBCL console . However, I am still an error message that 'BUTTON is an undefined variable.

 * (ql:quickload 'ltk) To load "ltk": Load 1 ASDF system: ltk ; Loading "ltk" (LTK) * (in-package :ltk) #<PACKAGE "LTK"> * (compile-file "/home/user/code/lisp/hello-1.lisp") ; caught WARNING: ; undefined variable: 'BUTTON ; ; compilation unit finished ; Undefined variable: ; 'BUTTON ; caught 1 WARNING condition ; /home/user/code/lisp/hello-1.fasl written ; compilation finished in 0:00:00.009 #P"/home/user/code/lisp/hello-1.fasl" T T * 

Then, since this did not work out the way I wanted, I also tried to define my own package definitions according to the answers of another question ( Problems with ltk (general lisp) , Xach blog post "Creating a small Lisp project with a quick project and Quicklisp" http://xach.livejournal.com/278047.html?thread=674335 and the ASDF manual ( http://common-lisp.net/project/asdf/asdf/The-defsystem-form.html ) using quickproject:make-project , but to no quickproject:make-project currently have the following files:

package.lisp ( (ql:quickload 'ltk) if I first (ql:quickload 'ltk) SBCL REPL):

 (defpackage :hello-world-ltk-system (:use :cl :asdf :ltk)) 

hello-world-ltk.asd (compiles cleanly after I compiled package.lisp first):

 (in-package :hello-world-ltk-system) (asdf:defsystem :hello-world-ltk :serial t :description "Describe hello-world-ltk here" :author "Your Name < your.name@example.com >" :license "Specify license here" :depends-on (:cl :asdf :ltk) :components ((:file "package") (:file "hello-world-ltk"))) 

hello-world-ltk.lisp (I get a compilation error The name "HELLO-WORLD-LTK" does not designate any package ).

 (require 'hello-world-ltk) (in-package :hello-world-ltk) (defun hello-world-1 () (with-ltk () (let ((b (make-instance 'button :master nil :text "Press me!" :command (lambda () (format t "Hello world!~&"))))) (pack b)))) 

When I try to compile this hello-world-ltk.lisp after successfully compiling package.lisp and hello-world-ltk.asd (which are all in the same directory), I get the following error:

 ; compiling (IN-PACKAGE :HELLO-WORLD-LTK) debugger invoked on a SB-KERNEL:SIMPLE-PACKAGE-ERROR in thread #<THREAD "initial thread" RUNNING {10029A0FA3}>: The name "HELLO-WORLD-LTK" does not designate any package. Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (SB-INT:%FIND-PACKAGE-OR-LOSE "HELLO-WORLD-LTK") 0] (load "/home/user/code/lisp/hello-world-ltk/hello-world-ltk") debugger invoked on a SIMPLE-ERROR in thread #<THREAD "initial thread" RUNNING {10029A0FA3}>: attempt to load an empty FASL file: "/home/user/code/lisp/hello-world-ltk/hello-world-ltk.fasl" Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Reduce debugger level (to debug level 1). 1: Exit debugger, returning to top level. (SB-FASL::LOAD-AS-FASL #<SB-SYS:FD-STREAM for "file /home/user/code/lisp/hello-world-ltk/hello-world-ltk.fasl" {1005291233}> NIL #<unavailable argument>) 0[2] 

So, I am completely lost here with all the different ways to define packages: ASDF, Quicklisp, package.lisp, quickproject , asdf:defsystem , require and ql:quickload ... quickproject:make-project looks promising, but I really don't know what not so with my source files yet. I am looking for a solution that should handle all compilation and package downloads, preferably in one command for the whole project, and this should also expand for large projects.

Thanks for any help :)

+7
source share
1 answer

The first problem in your code is using an apostrophe ( ' ) instead of a tick ( ' ). This is why you get an undefined variable error, since the 'button is read as the name of the variable (it is not quoted).

Now about packages and systems . a package is defined by defpackage and is a set of characters that are used after the in-package form inside a file (or in an interactive session). A package has internal and external (exported) symbols, which can be accessed as package::internal-symbol and package:external-symbol respectively. Packages can also be import characters from other packages. If you use-package , you import all external characters. So far, in-package switches the current package to the specified one, and you begin to define characters in it (and it is undesirable to do such things in third-party packages, for example LTK ). Therefore, if you want to use LTK characters, such as with-ltk or button , you just need to either use-package LTK or import these characters from LTK in the form of defpackage :

 (defpackage :hello-world-ltk-system (:use :cl) (:import-from :ltk :with-ltk :button)) 

or just import all the LTK characters (with the use clause):

 (defpackage :hello-world-ltk-system (:use :cl :ltk)) 

Finally, systems and packages are completely unrelated things. System is an instance of the ASDF:SYSTEM class that contains information about physical files and their relationships so that they can be compiled and loaded accordingly. For your hello-world application, I would assume that at the moment you are not worried about the systems and write all your code in one file. This file should start with a defpackage form, followed by an in-package , and then the rest of your code.

When this file becomes large enough, you will see clear parts in it, you can divide these parts into separate files. Then you will need to create a system definition file that looks like this:

 (asdf:defsystem :hello-world :depends-on (:ltk) :serial t :components ((:file "package") (:file "first") (:file "second") ...)) 

The "package.lisp" file will show the definition of your package.

+9
source

All Articles