Changeset 13634


Ignore:
Timestamp:
10/20/11 08:29:05 (9 years ago)
Author:
Mark Evenson
Message:

Examples of JSS usage.

Re-formatted JSR-223 constribution (Thanks Alessio!)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/doc/manual/abcl.tex

    r13628 r13634  
    66\begin{document}
    77\title{A Manual for Armed Bear Common Lisp}
    8 \date{October 13, 2011}
     8\date{October 20, 2011}
    99\author{Mark~Evenson, Erik~Huelsmann, Alessio~Stalla, Ville~Voutilainen}
    1010
     
    2727executed under the control of a suitable JVM by using the ``-jar''
    2828option to parse the manifest, and select the named class
    29 (\code{org.armedbear.lisp.Main}) for excution:
     29(\code{org.armedbear.lisp.Main}) for execution:
    3030
    3131\begin{listing-shell}
     
    141141by their name ending with \code{-RAW}.
    142142
    143 \subsection{Lowlevel Java API}
     143\subsection{Low-level Java API}
    144144
    145145There's a higher level Java API defined in the
     
    154154
    155155\begin{itemize}
    156 \item Call a specific method reference (pre-acquired)
     156\item Call a specific method reference (which was previously acquired)
    157157\item Dynamic dispatch using the method name and
    158158  the call-specific arguments provided by finding the
     
    236236that is used first by \code{JAVA:JCALL} and similar to resolve methods;
    237237the actual class of the object is only tried if the method is not found
    238 in the intended class. Of course, the intended class is always a superclass
     238in the intended class. Of course, the intended class is always a super-class
    239239of the actual class - in the worst case, they coincide. The intended class
    240240is deduced by the return type of the method that originally returned
     
    393393becomes considerably simpler.  If we can locate the instance of
    394394definition in the ABCL Java source, we can invoke the symbol directly.
    395 For instnace, to tell if a `LispObject` contains a reference to a symbol.
     395For instance, to tell if a `LispObject` contains a reference to a symbol.
    396396
    397397\begin{listing-java}
    398398    boolean nullp(LispObject object) {
    399399      LispObject result = Primitives.NULL.execute(object);
    400       if (result == NIL) { // the symbol 'NIL' is explicity named in the Java
     400      if (result == NIL) { // the symbol 'NIL' is explicitly named in the Java
    401401                           // namespace at ``Symbol.NIL''
    402402                           // but is always present in the
    403                            // localnamespace in its unadorned form for
     403                           // local namespace in its unadorned form for
    404404                           // the convenience of the User.
    405405        return false;
     
    462462\subsection{Java Scripting API (JSR-223)}
    463463
    464 ABCL can be built with support for JSR-223, which offers a language-agnostic
    465 API to invoke other languages from Java. The binary distribution downloadable
    466 from ABCL's common-lisp.net home is built with JSR-223 support. If you're building
    467 ABCL from source on a pre-1.6 JVM, you need to have a JSR-223 implementation in your
    468 CLASSPATH (such as Apache Commons BSF 3.x or greater) in order to build ABCL
    469 with JSR-223 support; otherwise, this feature will not be built.
    470 
    471 This section describes the design decisions behind the ABCL JSR-223 support. It is not a description of what JSR-223 is or a tutorial on how to use it. See http://trac.common-lisp.net/armedbear/browser/trunk/abcl/examples/jsr-223 for example usage.
     464ABCL can be built with support for JSR-223, which offers a
     465language-agnostic API to invoke other languages from Java. The binary
     466distribution downloadable from ABCL's common-lisp.net home is built
     467with JSR-223 support. If you're building ABCL from source on a pre-1.6
     468JVM, you need to have a JSR-223 implementation in your CLASSPATH (such
     469as Apache Commons BSF 3.x or greater) in order to build ABCL with
     470JSR-223 support; otherwise, this feature will not be built.
     471
     472This section describes the design decisions behind the ABCL JSR-223
     473support. It is not a description of what JSR-223 is or a tutorial on
     474how to use it. See
     475http://trac.common-lisp.net/armedbear/browser/trunk/abcl/examples/jsr-223
     476for example usage.
    472477
    473478\subsubsection{Conversions}
    474479
    475 In general, ABCL's implementation of the JSR-223 API performs implicit conversion from Java objects to Lisp objects when invoking Lisp from Java, and the opposite when returning values from Java to Lisp. This potentially reduces coupling between user code and ABCL. To avoid such conversions, wrap the relevant objects in \code{JavaObject} instances.
     480In general, ABCL's implementation of the JSR-223 API performs implicit
     481conversion from Java objects to Lisp objects when invoking Lisp from
     482Java, and the opposite when returning values from Java to Lisp. This
     483potentially reduces coupling between user code and ABCL. To avoid such
     484conversions, wrap the relevant objects in \code{JavaObject} instances.
    476485
    477486\subsubsection{Implemented JSR-223 interfaces}
    478487
    479 JSR-223 defines three main interfaces, of which two (Invocable and Compilable) are optional. ABCL implements all the three interfaces - ScriptEngine and the two optional ones - almost completely. While the JSR-223 API is not specific to a single scripting language, it was designed with languages with a more or less Java-like object model in mind: languages such as Javascript, Python, Ruby, which have a concept of "class" or "object" with "fields" and "methods". Lisp is a bit different, so certain adaptations were made, and in one case a method has been left unimplemented since it does not map at all to Lisp.
     488JSR-223 defines three main interfaces, of which two (Invocable and
     489Compilable) are optional. ABCL implements all the three interfaces -
     490ScriptEngine and the two optional ones - almost completely. While the
     491JSR-223 API is not specific to a single scripting language, it was
     492designed with languages with a more or less Java-like object model in
     493mind: languages such as Javascript, Python, Ruby, which have a concept
     494of "class" or "object" with "fields" and "methods". Lisp is a bit
     495different, so certain adaptations were made, and in one case a method
     496has been left unimplemented since it does not map at all to Lisp.
    480497
    481498\subsubsection{The ScriptEngine}
    482499
    483 The main interface defined by JSR-223, javax.script.ScriptEngine, is implemented by the class \code{org.armedbear.lisp.scripting.AbclScriptEngine}. AbclScriptEngine is a singleton, reflecting the fact that ABCL is a singleton as well. You can obtain an instance of AbclScriptEngine using the  AbclScriptEngineFactory or by using the service provider mechanism through ScriptEngineManager (refer to the javax.script documentation).
     500The main interface defined by JSR-223, javax.script.ScriptEngine, is
     501implemented by the class
     502\code{org.armedbear.lisp.scripting.AbclScriptEngine}. AbclScriptEngine
     503is a singleton, reflecting the fact that ABCL is a singleton as
     504well. You can obtain an instance of AbclScriptEngine using the
     505AbclScriptEngineFactory or by using the service provider mechanism
     506through ScriptEngineManager (refer to the javax.script documentation).
    484507
    485508\subsubsection{Startup and configuration file}
    486509
    487 At startup (i.e. when its constructor is invoked, as part of the static initialization phase of AbclScriptEngineFactory) the ABCL script engine attempts to load an "init file" from the classpath (/abcl-script-config.lisp). If present, this file can be used to customize the behaviour of the engine, by setting a number of variables in the ABCL-SCRIPT package. Here is a list of the available variables:
     510At startup (i.e. when its constructor is invoked, as part of the
     511static initialization phase of AbclScriptEngineFactory) the ABCL
     512script engine attempts to load an "init file" from the classpath
     513(/abcl-script-config.lisp). If present, this file can be used to
     514customize the behaviour of the engine, by setting a number of
     515variables in the ABCL-SCRIPT package. Here is a list of the available
     516variables:
    488517
    489518\begin{itemize}
    490 \item *use-throwing-debugger* Controls whether ABCL uses a non-standard debugging hook function to throw a Java exception instead of dropping into the debugger in case of unhandled error conditions.
     519\item *use-throwing-debugger* Controls whether ABCL uses a
     520  non-standard debugging hook function to throw a Java exception
     521  instead of dropping into the debugger in case of unhandled error
     522  conditions.
    491523  \begin{itemize}
    492524  \item Default value: T
    493   \item Rationale: it is more convenient for Java programmers using Lisp as a scripting language to have it return exceptions to Java instead of handling them in the Lisp world.
    494   \item Known Issues: the non-standard debugger hook has been reported to misbehave in certain circumstances, so consider disabling it if it doesn't work for you.
     525  \item Rationale: it is more convenient for Java programmers using
     526    Lisp as a scripting language to have it return exceptions to Java
     527    instead of handling them in the Lisp world.
     528  \item Known Issues: the non-standard debugger hook has been reported
     529    to misbehave in certain circumstances, so consider disabling it if
     530    it doesn't work for you.
    495531  \end{itemize}
    496 \item *launch-swank-at-startup* If true, Swank will be launched at startup. See *swank-dir* and *swank-port*.
     532\item *launch-swank-at-startup* If true, Swank will be launched at
     533  startup. See *swank-dir* and *swank-port*.
    497534  \begin{itemize}
    498535  \item Default value: NIL
    499536  \end{itemize}
    500 \item *swank-dir* The directory where Swank is installed. Must be set if *launch-swank-at-startup* is true.
    501 \item *swank-port* The port where Swank will listen for connections. Must be set if *launch-swank-at-startup* is true.
     537\item *swank-dir* The directory where Swank is installed. Must be set
     538  if *launch-swank-at-startup* is true.
     539\item *swank-port* The port where Swank will listen for
     540  connections. Must be set if *launch-swank-at-startup* is true.
    502541  \begin{itemize}
    503542  \item Default value: 4005
     
    505544\end{itemize}
    506545
    507 Additionally, at startup the AbclScriptEngine will \code{(require 'asdf)} - in fact, it uses asdf to load Swank.
     546Additionally, at startup the AbclScriptEngine will \code{(require
     547  'asdf)} - in fact, it uses asdf to load Swank.
    508548
    509549\subsubsection{Evaluation}
    510550
    511 Code is read and evaluated in the package ABCL-SCRIPT-USER. This packages USEs the COMMON-LISP, JAVA and ABCL-SCRIPT packages. Future versions of the script engine might make this default package configurable. The \code{CL:LOAD} function is used under the hood for evaluating code, and thus the same behavior of LOAD is guaranteed. This allows, among other things, \code{IN-PACKAGE} forms to change the package in which the loaded code is read.
    512 
    513 It is possible to evaluate code in what JSR-223 calls a "ScriptContext" (basically a flat environment of name->value pairs). This context is used to establish special bindings for all the variables defined in it; since variable names are strings from Java's point of view, they are first interned using READ-FROM-STRING with, as usual, ABCL-SCRIPT-USER as the default package. Variables are declared special because CL's \code{LOAD}, \code{EVAL} and \code{COMPILE} functions work in a null lexical environment and would ignore non-special bindings.
    514 
    515 Contrary to what the function \code{LOAD} does, evaluation of a series of forms returns the value of the last form instead of T, so the evaluation of short scripts does the Right Thing.
     551Code is read and evaluated in the package ABCL-SCRIPT-USER. This
     552packages USEs the COMMON-LISP, JAVA and ABCL-SCRIPT packages. Future
     553versions of the script engine might make this default package
     554configurable. The \code{CL:LOAD} function is used under the hood for
     555evaluating code, and thus the same behavior of LOAD is
     556guaranteed. This allows, among other things, \code{IN-PACKAGE} forms
     557to change the package in which the loaded code is read.
     558
     559It is possible to evaluate code in what JSR-223 calls a
     560"ScriptContext" (basically a flat environment of name->value
     561pairs). This context is used to establish special bindings for all the
     562variables defined in it; since variable names are strings from Java's
     563point of view, they are first interned using READ-FROM-STRING with, as
     564usual, ABCL-SCRIPT-USER as the default package. Variables are declared
     565special because CL's \code{LOAD}, \code{EVAL} and \code{COMPILE}
     566functions work in a null lexical environment and would ignore
     567non-special bindings.
     568
     569Contrary to what the function \code{LOAD} does, evaluation of a series
     570of forms returns the value of the last form instead of T, so the
     571evaluation of short scripts does the Right Thing.
    516572
    517573\subsubsection{Compilation}
    518574
    519 AbclScriptEngine implements the javax.script.Compilable interface. Currently it only supports compilation using temporary files. Compiled code, returned as an instance of javax.script.CompiledScript, is read, compiled and executed by default in the ABCL-SCRIPT-USER package, just like evaluated code. Differently from evaluated code, though, due to the way the ABCL compiler works, compiled code contains no reference to top-level self-evaluating objects (like numbers or strings). Thus, when evaluated, a piece of compiled code will return the value of the last non-self-evaluating form: for example the code "(do-something) 42" will return 42 when interpreted, but will return the result of (do-something) when compiled and later evaluated. To ensure consistency of behavior between interpreted and compiled code, make sure the last form is always a compound form - at least (identity some-literal-object). Note that this issue should not matter in real code, where it is unlikely a top-level self-evaluating form will appear as the last form in a file (in fact, the Common Lisp load function always returns T upon success; with JSR-223 this policy has been changed to make evaluation of small code snippets work as intended).
     575AbclScriptEngine implements the javax.script.Compilable
     576interface. Currently it only supports compilation using temporary
     577files. Compiled code, returned as an instance of
     578javax.script.CompiledScript, is read, compiled and executed by default
     579in the ABCL-SCRIPT-USER package, just like evaluated code. Differently
     580from evaluated code, though, due to the way the ABCL compiler works,
     581compiled code contains no reference to top-level self-evaluating
     582objects (like numbers or strings). Thus, when evaluated, a piece of
     583compiled code will return the value of the last non-self-evaluating
     584form: for example the code "(do-something) 42" will return 42 when
     585interpreted, but will return the result of (do-something) when
     586compiled and later evaluated. To ensure consistency of behavior
     587between interpreted and compiled code, make sure the last form is
     588always a compound form - at least (identity some-literal-object). Note
     589that this issue should not matter in real code, where it is unlikely a
     590top-level self-evaluating form will appear as the last form in a file
     591(in fact, the Common Lisp load function always returns T upon success;
     592with JSR-223 this policy has been changed to make evaluation of small
     593code snippets work as intended).
    520594
    521595\subsubsection{Invocation of functions and methods}
    522596
    523 AbclScriptEngine implements the \code{javax.script.Invocable} interface, which allows to directly call Lisp functions and methods, and to obtain Lisp implementations of Java interfaces. This is only partially possible with Lisp since it has functions, but not methods - not in the traditional OO sense, at least, since Lisp methods are not attached to objects but belong to generic functions. Thus, the method \code{invokeMethod()} is not implemented and throws an UnsupportedOperationException when called. The \code{invokeFunction()} method should be used to call both regular and generic functions.
     597AbclScriptEngine implements the \code{javax.script.Invocable}
     598interface, which allows to directly call Lisp functions and methods,
     599and to obtain Lisp implementations of Java interfaces. This is only
     600partially possible with Lisp since it has functions, but not methods -
     601not in the traditional OO sense, at least, since Lisp methods are not
     602attached to objects but belong to generic functions. Thus, the method
     603\code{invokeMethod()} is not implemented and throws an
     604UnsupportedOperationException when called. The \code{invokeFunction()}
     605method should be used to call both regular and generic functions.
    524606
    525607\subsubsection{Implementation of Java interfaces in Lisp}
    526608
    527 ABCL can use the Java reflection-based proxy feature to implement Java interfaces in Lisp. It has several built-in ways to implement an interface, and supports definition of new ones. The \code{JAVA:JMAKE-PROXY} generic function is used to make such proxies. It has the following signature:
     609ABCL can use the Java reflection-based proxy feature to implement Java
     610interfaces in Lisp. It has several built-in ways to implement an
     611interface, and supports definition of new ones. The
     612\code{JAVA:JMAKE-PROXY} generic function is used to make such
     613proxies. It has the following signature:
    528614
    529615\code{jmake-proxy interface implementation \&optional lisp-this ==> proxy}
    530616
    531 \code{interface} is a Java interface metaobject (e.g. obtained by invoking \code{jclass}) or a string naming a Java interface. \code{implementation} is the object used to implement the interface - several built-in methods of jmake-proxy exist for various types of implementations. \code{lisp-this} is an object passed to the closures implementing the Lisp "methods" of the interface, and defaults to \code{NIL}.
    532 
    533 The returned proxy is an instance of the interface, with methods implemented with Lisp functions.
     617\code{interface} is a Java interface metaobject (e.g. obtained by
     618invoking \code{jclass}) or a string naming a Java
     619interface. \code{implementation} is the object used to implement the
     620interface - several built-in methods of jmake-proxy exist for various
     621types of implementations. \code{lisp-this} is an object passed to the
     622closures implementing the Lisp "methods" of the interface, and
     623defaults to \code{NIL}.
     624
     625The returned proxy is an instance of the interface, with methods
     626implemented with Lisp functions.
    534627
    535628Built-in interface-implementation types include:
    536629
    537630\begin{itemize}
    538 \item a single Lisp function which upon invocation of any method in the interface will be passed the method name, the Lisp-this object, and all the parameters. Useful for interfaces with a single method, or to implement custom interface-implementation strategies.
    539 \item a hash-map of method-name -> Lisp function mappings. Function signature is \code{(lisp-this \&rest args)}.
    540 \item a Lisp package. The name of the Java method to invoke is first transformed in an idiomatic Lisp name (\code{javaMethodName} becomes \code{JAVA-METHOD-NAME}) and a symbol with that name is searched in the package. If it exists and is fbound, the corresponding function will be called. Function signature is as the hash-table case.
     631\item a single Lisp function which upon invocation of any method in
     632  the interface will be passed the method name, the Lisp-this object,
     633  and all the parameters. Useful for interfaces with a single method,
     634  or to implement custom interface-implementation strategies.
     635\item a hash-map of method-name -> Lisp function mappings. Function
     636  signature is \code{(lisp-this \&rest args)}.
     637\item a Lisp package. The name of the Java method to invoke is first
     638  transformed in an idiomatic Lisp name (\code{javaMethodName} becomes
     639  \code{JAVA-METHOD-NAME}) and a symbol with that name is searched in
     640  the package. If it exists and is fbound, the corresponding function
     641  will be called. Function signature is as the hash-table case.
    541642\end{itemize}
    542643
    543 This functionality is exposed by the AbclScriptEngine with the two methods getInterface(Class) and getInterface(Object, Class). The former returns an interface implemented with the current Lisp package, the latter allows the programmer to pass an interface-implementation object which will in turn be passed to the jmake-proxy generic function.
     644This functionality is exposed by the AbclScriptEngine with the two
     645methods getInterface(Class) and getInterface(Object, Class). The
     646former returns an interface implemented with the current Lisp package,
     647the latter allows the programmer to pass an interface-implementation
     648object which will in turn be passed to the jmake-proxy generic
     649function.
    544650
    545651\chapter{Implementation Dependent Extensions}
     
    727833\section{ASDF}
    728834
    729 asdf-2.017 is packaged as core component of ABCL.  By default, ASDF is
    730 not loaded, as it relies on the CLOS subsystem which can take a bit of
    731 time to initialize.
     835asdf-2.017 is packaged as core component of ABCL, but not intialized
     836by default, as it relies on the CLOS subsystem which can take a bit of
     837time to initialize.  It may be initialized by the ANSI
     838\textsc{REQUIRE} mechanism as follows:
    732839
    733840\begin{listing-lisp}
     
    739846\section{abcl-asdf}
    740847
    741 Allow ASDF system definition which dynamically loads JVM artifacts
    742 such as jar archives via a Maven encapsulation.
    743 
    744 ASDF components added:  JAR-FILE, JAR-DIRECTORY, CLASS-FILE-DIRECTORY
     848This contrib to ABCL enables an additional syntax for ASDF system
     849definition which dynamically loads JVM artifacts such as jar archives
     850via a Maven encapsulation.
     851
     852The following ASDF components are added:  JAR-FILE, JAR-DIRECTORY, CLASS-FILE-DIRECTORY
    745853and MVN.
    746854
     
    758866\section{jss}
    759867
    760 Java Syntax sucks, so we introduce the \#" macro.
    761 
     868To one used to a syntax that can construct macros, the Java syntax
     869sucks, so we introduce the \#" macro.
     870
     871\subsection{JSS usage}
     872
     873Example:
     874
     875\begin{listing-lisp}
     876  CL-USER> (require 'jss)
     877
     878  CL-USER) (#"getProperties" 'java.lang.System)
     879
     880  CL-USER) (#"propertyNames" (#"getProperties" 'java.lang.System))
     881\end{listing-lisp}
    762882
    763883\chapter{History}
Note: See TracChangeset for help on using the changeset viewer.