git » jacl.git » commit 60f0967

demo paper progress

author Alan Dipert
2020-04-16 09:07:19 UTC
committer Alan Dipert
2020-04-16 09:07:19 UTC
parent b4bd8f443393cb00442c8937cfd6d712484e9e24

demo paper progress

paper/jacl-demo-els-2020.tex +232 -447
paper/jacl-els-2020.bib +8 -0

diff --git a/paper/jacl-demo-els-2020.tex b/paper/jacl-demo-els-2020.tex
index af66807..608c7a2 100644
--- a/paper/jacl-demo-els-2020.tex
+++ b/paper/jacl-demo-els-2020.tex
@@ -26,16 +26,15 @@
 \email{alan@dipert.org}
 
 \begin{abstract}
-  This paper demonstrates JavaScript-Assisted Common Lisp (JACL), a
-  new Web-browser based implementation of an extended subset of Common
-  Lisp. While still in the early stages of development, JACL is an
-  effort to facilitate the eventual use of Common Lisp in overcoming
-  the challenges of Single-page Web Application (SPA)
-  development. JACL promotes interactive development in the Web
-  browser environment with its \emph{asynchronous reader} and Chrome
-  DevTools-based REPL client. JACL includes an optimizing
-  Lisp-to-JavaScript compiler and supports interoperation with
-  JavaScript.
+  This paper demonstrates JavaScript-Assisted Common Lisp (JACL), an
+  experimental Web-browser based implementation of an extended subset
+  of Common Lisp. JACL, which is in the early stages of development,
+  is an effort to explore new techniques for large-scale Single-page
+  Web Application (SPA) development in Lisp. JACL includes an
+  optimizing Lisp-to-JavaScript compiler and interoperates with
+  JavaScript. JACL promotes interactive, \emph{residential}
+  development in the Web browser environment with its
+  \emph{asynchronous reader} and Chrome DevTools-based REPL client.
 \end{abstract}
 
 \begin{CCSXML}
@@ -60,7 +59,7 @@
 
 \maketitle
 
-\section{Motivation}
+\section{Introduction}
 
 The demand for SPAs in the past decade has only grown, and users and
 stakeholders continually expect larger and more sophisticated
@@ -75,442 +74,228 @@ development workflows, and claims some advantage relative to the
 status quo.
 
 This paper demonstrates one new such language, JavaScript-Assisted
