-;;; 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):
-
-(defpsmacro 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 (incf ,idx)))
- ((>= ,idx (slot-value ,arrvar 'length)))
- (let ((,var (aref ,arrvar ,idx)))
- ,@body)))))
-
-;;; Macros can be defined in ParenScript itself (as opposed to Lisp)
-;;; by using the ParenScript `MACROLET' and 'DEFMACRO' forms.
-
-;;; ParenScript also supports the use of macros defined in the
-;;; underlying Lisp. 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/JS' and
-;;; 'DEFMACRO+JS'. 'DEFMACRO/JS' defines a Lisp macro and then imports
-;;; it into the ParenScript macro environment, while 'DEFMACRO+JS'
-;;; defines two macros with the same name and expansion, one in
-;;; ParenScript and one in Lisp. 'DEFMACRO+JS' 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'. 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)