This sounds like the right way to go. I am also in agreement with Henrik that providing a protocol into the relevant parts of the package system would be a very valuable addition. The one thing I think is critical is that ParenScript's current semantics with respect to naming be preserved if you choose not to use the package system.
Vladimir
On 6/26/07, Red Daly reddaly@gmail.com wrote:
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
parenscript-devel mailing list parenscript-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel