Dear Fellow Parenscripters,
Here I detail a proposed package system for Parenscript to ease modular
development. This is a feature intended to make up for the many hacks
Javascript programmers use to write libraries. The proposed system takes
after and integrates with the Lisp package system. Its implementation will
constitute a hearty advancement of the current Parenscript compiler.
The proposed system should introduce new concepts and should be robust
enough to lay the foundation for a lot of future work in a coherent way.
Different packages can introduce new special forms--that is, modify the
language at the lowest level. With this, a "javascript2" package can
introduce Parenscript forms that compile to the latest version of ECMAScript
without implicating the rest of the project. The additional semantic
analysis of Parenscript programs will pave the way for cropped, minified, or
obfuscated scripts. In addition, a formal package specification will lead
to asdf-installable script libraries with better deployment characteristics
than current package systems for web development in other languages.
A Parenscript package (or "script package" or simply "package," as opposed
to a "Lisp package") has a few main properties: a name and list of
nicknames, an primary associated Lisp package, a list of exported
identifiers, and a collection of macros defined in the associated Lisp
package. We must also introduce and formalize a two other concepts:
Parenscript identifiers (analog of Lisp symbols), and a compilation
environment.
A Parenscript package is defined and exists in the context of a compilation
environment. A compilation environment simply keeps track of compiler
state; when any Parenscript code is compiled, a new compilation environment
is created or an existing one is passed to the compiler. The environment is
modified to reflect the lexical scope as forms are processed. Specifically,
the compilation environment will consist of a stack of Parenscript
identifiers (introduced by defun and defvar forms); a stack of macros and
symbol macros; a list of defined script packages; and the current script
package.
An identifier in Parenscript is analogous to a Lisp symbol, but it only
exists during compile time. An identifier has a string value and
associated Parenscript package.
Now I will run through a simple example to demonstrate these new
developments:
Script packages are primarily defined using a Parenscript form analogous to
the Lisp defpackage:
(defpackage friendly-script
(:use parenscript psos)
(:export hello-world)
(:lisp-package friendly)
(:documentation "Scripts for issuing greetings."))
This introduces a new package into the compilation environment. We enter
the package system after it is defined as in Lisp:
;; enter the friendly-script package
; changes the current package in the compilation environment to
:friendly-script
(in-package :friendly-script)
;; define the hello-world function, which we export
; adds friendly-script::hello-world to the identifier stack in the
compilation env.
(defun hello-world ()
(alert "hello world."))
;; enter the user package
; changes current package in compilation environment
(in-package :parenscript-user)
;; call the friendly-script's hello-world function
; the compiler recognizes that friendly-script::hello-world is an e
(friendly-script:hello-world)
To give you an idea, this will all compile to something like the following
Javascript:
function friendlyScript_helloWorld() { alert("hello world."); }
friendlyScript_helloWorld();
In terms of implementation, the package system will introduce a few new
classes (script-package, identifier, and compilation-environment); uproot
existing parsing procedures and replant them around the package system; and
add a semantic analysis phase into the compilation pipeline. I will fill in
details and announce problems with the implementation as it moves forward.
Hopefully this is an exciting prospect for the community. The package
system should empower those who want to build large programs or share
Parenscript extensions/libraries. It should also preserve the
javascript-in-sexps Parenscript we know and love.
Anyhow, I look forward to comments on this proposal. Happy hacking!
Red