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