-;;; A more complicated ParenScript macro example is the implementation
-;;; of the `DOLIST' form (note how `JS-GENSYM', the ParenScript of
-;;; `GENSYM', is used to generate new ParenScript variable names):
-
-(defjsmacro dolist (i-array &rest body)
- (let ((var (first i-array))
- (array (second i-array))
- (arrvar (js-gensym "arr"))
- (idx (js-gensym "i")))
- `(let ((,arrvar ,array))
- (do ((,idx 0 (++ ,idx)))
- ((>= ,idx (slot-value ,arrvar 'length)))
- (let ((,var (aref ,arrvar ,idx)))
- ,@body)))))
-
-;;; Macros can be added dynamically to the macro environment by using
-;;; the ParenScript `MACROLET' form (note that while `DEFJSMACRO' is a
-;;; Lisp form, `MACROLET' and `SYMBOL-MACROLET' are ParenScript forms).
-
-;;; ParenScript also supports symbol macros, which can be introduced
-;;; using the ParenScript form `SYMBOL-MACROLET'. A new macro
-;;; environment is created and added to the current macro environment
-;;; list while compiling the body of the `SYMBOL-MACROLET' form. For
-;;; example, the ParenScript `WITH-SLOTS' is implemented using symbol
-;;; macros.
-
-(defjsmacro with-slots (slots object &rest body)
+;;; A more complicated Parenscript macro example is the implementation
+;;; of the `DOLIST' form (note how `PS-GENSYM', the Parenscript of
+;;; `GENSYM', is used to generate new Parenscript variable names):
+
+(defpsmacro dolist ((var array &optional (result nil result?)) &body body)
+ (let ((idx (ps-gensym "_js_idx"))
+ (arrvar (ps-gensym "_js_arrvar")))
+ `(do* (,var
+ (,arrvar ,array)
+ (,idx 0 (1+ ,idx)))
+ ((>= ,idx (slot-value ,arrvar 'length))
+ ,@(when result? (list result)))
+ (setq ,var (aref ,arrvar ,idx))
+ ,@body)))
+
+;;; Macros can be defined in Parenscript code itself (as opposed to
+;;; from Lisp) by using the Parenscript `MACROLET' and `DEFMACRO'
+;;; forms. Note that macros defined this way are defined in a null
+;;; lexical environment (ex - (let ((x 1)) (defmacro baz (y) `(+ ,y
+;;; ,x))) will not work), since the surrounding Parenscript code is
+;;; just translated to JavaScript and not actually evaluated.
+
+;;; Parenscript also supports the use of macros defined in the
+;;; underlying Lisp environment. Existing Lisp macros can be imported
+;;; into the Parenscript macro environment by
+;;; `IMPORT-MACROS-FROM-LISP'. This functionality enables code sharing
+;;; between Parenscript and Lisp, and is useful in debugging since the
+;;; full power of Lisp macroexpanders, editors and other supporting
+;;; facilities can be used. However, it is important to note that the
+;;; macroexpansion of Lisp macros and Parenscript macros takes place
+;;; in their own respective environments, and many Lisp macros
+;;; (especially those provided by the Lisp implementation) expand into
+;;; code that is not usable by Parenscript. To make it easy for users
+;;; to take advantage of these features, two additional macro
+;;; definition facilities are provided by Parenscript: `DEFMACRO/PS'
+;;; and `DEFMACRO+PS'. `DEFMACRO/PS' defines a Lisp macro and then
+;;; imports it into the Parenscript macro environment, while
+;;; `DEFMACRO+PS' defines two macros with the same name and expansion,
+;;; one in Parenscript and one in Lisp. `DEFMACRO+PS' is used when the
+;;; full 'macroexpand' of the Lisp macro yields code that cannot be
+;;; used by Parenscript.
+
+;;; Parenscript also supports symbol macros, which can be introduced
+;;; using the Parenscript form `SYMBOL-MACROLET' or defined in Lisp
+;;; with `DEFINE-PS-SYMBOL-MACRO'. For example, the Parenscript
+;;; `WITH-SLOTS' is implemented using symbol macros.
+
+(defpsmacro with-slots (slots object &rest body)