source: tags/0.26.0/abcl/doc/manual/abcl.tex

Last change on this file was 13372, checked in by Mark Evenson, 13 years ago

Document the extension to CLOS specialization for Java objects.

File size: 13.3 KB
Line 
1% http://en.wikibooks.org/wiki/LaTeX/
2
3\include{index.sty}
4
5\begin{document}
6\title{A Manual for Armed Bear Common Lisp}
7\date{June 17, 2011}
8\author{Mark Evenson, Erik Huelsmann, Alessio Stallo, Ville Voutilainen}
9
10\section{Introduction}
11\subsection{Version}
12
13This manual corresponds to abcl-0.26.0, as yet unreleased.
14
15\section{Obtaining}
16
17\subsection{Source Repositories}
18
19\begin[shell]{code} 
20  svn co http://svn.common-lisp.net/armedbear/trunk abcl
21\end{code}
22
23\subsection{Requirements}
24
25java-1.5.xx, java-1.6.0_10+ recommended.
26
27\subsection{Building from Source}
28
29There are three ways to build ABCL from the source release with the
30preferred (and most tested way) is to being to use the Ant build tool:
31
32\begin{itemize}
33
34\item Use the Ant build tool for Java environments.
35
36\item Use the Netbeans 6.x IDE to open ABCL as a project.
37
38\item Bootstrap ABCL using a Common Lisp implementation. Supported
39  implementations for this process: SBCL, CMUCL, OpenMCL, Allegro
40  CL, LispWorks or CLISP.
41\end{itemize}
42
43In all cases you need a Java 5 or later JDK (JDK 1.5 and 1.6 have been
44tested).  Just the JRE isn't enough, as you need the Java compiler
45('javac') to compile the Java source of the ABCL implementation.
46
47Note that when deploying ABCL having JDK isn't a requirement for the
48installation site, just the equivalent JRE, as ABCL compiles directly
49to byte code, avoiding the need for the 'javac' compiler in deployment
50environments.
51
52
53\subsubsection{Using Ant}
54
55Download a binary distribution [Ant version 1.7.1 or greater][1].
56Unpack the files somewhere convenient, ensuring that the 'ant' (or
57'ant.bat' under Windows) executable is in your path and executable.
58
59[1]: http://ant.apache.org/bindownload.cgi
60
61Then simply executing
62
63\begin[shell]{code}
64       unix$ ant
65\end{code}
66
67or
68
69\begin[shell]{code}
70    dos> ant.bat
71\end{code}
72
73from the directory containing this README file will create an
74executable wrapper ('abcl' under UNIX, 'abcl.bat' under Windows).  Use
75this wrapper to start ABCL.
76
77
78\subsubsection{Using NetBeans}
79
80Obtain and install the [Netbeans IDE][2]. One should be able to open
81the ABCL directory as a project in the Netbeans 6.x application,
82whereupon the usual build, run, and debug targets as invoked in the
83GUI are available.
84
85[2]: http://netbeans.org/downloads/
86
87
88\subsubsection{Building from Lisp}
89
90
91Building from a Lisp is the most venerable and untested way of
92building ABCL.  It produces a "non-standard" version of the
93distribution that doesn't share build instructions with the previous
94two methods, but it still may be of interest to those who absolutely
95don't want to know anything about Java.
96
97First, copy the file 'customizations.lisp.in' to 'customization.lisp',
98in the directory containing this README file, editing to suit your
99situation, paying attention to the comments in the file.  The critical
100step is to have Lisp special variable '*JDK*' point to the root of the
101Java Development Kit.  Underneath the directory referenced by the
102value of '*JDK*' there should be an exectuable Java compiler in
103'bin/javac' ('bin/java.exe' under Windows).
104
105Then, one may either use the 'build-from-lisp.sh' shell script or load
106the necessary files into your Lisp image by hand.
107
108\paragraph{Using the 'build-from-lisp.sh' script}
109
110Under UNIX-like systems, you may simply invoke the
111'build-from-lisp.sh' script as './build-from-lisp.sh
112<lisp-of-choice>', e.g.
113
114\begin[shell]{code}
115    unix$ ./build-from-lisp.sh sbcl
116\end{code}
117
118After a successful build, you may use \file{abcl} (\file{abcl.bat} on
119Windows) to start ABCL.  Note that this wrappers contain absolute
120paths, so you'll need to edit them if you move things around after the
121build.
122
123If you're developing on ABCL, you may want to use
124
125\begin[shell]{code}
126    unix$ ./build-from-lisp.sh <implementation> --clean=nil
127\end{code}
128
129to not do a full rebuild.
130
131In case of failure in the javac stage, you might try this:
132
133\begin[shell]{code}
134    unix$ ./build-from-lisp.sh <implementation> --full=t --clean=t --batch=nil
135\end{code}
136
137This invokes javac separately for each .java file, which avoids running
138into limitations on command line length (but is a lot slower).
139
140\subsubsubsection{Building from another Lisp by hand}
141
142There is also an ASDF definition in 'abcl.asd' for the BUILD-ABCL
143which can be used to load the necessary Lisp definitions, after which
144
145\begin[lisp]{code}
146    CL-USER> (build-abcl:build-abcl :clean t :full t)
147\end{code}
148
149will build ABCL.  If ASDF isn't present, simply LOAD the
150'customizations.lisp' and 'build-abcl.lisp' files to achieve the same
151effect as loading the ASDF definition.
152
153\subsection{Contributing}
154
155\section{Interaction with host JVM}
156
157% describe calling Java from Lisp, and calling Lisp from Java,
158% probably in two separate sections.  Presumably, we can partition our
159% audience into those who are more comfortable with Java, and those
160% that are more comforable with Lisp
161
162\subsection{Lisp to Java}
163
164ABCL offers a number of mechanisms to manipulate Java libraries from
165Lisp.
166
167\begin{itemize}
168\item Java values are accessible as objects of type JAVA:JAVA-OBJECT.
169\item The Java FFI presents a Lisp package (JAVA) with many useful
170  symbols for manipulating the artifacts of expectation on the JVM,
171  including creation of new objects \ref{JAVA:JNEW}, \ref{JAVA:JMETHOD}), the
172  introspection of values \ref{JAVA:JFIELD}, the execution of methods
173  (\ref{JAVA:JCALL}, \ref{JAVA:JCALL-RAW}, \ref{JAVA:JSTATIC})
174\item The JSS package (\ref{JSS}) in contrib introduces a convenient macro
175  syntax \ref{JSS:SHARPSIGN_DOUBLEQUOTE_MACRO} for accessing Java
176  methods, and additional convenience functions.
177\item Java classes and libraries may be dynamically added to the
178  classpath at runtime (JAVA:ADD-TO-CLASSPATH).
179\end{itemize}
180
181\subsection{Lisp from Java}
182
183Manipulation of the Lisp API is currently lacking a stable interface,
184so what is documented here is subject to change. 
185
186\begin{itemize}
187\item All Lisp values are descendants of LispObject.java
188\item Lisp symbols are accessible via either directly referencing the
189  Symbol.java instance or by dynamically introspecting the
190  corresponding Package.java instance.
191\item The Lisp dynamic environment may be saved via
192  \code{LispThread.bindSpecial(BINDING)} and restored via
193  LispThread.resetSpecialBindings(mark).
194\item Functions may be executed by invocation of the
195  Function.execute(args [...])
196\end{itemize}
197
198\subsubsection{Lisp FFI}
199
200FFI stands for "Foreign Function Interface" which is the phase which
201the contemporary Lisp world refers to methods of "calling out" from
202Lisp into "foreign" languages and environments.  This document
203describes the various ways that one interacts with Lisp world of ABCL
204from Java, considering the hosted Lisp as the "Foreign Function" that
205needs to be "Interfaced".
206
207\subsubsubsection{Calling Lisp from Java}
208
209Note: As the entire ABCL Lisp system resides in the org.armedbear.lisp
210package the following code snippets do not show the relevant import
211statements in the interest of brevity.  An example of the import
212statement would be
213
214\begin[java]{code}
215  import org.armedbear.lisp.*;
216\end{document}
217
218to potentially import all the JVM symbol from the `org.armedbear.lisp'
219namespace.
220
221Per JVM, there can only ever be a single Lisp interpreter.  This is
222started by calling the static method `Interpreter.createInstance()`.
223
224\begin[java]{code}
225  Interpreter interpreter = Interpreter.createInstance();
226\end{code}
227
228If this method has already been invoked in the lifetime of the current
229Java process it will return null, so if you are writing Java whose
230life-cycle is a bit out of your control (like in a Java servlet), a
231safer invocation pattern might be:
232
233\begin[java]{code}
234  Interpreter interpreter = Interpreter.getInstance();
235  if (interpreter == null) {
236    interpreter = Interpreter.createInstance();
237  }
238\end{code}
239
240
241
242The Lisp \code{eval} primitive may be simply passed strings for evaluation,
243as follows
244
245\begin[java]{code}
246  String line = "(load \"file.lisp\")";
247  LispObject result = interpreter.eval(line);
248\end{code}
249
250Notice that all possible return values from an arbitrary Lisp
251computation are collapsed into a single return value.  Doing useful
252further computation on the `LispObject` depends on knowing what the
253result of the computation might be, usually involves some amount
254of \code{instanceof} introspection, and forms a whole topic to itself
255(c.f. [Introspecting a LispObject](#introspecting)). 
256
257Using `EVAL` involves the Lisp interpreter.  Lisp functions may be
258directly invoked by Java method calls as follows.  One simply locates
259the package containing the symbol, then obtains a reference to the
260symbol, and then invokes the `execute()` method with the desired
261parameters.
262
263\begin[java]{code}
264    interpreter.eval("(defun foo (msg) (format nil \"You told me '~A'~%\" msg))");
265    Package pkg = Packages.findPackage("CL-USER");
266    Symbol foo = pkg.findAccessibleSymbol("FOO");
267    Function fooFunction = (Function)foo.getSymbolFunction();
268    JavaObject parameter = new JavaObject("Lisp is fun!");
269    LispObject result = fooFunction.execute(parameter);
270    // How to get the "naked string value"?
271    System.out.prinln("The result was " + result.writeToString());
272\end{code}
273
274If one is calling an primitive function in the CL package the syntax
275becomes considerably simpler if we can locate the instance of
276definition in the ABCL source, we can invoke the symbol directly.  To
277tell if a `LispObject` contains a reference to a symbol.
278
279\begin[java]{code}
280    boolean nullp(LispObject object) {
281      LispObject result = Primitives.NULL.execute(object);
282      if (result == NIL) {
283        return false;
284      }
285      return true;
286   }
287\end{code}
288
289\paragraph{Introspecting a LispObject}
290\label{topic:Introspecting a LispObject}
291
292We present various patterns for introspecting an an arbitrary
293`LispObject` which can represent the result of every Lisp evaluation
294into semantics that Java can meaniningfully deal with.
295
296\paragragh{LispObject as \code{boolean}}
297
298If the LispObject a generalized boolean values, one can use
299\java{getBooleanValue()} to convert to Java:
300
301\begin[java]{code}
302     LispObject object = Symbol.NIL;
303     boolean javaValue = object.getBooleanValue();
304\end{code}
305
306Although since in Lisp, any value other than NIL means "true", the
307use of Java equality it quite a bit easier and more optimal:
308
309\begin[java]{code}}
310    boolean javaValue = (object != Symbol.NIL);
311\end{code}
312
313\subsubsubsubsection{LispObject is a list}
314
315If LispObject is a list, it will have the type `Cons`.  One can then use
316the \code{copyToArray} to make things a bit more suitable for Java
317iteration.
318
319\begin[java]{code}
320    LispObject result = interpreter.eval("'(1 2 4 5)");
321    if (result instanceof Cons) {
322      LispObject array[] = ((Cons)result.copyToArray());
323      ...
324    }
325\end{code}
326   
327A more Lispy way to iterated down a list is to use the `cdr()` access
328function just as like one would traverse a list in Lisp:;
329
330\begin[java]{code}
331    LispObject result = interpreter.eval("'(1 2 4 5)");
332    while (result != Symbol.NIL) {
333      doSomething(result.car());
334      result = result.cdr();
335    }
336\end{code}
337
338
339\subsection{JAVA}
340
341% include autogen docs for the JAVA package.
342
343\section{ANSI Common Lisp Conformance}
344
345ABCL is currently a non-conforming ANSI Common Lisp implementation due
346to the following (known) issues:
347
348\begin{itemize}
349  \item Lack of long form of DEFINE-METHOD-COMBINATION
350  \item Missing statement of conformance in accompanying documentation
351  \item Incomplete MOP
352    % TODO go through AMOP with symbols, starting by looking for
353    % matching function signature.
354    % XXX is this really blocking ANSI conformance?  Answer: we have
355    % to start with such a ``census'' to determine what we have.
356\end{itemize}
357
358ABCL aims to be be a fully conforming ANSI Common Lisp
359implementation.  Any other behavior should be reported as a bug.
360
361\section{Extensions}
362
363The symbols in the EXTENSIONS package consititutes extensions to the
364ANSI standard that are potentially useful to the user.  They include
365functions for manipulating network sockets, running external programs,
366registering object finalizers, constructing reference weakly held by
367the garbage collector and others.
368
369\include{extensions}
370
371\subsection{Beyond ANSI}
372
373Naturally, in striving to be a useful contemporary Common Lisp
374implementation, ABCL endeavors to include extensions beyond the ANSI
375specification which are either widely adopted or are especially useful
376in working with the hosting JVM.
377
378\subsubsection{Extensions to CLOS}
379
380There is an additional syntax for specializing the parameter of a
381generic function on a java class, viz. (java:jclass CLASS__STRING)
382where CLASS__STRING is a string naming a Java class in dotted package
383form.
384
385For instance the following specialization would perhaps allow one to
386print more information about the contents of a java.util.Collection
387object
388
389\begin[java]{code}
390(defmethod print-object ((coll (java:jclass "java.util.Collection")) stream)
391 â€Š
392 \end[java]{code}
393
394If the class had been loaded via a classloader other than the original
395the class you wish to specialize on, one needs to specify the
396classloader as an optional third argument.
397
398\begin[java]{code}
399(defmethod print-object ((device-id (java:jclass "dto.nbi.service.hdm.alcatel.com.NBIDeviceID"
400                                    (#"getBaseLoader" cl-user::*classpath-manager*)))
401 â€Š
402 \end[java]{code}
403
404
405\section{Multithreading}
406
407% TODO document the THREADS package.
408\include{threads}
409
410\section{History}
411
412\end{document}
413
414% TODO
415%   1.  Create mechanism for swigging DocString and Lisp docs into
416%       sections.
417
Note: See TracBrowser for help on using the repository browser.