![]() | ![]() | ![]() | Starting GBBopen | ![]() |
This initial exercise requires that you:
:gbbopen-user
GBBopen requires a supported Common Lisp implementation. If one has already been installed on your system, then this step is finished. (That was easy!) If not, then you will need to choose, obtain, and install a Common Lisp implementation before moving on to the next step.
The list of Common Lisp implementations, with version numbers, on which GBBopen is supported is maintained on the “Current ports” page of the GBBopen Project web site. The list includes commercial products and open-source implementations made available under varying license arrangements. The vendors of commercial Common Lisp products offer no-cost “Trial” or “Personal” editions that can support the tutorial exercises and allow you to become familiar with their products before making a purchase decision.
Choosing a particular implementation is a subjective decision. Some Common Lisp implementations run on only a single platform. Some implementations do not provide multiprocessing (thread) support on some or all of the platforms that they run on. Some implementations come with their own integrated development environment (IDE), interactive graphics facilities, and supported libraries and extensions. When it comes to selecting an implementation, there is no “best” answer (but there is also no wrong answer, if the implementation meets your current needs). All these Common Lisp implementations strive to conform to the ANSI (American National Standards Institute) standard for the Common Lisp language. By writing GBBopen applications to remain consistent with the ANSI standard (including portable extensions to the standard that are provided by GBBopen), we can easily run our code on any Common Lisp implementation that provides similar capabilities (such as threads, for example).
However you choose to obtain Common Lisp, you must have an installed and operating implementation for your system before proceeding to the next step.
Unless someone has already installed GBBopen on your machine, you will need to
obtain and install it. GBBopen is available in source form from
http://GBBopen.org/
A snapshot archive of the GBBopen source-code repository can be downloaded
from
http://gbbopen.org/downloads/GBBopen.tar.gz
README
file of the installation.
Alternatively, if you are familiar with Subversion and have a Subversion client installed on your computer, you can checkout the latest files directly from the GBBopen repository. For example, the shell command:
[~]$ svn checkout http://GBBopen.org/svn/GBBopen/trunk/ gbbopenwill create a GBBopen repository tree rooted at the directory named
gbbopen
in your current working directory. As above, follow the
“Compiling All GBBopen Modules” instructions that are contained in the
README
file of the installation.
GBBopen development is ongoing, and you should update your GBBopen installation regularly in order to obtain the latest capabilities and enhancements. Subversion provides an easy way to keep current, and you are strongly encouraged to install a Subversion client and use it perform frequent updates. Simply issue the command:
[~/gbbopen]$ svn updatefrom the root directory of your GBBopen repository tree. The TortoiseSVN Subversion client is highly recommended for Windows users. TortoiseSVN is smoothly integrated with the Windows Shell (Explorer) and is as easy to use as TortoiseCVS (also highly recommended if aren't already using it as your CVS client on Windows).
Subversion .svn
administrative directories are included in the GBBopen
snapshot archive, so a Subversion update
command can be used to freshen
a GBBopen installation that was originally installed using the snapshot
archive download-and-extraction approach described previously.
If you use clbuild, you can use it to download the latest GBBopen sources by issuing the following command:
[~]$ clbuild install gbbopen
At any later time, you can issue the command:
[~]$ clbuild update gbbopento obtain the latest sources from the GBBopen repository.
If your clbuild doesn't know about GBBopen, add the following line to the clbuild wnpp-projects file:
gbbopen get_svn http://gbbopen.org/svn/GBBopen/trunk/ #blackboard-system framework, tools, & utilities
As was the case with the other two download methods, follow the “Compiling
All GBBopen Modules” instructions that are contained in the GBBopen
README
file to complete the installation.
If you use Quicklisp, you can use it to download and install GBBopen by evaluating the following form once Quicklisp is set up:
> (ql:quickload "gbbopen") ;; GBBopen is installed in <install-dir> ;; Your "home" directory is <homedir> ;; Predefining :SWANK-BACKEND package for SLIME... ;; No shared module command definitions were found in <install-dir>/gbbopen-modules/. ;; No personal module command definitions were found in <homedir>/gbbopen-modules/. ;; GBBopen is installed in <install-dir> ;; Your "home" directory is <homedir> ;; Loading <install-dir>/extended-repl.lisp ;; Loading <install-dir>/commands.lisp ;; Loading <install-dir>/gbbopen-modules-directory.lisp ;; No shared module command definitions were found in <install-dir>/gbbopen-modules/. ;; No personal module command definitions were found in <homedir>/gbbopen-modules/. ;; Defining an ASDF defsystem for each Module Manager module... To load "gbbopen": Load 1 ASDF system: gbbopen ; Loading "gbbopen" ("gbbopen") >
As was the case with the other download methods, follow the “Compiling
All GBBopen Modules” instructions that are contained in the GBBopen
README
file to complete the installation.
If you need help or advice, the GBBopen Forum is the place to ask (should this tutorial and a search of the Forum boards come up short). The posts and advice available there will save you time and frustration and get you writing quality GBBopen applications easier and sooner. Why not register right now?
This tutorial assumes that you have a basic understanding of Common Lisp and, in particular, how to interact with the Common Lisp implementation that you are using. Thus, you should be able to start up your Common Lisp system and enter forms into the “Lisp Listener” (also called the read-eval-print loop or simply the REPL) that it provides.
When you start your Common Lisp system, it may first display some informational messages and then you should see a prompt for input that looks something like:
>The specific format of the prompt differs depending on your Common Lisp implementation. The prompt character may vary, such as
*
, :
, or
?
. The prompt might include a entry number that is incremented each
time an expression is entered, such as:
[1]>or it might also include the name of the current package (symbol namespace) being used by the REPL:
cl-user(1)>
For the remainder of this tutorial, we will include the package name in our example prompts to make it clear what package should be current:
cl-user>The REPL prompt indicates that it is awaiting a Common Lisp expression to evaluate and then display the evaluation results. For example, enter the expression:
cl-user> (+ 1 2) 3 cl-user>Note that what you need to enter is shown in black and other items, such as the REPL prompt and displayed result,
3
, are shown in gray. We will
follow this convention throughout the tutorial to help make it clear what you
must provide in the context of other information.
You may find it easier and faster to cut and paste text from this tutorial (if you are working with it on-line) rather than typing what is requested. On the other hand, some feel that they learn faster (and improve retention) through the action of typing. Either text-entry approach, however, is preferable to simply reading through the exercises. This tutorial is about learning by doing!
While we are on the subject of what is displayed, enter the following expression:
cl-user> 'symbol symbol cl-user>The displayed result that you see might be in lower case, as shown, or upper case, or even capitalized. In this tutorial, results are shown with Common Lisp symbols displayed in lower case, which I prefer as being slightly easier to read. If you wish, you can duplicate this behavior in your REPL by entering the following form:
cl-user> (setf *print-case* ':downcase) :downcase cl-user>
Your Common Lisp implementation may also differ slightly on how it displays multiple returned values. For example:
cl-user> (values 1 2 3) 1 2 3 cl-user>
In this tutorial, we show multiple returned values as displayed on separate lines. Your Common Lisp implementation may show them differently, such as with semicolon value-separator characters:
cl-user> (values 1 2 3) 1 ; 2 ; 3 cl-user>
Even you are a very careful typist, sooner or later you will enter a Common Lisp expression that signals an error. Therefore, it is important that you know how to get back on track when the inevitable occurs. Let's intentionally generate an error. Enter:
cl-user> (/ 1 0) Error: Attempt to divide 1 by zero. cl-user>>
The behavior of your Common Lisp environment should look similar, and you should now be in your implementation's debugger or “break loop.” The debugger prompt may differ from the standard REPL prompt to help remind you that you are in the break loop. Alternatively, your implementation may open another window or buffer in response to the error. Your implementation may allow you to continue entering Common Lisp expressions at the break prompt that are evaluated and the results displayed just as if you were in the normal REPL (opening the possibility of causing another error and triggering another instance of the debugger). You can use the debugger to inspect the nesting, or “backtrace,” of function calls that led to the error, view and edit local variable bindings, and so forth, and you can often correct the cause of the error and resume the broken evaluation directly from the debugger.
For this tutorial, you only need to know how to abort out of the evaluation and return back to the REPL if you trigger an error. The details for aborting the computation and exiting the debugger are implementation dependent, so you may need to investigate how to abort out of an error on your Common Lisp implementation. For example, it might be as easy as entering an abort debugger command:
cl-user> (/ 1 0) Error: Attempt to divide 1 by zero. cl-user>> :a cl-user>Consult your Common Lisp documentation or a knowledgeable friend if you need assistance with the debugger in your Common Lisp implementation (
:a
or q
are typical abort commands).
There are other mistakes that don't signal an error. Suppose I foolishly evaluate this expression:
cl-user> (loop (print "This is repetitive...") (sleep 1))
"This is repetitive..."
"This is repetitive..."
...
Once I grow tired of watching this phrase repeat, it would be good to
terminate the evaluation without having to kill the entire Common Lisp
program.
Again, the specifics depend on your Common Lisp environment, but all that is
needed is to interrupt, or “break,” the computation. Often this is
associated with typing one or more Control-c (^c
) characters:
cl-user> (loop (print "This is repetitive...") (sleep 1))
"This is repetitive..."
"This is repetitive..."
...
"This is repetitive..."
"This is repetitive..."
"This is rep^C
Error: Received keyboard interrupt ^C
cl-user>>
Typically a keyboard interrupt invokes the debugger where the computation
can be resumed or aborted:
cl-user> (loop (print "This is repetitive...") (sleep 1))
"This is repetitive..."
"This is repetitive..."
...
"This is repetitive..."
"This is repetitive..."
"This is rep^C
Error: Received keyboard interrupt ^C
cl-user>> :a
cl-user>
Here is one last difficulty. Suppose I enter:
cl-user> (list "This" "is "also" "a" "problem!") cl-user> cl-user> cl-user>My REPL seems dead: no result is displayed and I continue to be prompted again and again for input. I suppose I should try the entering the expression again:
cl-user> (list "This" "is "also" "a" "problem!") cl-user> cl-user> cl-user> cl-user> (list "This" "is" "also" "a" "problem!") cl-user> cl-user>Nope, my REPL is still broken.
Of course the cause of the problem is that I forgot the closing double-quote
character on "is"
when I entered the first expression. The REPL is
still patiently waiting for me to finish that first Common Lisp expression.
(I didn't break it after all!)
So how do I get out of this? I could try entering a sequence of double-quote and close parentheses and hope I that I get lucky:
cl-user> (list "This" "is "also" "a" "problem!") cl-user> cl-user> cl-user> cl-user> (list "This" "is" "also" "a" "problem!") cl-user> cl-user> cl-user> " cl-user> ) Error: Attempt to take the value of the unbound variable `also'. cl-user>>or I could interrupt the REPL read operation, just as I did with the infinite loop situation above, and abort back from the debugger to the REPL and try again:
cl-user> (list "This" "is "also" "a" "problem!") cl-user> cl-user> cl-user> cl-user> (list "This" "is" "also" "a" "problem!") cl-user> cl-user> cl-user> ^C Error: Received keyboard interrupt ^C cl-user>> :a cl-user> (list "This" "is" "also" "a" "problem!") ("This" "is" "also" "a" "problem!") cl-user>
You may discover even more creative ways to get into problems, but these example situations should give you enough experience to get through the rest of the tutorial.
:gbbopen-user
moduleGBBopen is packaged with its own module system that supports compiling and loading GBBopen components.
To compile and load the :gbbopen-user
<install-dir>/initiate.lisp
cl-user> (load "<install-dir>/initiate.lisp")
;; Loading <install-dir>/initiate.lisp
;; GBBopen is installed in <install-dir>
;; Your "home" directory is <homedir>
;; Loading <install-dir>/extended-repl.lisp
;; Loading <install-dir>/commands.lisp
;; Loading <install-dir>/gbbopen-modules-directory.lisp
;; No shared module command definitions were found in <install-dir>/gbbopen-modules/.
;; No personal module command definitions were found in <homedir>/gbbopen-modules/.
#P"<install-dir>/initiate.lisp"
cl-user> :gbbopen-user
;; Loading <install-dir>/startup.lisp
;; GBBopen is installed in <install-dir>
;; Your "home" directory is <homedir>
;; Loading <install-dir>/source/module-manager/module-manager-loader.lisp
;; Loading <install-dir>/<platform-dir>/module-manager/module-manager.lisp
...
;; Loading <install-dir>/modules.lisp
;; No shared module definitions were found in <install-dir>/gbbopen-modules/.
;; No personal module definitions were found in <homedir>/gbbopen-modules/.
...
;; Compiling <install-dir>/source/gbbopen/gbbopen-user.lisp
;; Loading <install-dir>/<platform-dir>/gbbopen/gbbopen-user.fasl
t
gbbopen-user>
GBBopen should compile (if necessary) and load all the files needed for the
next exercise without error. The output on your Common Lisp implementation
may vary somewhat from that shown above. For example, the file extension for
compiled files, shown as .fasl
throughout this tutorial, is dependent on
your Common Lisp implementation and platform.
|
Note that when the :gbbopen-user
module was loaded, the Module Manager
changed the current package to the :gbbopen-user
cl-user> *package* #<package GBBOPEN-USER> gbbopen-user>
In Common Lisp, a package is a namespace that maps names to
symbols. One package is always designated as the “current” package, and it
is this package that is used by default for creating and finding symbols by
their names. Initially, the current package is set to the
:common-lisp-user
:gbbopen-user
:gbbopen-user
:gbbopen-user
If you are running GBBopen in a Common Lisp environment that doesn't support
REPL commands and the :gbbopen-user
<install-dir>/initiate.lisp
:common-lisp-user
cl-user> (load "<install-dir>/initiate.lisp")
;; Loading <install-dir>/initiate.lisp
;; GBBopen is installed in <install-dir>
;; Your "home" directory is <homedir>
;; Loading <install-dir>/extended-repl.lisp
;; Loading <install-dir>/commands.lisp
;; Loading <install-dir>/gbbopen-modules-directory.lisp
;; No shared module command definitions were found in <install-dir>/gbbopen-modules/.
;; No personal module command definitions were found in <homedir>/gbbopen-modules/.
#P"<install-dir>/initiate.lisp"
cl-user> (gbbopen-user)
;; Loading <install-dir>/startup.lisp
...
;; Loading <install-dir>/<platform-dir>/gbbopen/gbbopen-user.fasl
gbbopen-user>
If one or more GBBopen files needs to be compiled, you must have write
permission for those files and directories on your file system. If you do not
have write permission and someone else is maintaining your GBBopen
installation, you must remind them that they should perform the “Compiling
All GBBopen Modules” operations (described in the GBBopen installation
README
file) every time they update GBBopen to ensure that all the
latest GBBopen files have been compiled.
GBBopen's REPL commands are defined to mimic the syntax of existing REPL commands in your Common Lisp environment. REPL commands, including those that have arguments, are normally specified using a non-list (“spread”) representation. For example:
cl-user> :gbbopen-user :create-dirs
;; Loading <install-dir>/startup.lisp
...
;; Loading <install-dir>/<platform-dir>/gbbopen/gbbopen-user.fasl
gbbopen-user>
Some Common Lisp implementations (Clozure
CL,
LispWorks, and
SBCL) and the
SLIME REPL interface, also
support REPL commands in non-spread (list) form in addition to the
spread notation. For example:
cl-user> (:gbbopen-user :create-dirs)
;; Loading <install-dir>/startup.lisp
...
;; Loading <install-dir>/<platform-dir>/gbbopen/gbbopen-user.fasl
gbbopen-user>
As noted above, equivalent functions in the :common-lisp-user
cl-user> (cl-user:gbbopen-user :create-dirs)
;; Loading <install-dir>/startup.lisp
...
;; Loading <install-dir>/<platform-dir>/gbbopen/gbbopen-user.fasl
gbbopen-user>
We will show the spread command syntax throughout the rest of the Tutorial. (GBBopen's REPL commands are summarized in the GBBopen REPL Commands Quick Reference Card, available on the GBBopen web site.)
<install-dir>/initiate.lisp
Although loading GBBopen's <install-dir>/initiate.lisp
The GBBopen Project
![]() | ![]() | ![]() | Starting GBBopen | ![]() |