Re: Tail recursion syntactic sugar faked with TAGBODY-based construct?



Kaz Kylheku wrote:
....
TAILPROG is merely:

(defmacro tailprog (let-bindings pseudo-funcs &rest forms)
(let (argtags-forms macrolet-elems)
(dolist (pfunc pseudo-funcs)
(destructuring-bind (name vars &rest forms) pfunc
(push `(label ,name ,@vars) argtags-forms)
(push `(return ,@forms) argtags-forms)
(push `(,name (&rest args) `(goto ,',name ,@args)) macrolet-
elems)))
(nreverse argtags-forms)
(nreverse macrolet-elems)
`(macrolet (,@macrolet-elems)
(let ,let-bindings
(argtags nil
(return (progn ,@forms))
,@argtags-forms)))))

Cute macro. However, TAILPROG relies on NREVERSE not messing up ARGTAGS-FORMS and MACROLET-ELEMS (which it is permitted to do according to the standard), in LW5.1-beta I get

CL-USER 12 > (let ((list '(1 2 3)))
(values (nreverse list)
list))
(3 2 1)
(1)

CL-USER 13 >

so I changed TAILPROG to

(defmacro tailprog (let-bindings pseudo-funcs &rest forms)
(let (argtags-forms macrolet-elems)
(dolist (pfunc pseudo-funcs)
(destructuring-bind (name vars &rest forms) pfunc
(push `(label ,name ,@vars) argtags-forms)
(push `(return ,@forms) argtags-forms)
(push `(,name (&rest args) `(goto ,',name ,@args)) macrolet-elems)))
`(macrolet ,(reverse macrolet-elems)
(let ,let-bindings
(argtags nil
(return (progn ,@forms))
,@(reverse argtags-forms))))))

instead -- that seems to work.

-Klaus.
.