Adding CL:TAGBODY for SERIES support

Jason Miller jason at milr.com
Fri Jan 27 21:54:37 UTC 2023


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