But it doesn't pick up the lexical environment:
(let ((x 1)) (ps:ps (setf y (lisp x)))) => [Condition of type UNBOUND-VARIABLE]
This is true even when PS is the current package. Can anyone (Vladimir?) explain whether it has to be this way? Or could PS be extended to pick up lexical bindings as well?
you may find the following example interesting. it's a similar issue for sql and lisp unquoting handled by the [] reader and the sql compile machinery in cl-rdbms.
the idea in short: [] reads its body into an sexp (a macrocall to a macro named SQL, this is important to keep backquote work inside the [] reader). commas and ,@ on the first level of depth inside the [] reader are read into a special form (sql-unquote (something to be evaled in lisp) splicedp). then the SQL macro at macroexpand time parses its sexp body into an SQL AST (clos objects) and then reduces everything it can into a constant string. naturally the body of sql-unquote AST nodes are emitted inline as code.
http://common-lisp.net/project/cl-rdbms/showcase.html
a similar approach could work for js compilation and js would probably benefit even more then sql. just wild guessing here, but i think this scheme would speed up ps compilation by a few magnitudes and reduce consing to a fraction of the current. (there was plenty of room for optimization in the old parenscript, i've divided it by 100 already in the old repo... :)
if we (cl-dwim guys) had infinite time we would do it ourselves, but i hope someone will pick up the idea and do it for ps... ;)