Adding CL:TAGBODY for SERIES support

Jason Miller jason at milr.com
Fri Jan 27 22:16:50 UTC 2023


Answering my own question, it seems to at least have some support, but the
following rather simple test-case seems to trip it up somehow:

(parenscript:ps (defun bar () (tagbody (go x) (alert "hi") x)))

-Jason

On Fri, 27 Jan 2023 13:54:37 -0800 Jason Miller <jason at milr.com> wrote:
> Neat!  I'll take a closer look later.
> 
> Does it fully support the strange combination of lexical scope and dynamic
> extent that CL:TAGBODY does?
> 
> For example:
> 
>     (defun foo (x) (funcall x))
>     (tagbody
>      (foo (lambda () (go x)))
>      (format t "This does not happen~%")
>      x)
> 
> -Jason
> 
> On Fri, 27 Jan 2023 09:00:58 -0700 Andrew Easton <Andrew at Easton24.com> wrote:
> > Hello everyone, 
> > 
> > How’s it going?
> > 
> > There is now a working version of (parenscript:defpsmacro tagbody (&body body) …)),
> > See my blog post here: "https://dapperdrake.neocities.org/faster-loops-javascript <https://dapperdrake.neocities.org/faster-loops-javascript>” .
> > 
> > This adds nestable (tagbody … (tagbody …) …)) forms as a user-land library to parenscript.
> > 
> > Apologies for missing documentation.  It will be added gradually.  Also, hosting a tarball on
> > Neocities.org is planned in future as well as somehow getting the library into quicklisp. A name
> > like parenscript-tagbody-go seems useful.
> > 
> > This code is still missing the check of *DEFINED-OPERATORS*.  How is that supposed to look?
> > 
> > 
> > 
> > Cheers,
> > Andrew 
> > 
> > 
> > 
> > 
> > 
> > 
> > > On May 29, 2022, at 20:24, Andrew Easton <andrew at easton24.de> wrote:
> > > 
> > > Hi Philipp,
> > > 
> > > That sounds like a good plan.
> > > 
> > > From my current vantage point, this seems like step
> > > three.  I just got done with at step one.  Step two
> > > is for me to get acquainted with the parenscript
> > > codebase.
> > > 
> > > I will get a feel the existing code base and then we
> > > can take the next steps from there.
> > > 
> > > I already cloned the git repository to my local
> > > development machine.  The current commit for branch
> > > master seems to be:
> > > 
> > > commit 1fd720bc4e2bc5ed92064391b730b9d4db35462a (HEAD -> master)
> > > | Author: Vladimir Sedach <vas at oneofus.la>
> > > | Date:   Wed Jun 17 20:29:19 2020 -0700
> > > 
> > > 
> > > Regarding tail-call optimization in JavaScript:
> > > Jason Miller also recommended that.  Unfortunately, I
> > > dug up information indicating that it is unsupported
> > > in Google's V8 JavaScript implementation, see
> > > [stackoverflow.com (2017)].
> > > 
> > > Quoting part of my reply to Jason for the benefit of
> > > future readers of this specific email:
> > > 
> > >> [...] This seems to necessitate a (loop (case ...))
> > >> based approach, because SERIES may be used for loops
> > >> with iteration counts greater than the stack size.
> > >> Nevertheless, not all is lost.
> > >> 
> > >> PARENSCRIPT already compiles
> > >> (block nil ((lambda () (return 3)))) as catch/throw
> > >> correctly.  Note, the call in the body of the BLOCK.
> > >> So at least some dynamic ((lambda () (go ...))) calls
> > >> should be compilable; hopefully all of them.  Even if
> > >> it only captures 70% of all use cases, that is way
> > >> more than zero.
> > > 
> > > 
> > > 
> > > Cheers,
> > > Andrew
> > > 
> > > 
> > > 
> > > [stackoverflow.com (2017)], Answer by T.J. Crowder:
> > > TITLE:
> > > ES6 Tail Recursion Optimisation Stack Overflow,
> > > URL:
> > > https://stackoverflow.com/questions/42788139/es6-tail-recursion-optimisation-stack-overflow
> > > 
> > > 
> > > 
> > > On Sat, May 21, 2022 at 10:58:57AM +0200, Philipp Marek wrote:
> > >> Hi Andrew,
> > >> 
> > >> first of all -- how about registering on gitlab.common-lisp.net,
> > >> so that you can become a developer for [1] and work with a branch
> > >> using a Merge Request?
> > >> It would be much easier to track your progress (and individual changes)
> > >> that way.
> > >> 
> > >>> 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.
> > >> 
> > >> Hmmm, okay.
> > >> My first thought would've been to use a function for each
> > >> part and just do tail recursion... but it seems that
> > >> this isn't really supported in Javascript?!
> > >> 
> > >> 
> > >> 
> > >>> 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.
> > >> 
> > >> Yeah... that would be a good reason for simple function
> > >> calls and tail recursion.
> > >> 
> > >> 
> > >>> 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.
> > >> 
> > >> I'll take a look - but please let's try to get it into
> > >> the git repo first, so that any discussions have some
> > >> common state to refer to.
> > >> 
> > >> 
> > >>> 2. My understanding of the CL:TAGBODY definition in
> > >>>   the CLHS [4] may be wrong.  Which alternate
> > >>>   interpretations does anybody here know of?
> > >> 
> > >> What are your questions, or points of confusion?
> > >> 
> > >> 
> > >> 
> > >> Ad 1: https://gitlab.common-lisp.net/parenscript/parenscript
> > > 
> > 



More information about the parenscript-devel mailing list