-Common Lisp (JACL), an implementation of an extended subset of Common
-Lisp. The primary goal of the JACL project is to ease SPA development
-by applying Common Lisp --- a proven\cite{Cannon07,Garnet90,Action}
-substrate for UI innovation --- to the difficult challenges now faced
-by developers. The JACL language is envisioned as the means to
-achieving that goal.
-
-\section{Related Work}
-
-Many similar efforts to compile Lisp to JavaScript precede JACL. Lisps
-that have either demonstrated industrial utility or that implement a
-significant subset of Common Lisp are surveyed in appendix
-\ref{appendix:lisps}. Compared to related work, JACL distinguishes
-itself primarily by its emphasis on interactive development and by its
-\emph{asynchronous reader} facility.
-
-\section{Interactive Development Model}
-
-\section{JavaScript FFI}
-
-\section{Object Inspection}
-
-%\section{Design and Implementation}
-%
-%From a design perspective, JACL is an effort to balance the
-%requirements of an interactive and practical Lisp development
-%environment with the constraints imposed by the Web browser
-%platform. JACL proposes several innovations with respect to previous
-%work in pursuit of this balance.
-%
-%\subsection{Asynchronous reader}
-%
-%The basis for interactive development in Lisp is undeniably the REPL,
-%but as the JSCL ``pre-reader'' demonstrates, even the direct approach
-%to this simple mechanism is hampered by the asynchronous model of
-%input imposed by JavaScript.\cite{EventLoop}. Traditionally, Lisp
-%readers are implemented in environments with a blocking function for
-%obtaining input, like \texttt{getc(1)} on Unix. The blocking nature of
-%input consumption allows the reader to consume nested input
-%recursively, using the call stack to accumulate structures. In
-%JavaScript, input arrives asynchronously, and only when the call stack
-%is empty. To mitigate this difficulty, the JACL reader facility is
-%completely asynchronous. Conceptually, it is the JSCL REPL
-%``pre-reader'' taken to its inevitable conclusion.
-%
-%\section{Design and Implementation}
-%
-%From a design perspective, JACL is an effort to balance the
-%requirements of an interactive and practical Lisp development
-%environment with the constraints imposed by the Web browser
-%platform. JACL proposes several innovations with respect to previous
-%work in pursuit of this balance.
-%
-%\subsection{Asynchronous reader}
-%
-%The basis for interactive development in Lisp is undeniably the REPL,
-%but as the JSCL ``pre-reader'' demonstrates, even the direct approach
-%to this simple mechanism is hampered by the asynchronous model of
-%input imposed by JavaScript.\cite{EventLoop}. Traditionally, Lisp
-%readers are implemented in environments with a blocking function for
-%obtaining input, like \texttt{getc(1)} on Unix. The blocking nature of
-%input consumption allows the reader to consume nested input
-%recursively, using the call stack to accumulate structures. In
-%JavaScript, input arrives asynchronously, and only when the call stack
-%is empty. To mitigate this difficulty, the JACL reader facility is
-%completely asynchronous. Conceptually, it is the JSCL REPL
-%``pre-reader'' taken to its inevitable conclusion.
-%
-%The JACL reader is implemented as a JavaScript class,
-%\texttt{Reader}. \texttt{Reader} instances are parameterized by an
-%input source. One such input source is the \texttt{BufferedStream}
-%class. The input source asynchronously notifies the reader instance
-%when characters are available. The reader incrementally consumes these
-%characters. Once the reader has accumulated a Lisp datum, it notifies
-%its subscribers of the availability of the datum.
-%
-%The JACL reader implementation makes extensive use of modern
-%JavaScript features to support asynchronous programming including
-%promises, iterators, async functions, async iterators, and the
-%\texttt{await} keyword. These features simplify the JACL
-%implementation and aid its performance \cite{V8async}. It is hoped
-%that JACL will eventually be written in itself, and that these
-%features will be accessible from Lisp, perhaps as a set of
-%implementation-dependent \emph{declaration specifiers} available in
-%\texttt{DECLARE} expressions.
-%
-%The following example demonstrates, in JavaScript, the process by
-%which the JACL reader consumes characters and produces Lisp objects. A
-%\texttt{BufferedStream} and \texttt{Reader} are instantiated, sent
-%characters asynchronously, and then the resulting Lisp object is
-%printed to the JavaScript console.
-%
-%\begin{verbatim}
-%(async () => {
-%  let bs = new BufferedStream(),
-%      rdr = new Reader(bs);
-%  
-%  window.setTimeout(() => bs.write("1"), 1000);
-%  window.setTimeout(() => bs.write("2"), 2000);
-%  window.setTimeout(() => bs.write("3"), 3000);
-%  window.setTimeout(() => bs.write(" "), 4000);
-%  
-%  console.log(await rdr.read());
-%})();
-%\end{verbatim}
-%
-%\noindent In the preceding example, \texttt{window.setTimeout()} is
-%used to enqueue several JavaScript functions for execution after 1000,
-%2000, 3000, and 4000 milliseconds. Each enqueued function writes a
-%character of input to the \texttt{BufferedStream} \texttt{bs} when
-%invoked.
-%
-%Before any enqueued function is invoked, execution proceeds to the
-%\texttt{console.log} call, but is suspended by the \texttt{await}
-%keyword.
-%
-%The \texttt{await} keyword expects a JavaScript \texttt{Promise}
-%object on its right side, and JavaScript execution remains suspended
-%until the \texttt{Promise} has ``resolved'', or notified its
-%subscribers that the pending computation it represents has
-%completed. \texttt{rdr.read()} is an \texttt{async} function that
-%returns such a \texttt{Promise}.
-%
-%Once \texttt{rdr} has completed a form --- in this case, the number
-%123, after about 4000 milliseconds have elapsed --- execution
-%continues, and \texttt{123} is printed to the JavaScript console.
-%
-%The ``read'' portion of the JACL REPL is implemented by first
-%instantiating \texttt{BufferedStream} and \texttt{Reader}
-%objects. Then, in an asynchronous loop, objects are consumed from the
-%\texttt{Reader}, analyzed, compiled, and evaluated.
-%
-%Concurrently, characters may be sent to the \texttt{BufferedStream}
-%instantiated by the REPL by calling the \texttt{write()} or
-%\texttt{writeEach()} methods of the \texttt{BufferedaStream}
-%object. Neither character input nor read object consumption impede
-%other JavaScript operations, so the JACL REPL is suitable for
-%embedding in applications.
-%
-%Because of the platform and implementation-dependent nature of the
-%JACL reader, JACL does not support Common Lisp input streams, nor its
-%standard \texttt{READ} and \texttt{READ-FROM-STRING}
-%functions. Standard interfaces for extending the reader, such as the
-%\linebreak\texttt{SET-MACRO-CHARACTER} function, are not directly
-%supported. However, the JACL reader does provide an
-%implementation-specific way to define reader macros.
-%
-%\subsection{Chrome DevTools REPL}
-%
-%A browser-based REPL facilitates experimentation with the language by
-%interested people, from the comfort of their Web browsers. It's also a
-%useful debugging feature of a deployed application.
-%
-%However, most developers already have a preferred text editor and a
-%REPL interaction workflow, and so it's not within the JACL project
-%scope to build a resident IDE in the style of SLip. Even if a resident
-%IDE was a goal, the file system access restrictions imposed by the
-%browser would present significant challenges.
-%
-%Instead, JACL offers an alternative development REPL approach that
-%requires minimal host tooling: the DevTools-based REPL. Google Chrome
-%is capable of hosting a WebSocket-based debug server that implements
-%the DevTools Protocol \cite{GDevTools}. DevTools Protocol clients may
-%then connect to the server and interact with open tabs, such as by
-%evaluating arbitrary JavaScript within the context of the tab. JACL
-%leverages the DevTools Protocol to deliver a command-line REPL client
-%that may be run on development machines. The workflow is the
-%following:
-%
-%\begin{enumerate}
-%  \item Run Google Chrome from the shell with the \linebreak
-%    \texttt{--remote-debugging-port} parameter.
-%  \item Navigate to the Web site hosting the JACL system you wish to
-%    interact with.
-%  \item Run \texttt{jacl-repl} from the shell.
-%  \item Be presented with a Lisp prompt.
-%\end{enumerate}
-%
-%As a simple command-line application with a textual interface,
-%\texttt{jacl-repl} can be run in various contexts. For example, it
-%could be run within an Emacs ``inferior-lisp'' buffer, and then Lisp
-%forms could be sent from other Emacs buffers for evaluation in the
-%REPL. It could also be run as part of a build process that pipes Lisp
-%sources over the WebSocket for batch compilation. It is anticipated
-%that additional host-side tools that depend on \texttt{jacl-client}
-%will be necessary in the future to support loading source files in
-%dependency order.
-%
-%Unlike the pre-readers of SLip and JSCL, \texttt{jacl-client} is
-%completely ignorant of Lisp syntax. \texttt{jacl-client} merely
-%transports characters between the host machine and the Lisp system and
-%so is \emph{not} a pre-reader.
-%
-%There are a few obvious ways the JACL REPL experience could be
-%improved. For example, \texttt{jacl-repl} is currently an
-%R\cite{Rstats} script requiring an R installation and the
-%\texttt{chromote}\cite{Rchromote} package. A standalone binary
-%executable is imagined in the future in order to make it easier for
-%developers to start working on JACL projects. Additionally, JACL has
-%yet to define a printer for its native types, or an extensible print
-%protocol. Object string representations are obtained by calling the
-%generic JavaScript \texttt{toString()} method, which doesn't always
-%produce a representation that can be read back in.
-%
-%\subsection{Analyzing compiler}
-%
-%Unlike JSCL, the JACL compiler is organized to facilitate high-level
-%optimizations such as those that could support efficient compilation
-%of \texttt{TAGBODY} and other fundamental Common Lisp operators.
-%
-%The first compiler pass expands macros and produces an AST. The second
-%compiler pass performs optimizations and produces a new AST. The final
-%pass produces JavaScript code. AST nodes are represented by generic
-%JavaScript objects with at least the following keys:
-%
-%\begin{itemize}
-%  \item \texttt{op}: The name of the node, as a JavaScript string.
-%  \item \texttt{env}: An object of class \texttt{Env} that represents
-%    the lexical environment of the node.
-%  \item \texttt{parent}: The parent of the node; this is \texttt{null}
-%    for the root.
-%  \item \texttt{form}: The original source data of the node, a Lisp
-%    datum.
-%\end{itemize}
-%
-%\noindent Nodes and \texttt{Env} objects are immutable by
-%convention. Functions are provided for modifying and merging these
-%objects so as only to produce new objects. This convention reduces the
-%possibility of optimization passes interfering with one another. It
-%also eases understanding the AST, since every AST node contains a copy
-%of all relevant context. As JavaScript objects, AST nodes are easily
-%introspected using the object inspector of the Web browser.
-%
-%Currently, the \texttt{Env} object tracks evaluation context --- one
-%of \emph{statement}, \emph{expression}, or \emph{return} --- lexical
-%variables, and \texttt{TAGBODY} tags. In the future, it will track the
-%remaining aspects of the lexical environment, such as lexical
-%functions and macros.
-%
-%\subsubsection{Embedding JavaScript with \texttt{JACL:\%JS}}
-%
-%Unlike JSCL or SLip, the JACL compiler supports a special operator for
-%constructing fragments of JavaScript code, verbatim, from Lisp. The
-%semantics of this operator, \texttt{JACL:\%JS}, are inspired by a
-%similar feature of ClojureScript, \texttt{js*}. For example, the
-%following JACL code displays the number 3 in an alert box:
-%
-%\begin{verbatim}
-%(JACL:%JS "window.alert(~{})" 3)
-%\end{verbatim}
-%
-%The character sequence \texttt{\textasciitilde\{\}} is distinct from
-%any plausible \linebreak JavaScript syntax and so is used as placeholder
-%syntax. There must be as many placeholders as there are arguments to
-%\texttt{JACL:\%JS}.
-%
-%\subsubsection{Other interoperation support}
-%
-%In addition to \texttt{JACL:\%JS}, the JACL compiler currently
-%supports three more special operators for interacting with the host
-%platform: \texttt{JACL:\%NEW}, \texttt{JACL:\%DOT} and
-%\texttt{JACL:\%CALL}. These operators perform JavaScript object
-%instantiation, field access, and function calls, respectively. Since
-%JACL functions compile into JavaScript functions, \texttt{JACL:\%CALL}
-%is the basis for \texttt{FUNCALL} in JACL, and for function calls
-%generally.
-%
-%JACL also supplies a convenience macro, \texttt{JACL:\textbackslash.}
-%or ``the dot macro'' for performing a series of field accesses and
-%method calls\footnote{Strictly speaking, JavaScript ``method calls''
-%  are normal function calls but with a particular value of
-%  \texttt{this}.} concisely. The dot macro takes direct inspiration
-%from the \texttt{..} macro of Clojure. \texttt{JACL:\textbackslash.}
-%expands to zero or more nested \texttt{JACL:\%DOT} or
-%\texttt{JACL:\%CALL} forms. Here is an example of a
-%\texttt{JACL:\textbackslash.} form --- equivalent to the JavaScript
-%expression \texttt{(123).toString().length} --- and its corresponding
-%expansion:
-%
-%\begin{verbatim}
-%(\. 123 (|toString|) |length|)
-%(%DOT (%CALL 123 |toString|) |length|)
-%\end{verbatim}
-%
-%\noindent Note that JavaScript identifiers are case sensitive, and so
-%case-preserving, pipe-delimited Lisp symbols must be used to refer to
-%JavaScript object field and method names. The \emph{readtable case} of
-%the JACL reader cannot currently be modified. The dot macro also
-%recognizes Lisp or JavaScript strings as JavaScript identifiers.
-%
-%\subsubsection{\texttt{TAGBODY} compilation strategy}
-%
-%Consider the following Common Lisp program that decrements the local
-%variable \texttt{X} 10 times:
-%
-%\begin{verbatim}
-%(let ((x 10))
-%  (tagbody
-%    start
-%    (when (zerop x) (go end))
-%    (setq x (1- x))
-%    (go start)
-%    end))
-%\end{verbatim}
-%
-%\noindent JSCL, the existing Lisp closest to JACL, would compile the
-%preceding code into approximately\footnote{Actual JSCL output is not
-%  used because it includes type checks, generated variable names, and
-%  other code that would obscure the relevant machinery.} the following
-%JavaScript:
-%
-%\begin{verbatim}
-%function Jump(id, label) {
-%  this.id = id;
-%  this.label = label;
-%}
-%
-%var X = 10;
-%var id = [];
-%var label = 0;
-%LOOP: while (true) {
-%  try {
-%    switch(label) {
-%      case 0:
-%        if (X === 0) throw new Jump(id, 1);
-%        X = X-1;
-%        throw new Jump(id, 0);
-%      case 1:
-%      default:
-%        break LOOP;
-%    }
-%  } catch (e) {
-%    if (e instanceof Jump && e.id === id) {
-%      label = e.label;
-%    } else {
-%      throw e;
-%    }
-%  }
-%}
-%\end{verbatim}
-%
-%\noindent The mechanism is ingenious. \texttt{GO} tags became
-%\texttt{switch} labels, and jumps became \texttt{throw}
-%statements. The thrown objects are instances of \texttt{Jump}. Each
-%instance of \texttt{Jump} contains a destination label.
-%
-%Unfortunately, in this scheme, every jump requires a JavaScript
-%exception to be thrown, severely penalizing \texttt{TAGBODY} as
-%previously discussed. Fortunately, a straightforward \emph{local jump
-%  optimization} can be applied that yields a tremendous performance
-%benefit. Local jump optimization is a known
-%technique\cite{SICLTagbody}, but JACL is the first Lisp targeting
-%JavaScript to apply it.
-%
-%In order to perform this optimization, the JACL compiler first
-%identifies local \texttt{GO}s in its analysis pass. These are
-%\texttt{GO} nodes with no intervening \texttt{LAMBDA}
-%nodes\footnote{Note that \texttt{LAMBDA} doesn't necessarily preclude
-%  local jump optimization if the \texttt{LAMBDA} is inlined, but JACL
-%  currently does not inline functions.} between them and their
-%respective, lexically-enclosing \texttt{TAGBODY}s. Then,
-%\texttt{TAGBODY}s are identified that consist of only local
-%\texttt{GO}s.
-%
-%JavaScript generated for local \texttt{GO}s does not throw an
-%exception, but instead leverages the labeled form of the JavaScript
-%\texttt{continue}\cite{MozLabel} statement to transfer control
-%appropriately. JavaScript generated for \texttt{TAGBODY}s that have
-%been determined to consist only of local jumps omits the
-%\texttt{try/catch} block, saving on generated code size.
-%
-%The following code is similar\footnote{Once more, actual compiler
-%  output has been significantly modified and reformatted for brevity.}
-%to that generated by the JACL compiler. Cursory benchmarks
-%\ref{appendix:benchmarks} show JACL code runs several orders of
-%magnitude faster than JSCL, and that JACL code is almost as fast as
-%the JavaScript statement \texttt{while(X--)}:
-%
-%\begin{verbatim}
-%var X = 10;
-%var label = 0;
-%LOOP: while (true) {
-%  switch(label) {
-%    case 0:
-%      if (X === 0) {
-%        label = 1;
-%        continue LOOP;
-%      }
-%      X = X - 1;
-%      label = 0;
-%      continue LOOP;
-%    case 1:
-%    default:
-%      break LOOP;
-%  }
-%}
-%\end{verbatim}
-%
-%\section{Conclusion}
-%
-%We introduced JACL, a new Common Lisp created to ease SPA development.
-%JACL is designed as an efficient, practical tool, with the needs of
-%industrial SPA developers in mind. JACL integrates tightly with the
-%Web browser platform and interoperates easily with
-%JavaScript. Compared to other browser-based Lisps, JACL places a
-%higher emphasis on the value of the REPL, and introduces new
-%techniques for integrating the REPL into the development workflow.
-%
-%\section{Future Work}
-%
-%In order to be practical for application development, JACL must
-%support the creation of standalone executables. In the case of JACL,
-%these would be single JavaScript files that may be included in an HTML
-%page and are executed on page load. Fortunately, since JACL
-%development is image-based, JACL should support the traditional
-%approach of specifying a Lisp function entrypoint and dumping the Lisp
-%image to native (JavaScript) code. The
-%\texttt{SAVE-LISP-AND-DIE}\cite{SBCLManual} function in SBCL and the
-%\texttt{DELIVER}\cite{LispWorksDeliver} function in LispWorks are two
-%examples of this functionality in other implementations.
-%
-%JACL should be able to perform rudimentary optimizations such as
-%global function and variable tree shaking\cite{wiki:TreeShaking} in
-%order to reduce the size of generated executables. In addition, JACL
-%should make dynamic function and variable references in executables
-%static, so that third party tools like Google Closure
-%Compiler\cite{Bolin10} may optionally be used to perform additional
-%optimization.
-%
-%Other than the ability to produce optimized standalone executables,
-%many other design and implementation tasks remain, such as support for
-%special variables in lambda lists, \texttt{EVAL-WHEN}, macro lambda
-%lists, \texttt{DECLARE} et al, CLOS, various other data types,
-%compiler macros, etc. The list of tasks is enormous, but it is
-%anticipated that these features can be implemented over time, in the
-%order demanded by application development.
+Common Lisp (JACL), an experimental implementation of an extended
+subset of Common Lisp. JACL was created to explore new techniques for
+applying Common Lisp --- a proven\cite{Cannon07,Garnet90,Action}
+substrate for UI innovation --- to SPA development.
+
+Many projects involving compilation of Lisp to JavaScript precede
+JACL. Lisps that have either demonstrated industrial utility or that
+implement a significant subset of Common Lisp are surveyed in appendix
+\ref{appendix:lisps}. Like many of these related efforts, JACL
+includes an online, optimizing compiler and supports interoperation
+with JavaScript. These Lisps, and most other SPA implementation
+languages, are delivered as tools primarily designed to be run in the
+host environment, instead of in the target Web browser environment
+where compiled applications ultimately do. JACL distinguishes itself
+from these efforts by placing special emphasis on the value of
+\emph{residential} development style, where both applications and the
+tools used to create them co-evolve in a shared environment. JACL
+provides fundamental support for residential development with its
+\emph{asynchronous reader}.
+
+\section{Interoperation with JavaScript}
+
+JACL integrates tightly with JavaScript and depends heavily on the
+JavaScript runtime. As a result, JACL enjoys roughly the same
+applicability and performance characteristics as the JavaScript
+platform. However, this high degree of integration is at odds with
+comformance to the Common Lisp specification, and so JACL will never
+strictly conform.
+
+\subsection{Object Types}
+
+JACL introduces several of its own object types, currently implemented
+in JavaScript, including \texttt{Cons}, \texttt{LispSymbol}, and
+\texttt{LispString}. \texttt{Cons} and \texttt{LispSymbol} are
+introduced because JavaScript does not include direct
+equivalents. \texttt{LispString} is introduced because the native
+JavaScript \texttt{String} is immutable, whereas Lisp strings are
+mutable.
+
+JACL includes support for only one numeric type, the JavaScript
+\texttt{Number} object. The JavaScript \texttt{Number} is a
+double-precision 64-bit IEEE 754 value. The JACL reader interprets
+integers as \texttt{Number} objects. In the future, JACL will also
+interpret floating-point numbers as \texttt{Number}. This decision
+trades ANSI conformance for performance. If either type were boxed,
+arithmetic performance would suffer intolerably. JSCL\cite{JSCLGitHub}
+and Valtan\cite{valtanGitHub} make the same tradeoff.
+
+JACL functions are JavaScript functions, and may be invoked by
+JavaScript callbacks without a special calling convention. JavaScript
+functions named as Lisp values may be invoked with \texttt{FUNCALL} or
+\texttt{APPLY}. As opposed to JSCL, neither arguments nor return
+values are automatically coerced to or from any particular set of
+object types.
+
+\subsection{Operators}
+
+The JACL compiler supports a special operator for constructing
+fragments of JavaScript code, verbatim, from Lisp. The semantics of
+this operator, \texttt{JACL:\%JS}, are inspired by a similar feature
+of ClojureScript\cite{Cljs}, \texttt{js*}. For example, the following
+JACL code displays the number 3 in an alert box:
+
+\begin{verbatim}
+(JACL:%JS "window.alert(~{})" 3)
+\end{verbatim}
+
+The character sequence \texttt{\textasciitilde\{\}} is distinct from
+any plausible \linebreak JavaScript syntax and so is used as
+placeholder syntax. There must be as many placeholders as there are
+arguments to \texttt{JACL:\%JS}.
+
+In addition to \texttt{JACL:\%JS}, the JACL compiler currently
+supports three more special operators for interacting with the host
+platform: \texttt{JACL:\%NEW}, \texttt{JACL:\%DOT} and
+\texttt{JACL:\%CALL}. These operators perform JavaScript object
+instantiation, field access, and function calls, respectively. Since
+JACL functions are JavaScript functions, \texttt{JACL:\%CALL} is the
+basis for \texttt{FUNCALL} in JACL, and for function calls generally.
+
+JACL also supplies a convenience macro, \texttt{JACL:\textbackslash.}
+or ``the dot macro'' for performing a series of field accesses and
+method calls\footnote{Strictly speaking, JavaScript ``method calls''
+  are normal function calls but with a particular value of
+  \texttt{this}.} concisely. The dot macro takes direct inspiration
+from the \texttt{..} macro of
+Clojure\cite{Clojure}. \texttt{JACL:\textbackslash.}  expands to zero
+or more nested \texttt{JACL:\%DOT} or \texttt{JACL:\%CALL} forms. Here
+is an example of a \texttt{JACL:\textbackslash.} form --- equivalent
+to the JavaScript expression \texttt{(123).toString().length} --- and
+its corresponding expansion:
+
+\begin{verbatim}
+(\. 123 (|toString|) |length|)
+(%DOT (%CALL 123 |toString|) |length|)
+\end{verbatim}
+
+\noindent Note that JavaScript identifiers are case sensitive, and so
+case-preserving, pipe-delimited Lisp symbols must be used to refer to
+JavaScript object field and method names. The \emph{readtable case} of
+the JACL reader cannot currently be modified. The dot macro also
+recognizes Lisp or JavaScript strings as JavaScript identifiers.
+
+\subsection{Reader Macros}
+
+JACL includes two reader macros to support interoperation with
+JavaScript. These macros may be added to the \texttt{*READTABLE*} by
+calling the function
+\texttt{(JACL:ENABLE-JS-SYNTAX)}. \texttt{@\char`\"} denotes
+JavaScript \texttt{String} objects and \texttt{@|} denotes JavaScript
+identifiers.
+
+For example, the following two forms, which both evaluate to a JavaScript
+\texttt{String}, are equivalent:
+
+\begin{verbatim}
+@"Hello"
+(\. "Hello" (|toString|))
+\end{verbatim}
+
+\noindent \texttt{@|} may generally be used in place of the
+\texttt{JACL:\%JS} special form to refer to JavaScript
+identifiers. \texttt{(JACL:\%JS \char`\"alert\char`\")} and
+\texttt{@|alert|} are equivalent.
+  
+\section{Running JACL Programs}
+
+Currently, JACL programs may be evaluated in the Web browser in two
+ways: by adding Lisp \texttt{<script>} tags to the \texttt{<head>} of
+a Web page that also includes \texttt{jacl.js}, or by using the
+\texttt{jacl} tool included in the JACL
+distribution\cite{JACLDistribution} to connect to a running Web
+browser.
+
+\subsection{Lisp Scripts}
+
+Development of JACL itself is currently driven primarily by modifying
+\texttt{jacl.js} and the \texttt{boot.lisp} and
+\texttt{jacl-tests.lisp} Lisp scripts. The Lisp test scripts are
+included in the \texttt{index.html} file in the JACL
+distribution\cite{JACLDistribution}. After each modification, the Web
+browser is reloaded, and test results are displayed.
+
+This workflow is characteristic of the traditional JavaScript
+development workflow and has served JACL development so far. However,
+it requires runtime parsing and compilation of JACL source code, among
+other inefficiencies. Reloading the Web browser also destroys the
+entire runtime environment.
+
+The easiest way to create JACL programs in this manner is to start
+with the \texttt{index.html} Web page provided by JACL and then modify
+it by removing or adding new Lisp scripts.
+
+It is imagined that ultimately, Lisp sources will be incorporated into
+the Lisp \emph{image} exclusively by the REPL client tool. An
+arrangement such as this decouples source code loading from the Web
+browser lifecycle. Production executables may then be produced at any
+time from the Lisp image by a Lisp function in a manner similar to the
+\texttt{SAVE-LISP-AND-DIE}\cite{SBCLManual} function in SBCL or the
+\texttt{DELIVER}\cite{LispWorksDeliver} function in LispWorks.
+
+\subsection{REPL}
+
+JACL includes a REPL client program, \texttt{jacl}, that may be used
+to execute JACL programs in a Web browser from a terminal on the
+host. This process is described in detail in the \texttt{RUN.md}
+document included in the JACL distribution\cite{JACLDistribution}, but
+is summarized here.
+
+In order to use the REPL, the user must first start either the Google
+Chrome or Chromium browser with the remote debugging feature enabled.
+With remote debugging enabled, the Web browser may be controlled using
+a client program over a WebSocket connection. Then, the user must
+navigate to a Web page that includes at least \texttt{jacl.js} and
+\texttt{boot.lisp}.
+
+Finally, the user must start the \texttt{jacl} REPL client in a
+terminal. \texttt{jacl} leverages the remote debugging feature as a
+REPL transport, using it to send and receive characters between the
+host and the remote JACL runtime. The \texttt{jacl} tool is currently
+written in R\cite{Rstats} and uses the
+\texttt{chromote}\cite{Rchromote} package for interacting with the
+remote Chrome or Chromium browser.
+
+The \texttt{jacl} program has no knowledge of JACL syntax or
+semantics; it merely sends and receives characters. The intentional
+simplicity of \texttt{jacl} is part of the larger project goal of
+promoting residential-style tool and program development in the target
+environment. The simplicity of \texttt{jacl} is possible because of
+the asynchronous nature of the JACL reader. Incoming characters
+delivered over the WebSocket debugging connection are received by
+callback functions in the Web browser. The received characters are
+asynchronously and incrementally parsed into Lisp data. When a
+complete datum is formed, the compiler is called, and the resulting
+JavaScript is evaluated. Finally, any output is sent back over the
+debugger connection and received and printed by the \texttt{jacl}
+program.
+
+\section{Conclusion}
+
+We introduced JACL, a new and experimental Common Lisp created to
+explore techniques for building sophisticated SPAs. JACL integrates
+tightly with the Web browser platform and interoperates directly with
+JavaScript. Compared to other browser-based Lisps, JACL promotes
+residential development, and introduces a new technique for
+integrating the REPL into the development workflow.
+
+\section{Future Work}
+
+JACL currently lacks many basic Common Lisp data types, functions, and
+operators, and the resulting programming experience is challenging and
+wholly impractical. JACL should support as much of Common Lisp as is
+possible, accounting for the brutal limitations imposed by JavaScript
+and the Web platform. Fortunately, the many other existing Common
+Lisps that compile to JavaScript demonstrate that a compelling
+implementation \emph{is} possible.
+
+Other than work related to missing features such as multiple values,
+CLOS, and the conditions system, much design work remains with regard
+to the specific affordances of the \texttt{jacl} tool. For example,
+it's unclear how a large JACL project involving library dependencies
+and multiple source files should be managed and loaded.
 
 \section{Acknowledgments}
 
diff --git a/paper/jacl-els-2020.bib b/paper/jacl-els-2020.bib
index 477b365..fd8f0f5 100644
--- a/paper/jacl-els-2020.bib
+++ b/paper/jacl-els-2020.bib
@@ -158,6 +158,14 @@
  lastaccessed="February 12, 2020",
 }
 
+@online{JACLDistribution,
+ author={{Alan Dipert}},
+ year={2020},
+ title="JACL",
+ url="https://tailrecursion.com/JACL/",
+ lastaccessed="April 16, 2020",
+}
+
 @misc{CljsRelease,
  author= {Rich Hickey},
  year= {2012},