1 | % TODO |
---|
2 | % 1. Create mechanism for swigging DocString and Lisp docs into |
---|
3 | % sections. |
---|
4 | |
---|
5 | |
---|
6 | \documentclass[10pt]{article} |
---|
7 | |
---|
8 | \usepackage{color,hyperref} |
---|
9 | \definecolor{darkblue}{rgb}{0.0,0.0,0.3} |
---|
10 | \hypersetup{colorlinks,breaklinks, |
---|
11 | linkcolor=darkblue,urlcolor=darkblue, |
---|
12 | anchorcolor=darkblue,citecolor=darkblue} |
---|
13 | |
---|
14 | \usepackage{a4wide} |
---|
15 | |
---|
16 | \begin{document} |
---|
17 | \title{A Manual for Armed Bear Common Lisp} |
---|
18 | \date{June 16, 2011} |
---|
19 | \author{Mark Evenson, Erik Huelsmann, Alessio Stallo, Ville Voutilainen} |
---|
20 | |
---|
21 | \section{Introduction} |
---|
22 | \subsection{Version} |
---|
23 | |
---|
24 | This manual corresponds to abcl-0.26.0, as yet unreleased. |
---|
25 | |
---|
26 | \section{Obtaining} |
---|
27 | |
---|
28 | \subsection{Requirements} |
---|
29 | |
---|
30 | java-1.5.xx, java-1.6.0_10+ recommended. |
---|
31 | |
---|
32 | \subsection{Building from Source} |
---|
33 | % TODO repeat install |
---|
34 | |
---|
35 | \subsection{Contributing} |
---|
36 | |
---|
37 | \section{Interaction with host JVM} |
---|
38 | |
---|
39 | % describe calling Java from Lisp, and calling Lisp from Java, |
---|
40 | % probably in two separate sections. Presumably, we can partition our |
---|
41 | % audience into those who are more comfortable with Java, and those |
---|
42 | % that are more comforable with Lisp |
---|
43 | |
---|
44 | \subsection{Lisp to Java} |
---|
45 | |
---|
46 | ABCL offers a number of mechanisms to manipulate Java libraries from |
---|
47 | Lisp. |
---|
48 | |
---|
49 | \begin{itemize} |
---|
50 | \item Java values are accessible as objects of type JAVA:JAVA-OBJECT. |
---|
51 | \item The Java FFI presents a Lisp package (JAVA) with many useful |
---|
52 | symbols for manipulating the artifacts of executation on the JVM, |
---|
53 | including creation of new objects (JAVA:JNEW, JAVA:JMETHOD), the |
---|
54 | introspection of values (JAVA:JFIELD), the execution of methods |
---|
55 | (JAVA:JCALL, JAVA:JCALL-RAW, JAVA:JSTATIC) |
---|
56 | \item The JSS package (JSS) in contrib introduces a convenient macro |
---|
57 | syntax (JSS:SHARPSIGN_HASH_DOUBLQUOTE_MACRO) for accessing Java |
---|
58 | methods, and additional convenience funtions. |
---|
59 | \item Java classes and libraries may be dynamically added to the |
---|
60 | classpath at runtime (JAVA:ADD-TO-CLASSPATH). |
---|
61 | \end{itemize} |
---|
62 | |
---|
63 | \subsection{Lisp from Java} |
---|
64 | |
---|
65 | Manipulation of the Lisp API is currently lacking a stable interface, |
---|
66 | so what is documented here is subject to change. |
---|
67 | |
---|
68 | \begin{itemize} |
---|
69 | \item All Lisp values are descendents of LispObject.java |
---|
70 | \item Lisp symbols are accessible via either directly referening the |
---|
71 | Symbol.java instance or by dynamically introspecting the |
---|
72 | corresponding Package.java instance. |
---|
73 | \item The Lisp dynamic envrionment may be saved via |
---|
74 | LispThread.bindSpecial(BINDING) and restored via |
---|
75 | LispThread.resetSpecialBindings(mark). |
---|
76 | \item Functions may be executed by invocation of the |
---|
77 | Function.execute(args [...]) |
---|
78 | \end{itemize} |
---|
79 | |
---|
80 | \subsubsection{Lisp FFI} |
---|
81 | |
---|
82 | FFI stands for "Foreign Function Interface", which is the way the |
---|
83 | contemporary Lisp world refers to methods of "calling out" from Lisp |
---|
84 | into "foreign" langauges and envrionments. This document describes |
---|
85 | the various ways that one interacts with Lisp world of Abcl from Java, |
---|
86 | considering the hosted Lisp as the "Foreign Function" that needs to be |
---|
87 | "Interfaced". |
---|
88 | |
---|
89 | |
---|
90 | \subsubsubsection{Calling Lisp from Java} |
---|
91 | |
---|
92 | Note: As the entire ABCL Lisp system resides in the org.armedbear.lisp |
---|
93 | package the following code snippets do not show the relevant import |
---|
94 | statements in the interest of brevity. |
---|
95 | |
---|
96 | Per JVM, there can only ever be a single Lisp interpreter. This is |
---|
97 | started by calling the static method `Interpreter.createInstance()`. |
---|
98 | |
---|
99 | \begin{code}{java} |
---|
100 | Interpreter interpreter = Interpreter.createInstance(); |
---|
101 | \end{code} |
---|
102 | |
---|
103 | If this method has already been invoked in the lifetime of the current |
---|
104 | Java process it will return null, so if you are writing Java whose |
---|
105 | lifecycle is a bit out of your control (like in a Java servlet), a |
---|
106 | safer invocation pattern might be: |
---|
107 | |
---|
108 | \begin{code}{java} |
---|
109 | Interpreter interpreter = Interpreter.getInstance(); |
---|
110 | if (interpreter == null) { |
---|
111 | interpreter = Interpreter.createInstance(); |
---|
112 | } |
---|
113 | \end{code} |
---|
114 | |
---|
115 | |
---|
116 | |
---|
117 | The Lisp `EVAL` primitive may be simply passed strings for evaluation, |
---|
118 | as follows |
---|
119 | |
---|
120 | \begin{code}{java} |
---|
121 | String line = "(load \"file.lisp\")"; |
---|
122 | LispObject result = interpreter.eval(line); |
---|
123 | \end{code} |
---|
124 | |
---|
125 | |
---|
126 | Notice that all possible return values from an arbitrary Lisp |
---|
127 | computation are collapsed into a single return value. Doing useful |
---|
128 | further computation on the `LispObject` depends on knowing what the |
---|
129 | result of the computation might be, usually involves some amount |
---|
130 | of instanceof introspection, and forms a whole topic to itself |
---|
131 | (c.f. [Introspecting a LispObject](#introspecting)). |
---|
132 | |
---|
133 | Using `EVAL` involves the Lisp interpreter. Lisp functions may be |
---|
134 | directly invoked by Java method calls as follows. One simply locates |
---|
135 | the package containing the symbol, then obtains a reference to the |
---|
136 | symbol, and then invokes the `execute()` method with the desired |
---|
137 | parameters. |
---|
138 | |
---|
139 | \begin{code}{java} |
---|
140 | interpreter.eval("(defun foo (msg) (format nil \"You told me '~A'~%\" msg))"); |
---|
141 | Package pkg = Packages.findPackage("CL-USER"); |
---|
142 | Symbol foo = pkg.findAccessibleSymbol("FOO"); |
---|
143 | Function fooFunction = (Function)foo.getSymbolFunction(); |
---|
144 | JavaObject parameter = new JavaObject("Lisp is fun!"); |
---|
145 | LispObject result = fooFunction.execute(parameter); |
---|
146 | // How to get the "naked string value"? |
---|
147 | System.out.prinln("The result was " + result.writeToString()); |
---|
148 | \end{code} |
---|
149 | |
---|
150 | If one is calling an primitive function in the CL package the syntax |
---|
151 | becomes considerably simpler if we can locate the instance of |
---|
152 | definition in the ABCL source, we can invoke the symbol directly. To |
---|
153 | tell if a `LispObject` contains a reference to a symbol. |
---|
154 | |
---|
155 | \begin{code}{java} |
---|
156 | boolean nullp(LispObject object) { |
---|
157 | LispObject result = Primitives.NULL.execute(object); |
---|
158 | if (result == NIL) { |
---|
159 | return false; |
---|
160 | } |
---|
161 | return true; |
---|
162 | } |
---|
163 | |
---|
164 | \end{code} |
---|
165 | |
---|
166 | /subsubsubsection{Introspecting a LispObject} |
---|
167 | |
---|
168 | We present various patterns for introspecting an an arbitrary |
---|
169 | `LispObject` which can represent the result of every Lisp evaluation |
---|
170 | into semantics that Java can meaniningfully deal with. |
---|
171 | |
---|
172 | /subsubsubsubsection{LispObject as \java{boolean}} |
---|
173 | |
---|
174 | If the LispObject a generalized boolean values, one can use |
---|
175 | \java{getBooleanValue()} to convert to Java: |
---|
176 | |
---|
177 | \begin{code}{java} |
---|
178 | LispObject object = Symbol.NIL; |
---|
179 | boolean javaValue = object.getBooleanValue(); |
---|
180 | \end{code} |
---|
181 | |
---|
182 | Although since in Lisp, any value other than NIL means "true", the |
---|
183 | use of Java equality it quite a bit easier and more optimal: |
---|
184 | |
---|
185 | \begin{code}{java} |
---|
186 | boolean javaValue = (object != Symbol.NIL); |
---|
187 | \end{code} |
---|
188 | |
---|
189 | /subsubsubsubsection{LispObject is a list} |
---|
190 | |
---|
191 | If LispObject is a list, it will have the type `Cons`. One can then use |
---|
192 | the `copyToArray[]` to make things a bit more suitable for Java |
---|
193 | iteration. |
---|
194 | |
---|
195 | \begin{code}{java} |
---|
196 | LispObject result = interpreter.eval("'(1 2 4 5)"); |
---|
197 | if (result instanceof Cons) { |
---|
198 | LispObject array[] = ((Cons)result.copyToArray()); |
---|
199 | ... |
---|
200 | } |
---|
201 | \end{code} |
---|
202 | |
---|
203 | A more Lispy way to iterated down a list is to use the `cdr()` access |
---|
204 | function just as like one would traverse a list in Lisp:; |
---|
205 | |
---|
206 | \begin{code}{java} |
---|
207 | LispObject result = interpreter.eval("'(1 2 4 5)"); |
---|
208 | while (result != Symbol.NIL) { |
---|
209 | doSomething(result.car()); |
---|
210 | result = result.cdr(); |
---|
211 | } |
---|
212 | \end{code} |
---|
213 | |
---|
214 | |
---|
215 | \subsection{JAVA} |
---|
216 | |
---|
217 | % include autogen docs for the JAVA package. |
---|
218 | |
---|
219 | \section{ANSI Common Lisp Conformance} |
---|
220 | |
---|
221 | ABCL is currently a non-conforming ANSI Common Lisp implementation due |
---|
222 | to the following (known) issues: |
---|
223 | |
---|
224 | \begin{itemize} |
---|
225 | \item Lack of long form of DEFINE-METHOD-COMBINATION |
---|
226 | \item Missing statement of conformance in accompanying documentation |
---|
227 | \item Incomplete MOP |
---|
228 | % TODO go through AMOP with symbols, starting by looking for |
---|
229 | % matching function signature. |
---|
230 | \end{itemize} |
---|
231 | |
---|
232 | ABCL aims to be be a fully conforming ANSI Common Lisp |
---|
233 | implementation. Any other behavior should be reported as a bug. |
---|
234 | |
---|
235 | \section{Extensions} |
---|
236 | |
---|
237 | % TODO document the EXTENSIONS package. |
---|
238 | |
---|
239 | \section{Multithreading} |
---|
240 | |
---|
241 | % TODO document the THREADS package. |
---|
242 | |
---|
243 | \section{History} |
---|
244 | |
---|
245 | \end{document} |
---|