[Bese-devel] Advancing Parenscript - current and future improvements

Henrik Hjelte henrik at evahjelte.com
Tue Jan 16 19:49:52 UTC 2007


On Tue, 2007-01-16 at 02:58 -0800, Red Daly wrote:

> I have a pretty stable implementation of a CLOS-like metaobject system 
> in Parenscript called the Parenscript Object System.  There is currently 
> support for generic functions and class inheritance.  
Looks great! I have to check this out soon..

> It also has some 
> cool (beta) features, like importing a CLOS class and sending instances 
> of that class across the net as a JSON object.  
FYI: If you use cl-json on the server, there are some updates in the
darcs repo compared to the release version.

> There are also things 
> that I haven't figured out how to do best, like slot definitions.  See 
> http://scratchpad.wikia.com/wiki/Parenscript_Object_System for more details.
> 
> The standard Javascript function definition is fairly bland, so I also 
> implemented lisp's function declaration syntax.  Keyword arguments, 
> defaulting parameters, and &rest arguments all expand to proper 
> Javascript function definitions.  Parenscript function definitions are 
> indistinguishable from their Lisp counterparts, since the code to parse 
> the paren-lambda lists is ripped from SBCL.
> 
> Now, there are a few problems that I would like to solve with the 
> assistance of interested parties :).
> 
> There is still no clear solution for packaging code into modules in 
> Javascript. This roughtly breaks down into two classes of problems: 
> namespace problems and packaging problems.
> 
> Namespace issues
> Namespace problems are those related to name conflicts in the Javascript 
> environment. Currently developers work around this by introducing simple 
> objects that serve as Java-esque prefixes: dojo.widgets.bloated, 
> Ajax.Request, etc. Using prefixes is a good idea, but importing a 
> package's "symbols" is sort of awkward. For example, a way to import 
> everying from the dojo package is this:
> 
> for (var dojoSym in dojo)
>    window[dojoSym] = dojo[dojoSym];
> 
> However, once those symbols are imported, they are imported into the 
> global scope where they may conflict.
> 
> Does with(dojo) solve this problem at all?  I remember reading that 
> with() is evil for performance and other reasons--it doesn't do what you 
> think.
I don't think with is a good idea for the reasons you mention. 

> I would like to come up with a more elegant solution for namespacing 
> Parenscript code.  Ideally there could be (defpackage) and (in-package) 
> forms hide the dirty object declarations and such from a Parenscript 
> user.  Ideas??

Since the javascript is generated, there is no reason why this:
myLibrary.myFunction();

couldn't look like this in parenscript:

(in-package :my-library)
(my-function)

Anything could be generated, myLibrary_myFunction or
x345657as_myFunction if you want to avoid all name collisions. Some
people care how the generated code looks, I don't very much.

What I have thinked about and would very much like is that parenscript
knew about dependencies and kept track of them. The idea is that you
shouldn't need to include lots of large javascript files even though you
only need one or two functions in a library. For the example above, when
parenscript should generates code for (my-function), it would look in
the package :my-library to see if there was a function definition for
my-function there. If not it would look at the imports in my-library.
Finally we could have "external" javascript definitions, for example the
core javascript functions or the "window" global scoped functions (or
objects). If there was no definition reachable for my-function
parenscript would show a Warning. All typo errors would disappear! You
could also warn about missing arguments and other things, and perhaps do
optimizations.

For those of us that care about performance and bandwidth,
a great thing could be that you could compile a .js file that included
exactly all functions you need and no more, in one file. 

In common-lisp code:
(with-js-environments (core-javascript window-object dojo-library)
   (generate-all 
     `((in-package :my-library)
       (my-function))))
would return something like:
"
function myLibrary_myFunction () {
  alert("hello");
};
myLibrary_MyFunction();
"

This would mean a lot of changes to parenscript. But it shouldn't be
that difficult should it?

One could also consider to start over again from the start with a new
project. The parenscript code has it's quirks that I'm not particular
found of, code such as dwim-join-strings.


> Packaging issues
> 
> Right now there is no consistent packaging strategy for Javascript code. 
> In most cases, developers wishing to use the latest and greatest will 
> download a project, add it to their own source tree, and then follow 
> special instructions about how to actually include the scripts in their 
> web sites. This works O.K. most of the time, but it is indeed not the 
> smartest system.
> 
> Parenscript should probably take advantage of Lisp's Another System 
> Definition Facility (ASDF) to define packages. I have not worked out the 
> details of how to define Parenscript systems yet. 
Parenscript and client-side web-applications (the main target for
javascript) are different from Lisp. I don't think you can just take
ASDF and put it in parenscript. I think one need to ask what exactly is
needed for a javascript environment. But something similar to asdf
syntax-wise would be nice. 

> Packaging issues are not as important as namespace issues to me, since a 
> large packaging system doesn't matter if there are name conflicts 
> everywhere.
I agree that packaging issues are of less importance (at least until
there are any packages to get). But it is not name conflicts that I'm
afraid of, it is loading and initializing all these files on the client.
Including dojo is not nice! I need a mapcar function and what do I get,
20 files and three seconds load time. Whereas in my dream solution I
would only get the little mapcar function from somewhere in my server
side library at compile time, then saved to a little page-specific js
file.

> 
> Thanks for listening.  I hope this message reaches the right people!
> Sincerely,
> Red Daly

And thank you! clos in javascript is way cool.

I'm interested in contributing to evolving parenscript. This mailing
list isn't that crowded, so it is a good place to discuss on isn't it?

Best wishes,
Henrik Hjelte








More information about the bese-devel mailing list