Hi Jason,
Thank you very much for raising the preamble issue. It seems like it is fixable, see below. The idea of a “preamble” will probably be removed. Fix still needs to be implemented by me.
The blog post has been amended to document this bug. Search for “TODO BUG #2”.
;; TODO BUG #2 2023-02-28
(parenscript:ps* '(defun bar () (tagbody (go x) (alert "hi") x)))
#| returns
"defun(bar, null, (function () { go(x); alert('hi'); var switchVar295 = 1; while (true) { switch (switchVar295) { case 1: 'tagbody-go-tag: X'; }; __PS_MV_REG = []; return; }; })());” |#
This output is incorrect. There should be no "go(x);" under any relevant circumstances as by the CLHS definition of (tagbody ...) and (go ...) .
The problem seems to be that the search for the "preamble" only checks for go-tags and not for (go ...) forms. This seems to be easily fixable by amending the preamble search to terminate upon encountering a top-level (go ...) form. Problem: (tagbody (funcall (lambda () (go x))) (alert "hi") x) still has the same behaviour, *without* involving a (go ...) form at the top level of the (tagbody ...).
Alternative proposal: Do away with the preamble and instead add a dummy gensymmed jump tag at the beginning of the (tagbody ...). That jump-tag should, conceptually, be unreachable. All (go ...) forms are then affected by the (macrolet ((go ...)) ...) wrappers being placed already. Then the preamble analysis becomes dead code and can be removed.
See Jason Miller's first bug reported on 2023-01-27 for current problems with wrapping (go ...) forms inside of (lambda ...) forms.
Cheers, Andrew
On Jan 27, 2023, at 15:16, Jason Miller jason@milr.com wrote:
(parenscript:ps (defun bar () (tagbody (go x) (alert "hi") x)))