Hello everyone,
It seems valuable to compile SERIES [1] macros with
PARENSCRIPT [2], however, parenscript does not currently
seem to support CL:TAGBODY [3,4]. Even poking around the
HyperSpec and discovering that CL:DO provides *not* an
implicit progn, but an implicit tagbody [5], does not
help. The (PARENSCRIPT:DO ...)-form only has an implicit
progn around the body [3].
I have started to implement TAGBODY for PARENSCRIPT
[A,B,C]. The general idea is to imitate a jump table
by looping over a switch-case. A GO (C-terminology:
jump) then sets the switch-variable to the next jump
destination. The loop subsequently causes the switch
to branch to the jump target in the switch-variable.
Leaving the tagbody means leaving the loop.
There are complications. Common Lisp allows nested
tagbody-forms. Common Lisp allows go-tags to be
referenced within the lexical scope *and* the dynamic
extent of a tagbody form. This means that a LAMBDA
can close over a go-tag and jump there, see an
example in [B], of how inconvenient this can become
for compilation to JavaScript.
PARENSCRIPT is well-designed. Its compilation of
BLOCKs, LOOPs and SWITCHes seems to permit
compilation of a TAGBODY to JavaScript code.
PARENSCRIPT even handles RETURNing from a BLOCK via a
LAMBDA by automatically creating a JavaScript try-catch.
This seems to curb the inconveniences brought on by
lexical closures jumping to go-tags in the TAGBODY's
dynamic extent.
I need help in the following points:
1. I need a code review of the algorithm.
The implementation in [B] seems to be
satisfactory. There are some test cases and
examples. Most there is the most hairy example I
could find up to now. I may have missed crucial
details.
2. My understanding of the CL:TAGBODY definition in
the CLHS [4] may be wrong. Which alternate
interpretations does anybody here know of?
3. What examples of PARENSCRIPT:DEFPSMACRO do you
know, that might help me understand its semantics?
I would hazard a guess at DEFPSMACRO being a
facility to add TAGBODY to PARENSCRIPT, however,
my understanding of DEFPSMACRO is very bad and I
do not know where to start tinkering with it to
further my understanding.
Kind regards,
Andrew Easton
=== Attachments ===
[A] 2022-05-20_defmacro-series-expand.lisp
[B] 2022-05-20_parenscript-devel_tagbody-code-short.lisp
[C] 2022-05-20_parenscript-devel_tagbody-code-long.lisp
The long version contains some dead-ends that were
encountered during development. This is an important
source of counter-examples.
=== References ===
[1] The SERIES macro package
a. https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node347.html#SECTION00340000…
b. https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node362.html#SECTION00350000…
c. https://dspace.mit.edu/handle/1721.1/6035
d. https://dspace.mit.edu/handle/1721.1/6031
e. (ql:quickload :series)
f. https://sourceforge.net/projects/series/
[2] Parenscript
https://parenscript.common-lisp.dev/
[3] Parenscript Reference manual (updated 2019-10-15)
https://parenscript.common-lisp.dev/reference.html
[4] Common Lisp HyperSpec (CLHS) entry for CL:TAGBODY
http://www.lispworks.com/documentation/HyperSpec/Body/s_tagbod.htm#tagbody
[5] Common Lisp HyperSpec (CLHS) entry for CL:DO
http://www.lispworks.com/documentation/HyperSpec/Body/m_do_do.htm#do