Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: anton@mips.complang.tuwien.ac.at (Anton Ertl) Newsgroups: comp.lang.forth Subject: Re: Back & Forth - Co-routines Date: Sun, 09 Feb 2025 23:08:22 GMT Organization: Institut fuer Computersprachen, Technische Universitaet Wien Lines: 104 Message-ID: <2025Feb10.000822@mips.complang.tuwien.ac.at> References: <874j1aycdt.fsf@nightsong.com> <3c3bdb056696f15c43fa512b5366002d@www.novabbs.com> <2025Feb6.135712@mips.complang.tuwien.ac.at> <3955434636b2a293c6a9c6d726ff6eae@www.novabbs.com> <2025Feb6.180659@mips.complang.tuwien.ac.at> <2cf9bd53562dae1241a161036e87cd6b@www.novabbs.com> <2025Feb8.120627@mips.complang.tuwien.ac.at> <87ed07vw8e.fsf@nightsong.com> Injection-Date: Mon, 10 Feb 2025 00:37:29 +0100 (CET) Injection-Info: dont-email.me; posting-host="442c14b1a1a92c17c43733f034ab60b6"; logging-data="913684"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ZzpjWpNWYSMusiRsPXdo5" Cancel-Lock: sha1:RiozWyPWsBjF+xcedt7j3qHyeBg= X-newsreader: xrn 10.11 Bytes: 5712 Paul Rubin writes: >anton@mips.complang.tuwien.ac.at (Anton Ertl) writes: >> The :}D means that the closure data is stored in the dictionary; there >> is also :}L (for locals, deallocated when the surrounding definition >> is exited), :}H (heap, deallocated with FREE-CLOSURE), and :}H1 (heap, >> deallocated right after the first (and only) execution). > >This is pretty cool, but it looks like quotations within the closure >aren't allowed to access the closure's locals Correct. You need to use a closure (and perform closure conversion and assignment conversion manually, if needed). >This is an attempt to make a counting function, like in Scheme: > >(define (x) > ((lambda (n) > (lambda () > (set! n (+ 1 n)) > n)) 0)) > >(define a (x)) > >(a) ; 1 >(a) ; 2, etc. : x ( -- xt ) here 0 , [{: addr :}d addr @ 1+ dup addr ! ;] ; x alias a x alias b a . \ 1 a . \ 2 b . \ 1 a . \ 3 Given that you are using dictionary allocation, traditional Forth allocation for the mutable data is fine. There is also a syntax for allocating data in other locations, but you don't need it with dictionary allocation and traditional dictionary allocation is usually shorter. With that syntax the equivalent would be: : x ( -- xt ) 0 <{: w^ n :}d n ;> drop [{: n :}d n @ 1+ dup n ! ;] ; The other issue is that the value-flavoured local N or ADDR in the closure cannot be changed in a way that takes effect outside the closure. So you give an address to it, and use @, ! etc. to work on that (assignment conversion). >It would be interesting if your conservative gc could be made reliable >and included with gforth, and then another suffix could be added to put >closure locals in the gc'd heap. Yes. There is :}xt for passing an xt that performs the allocation. See for all of these topics. Or read the paper: @InProceedings{ertl&paysan18, author = {M. Anton Ertl and Bernd Paysan}, title = {Closures --- the {Forth} way}, crossref = {euroforth18}, pages = {17--30}, url = {https://www.complang.tuwien.ac.at/papers/ertl%26paysan.pdf}, url2 = {http://www.euroforth.org/ef18/papers/ertl.pdf}, slides-url = {http://www.euroforth.org/ef18/papers/ertl-slides.pdf}, video = {https://wiki.forth-ev.de/doku.php/events:ef2018:closures}, OPTnote = {refereed}, abstract = {In Forth 200x, a quotation cannot access a local defined outside it, and therefore cannot be parameterized in the definition that produces its execution token. We present Forth closures; they lift this restriction with minimal implementation complexity. They are based on passing parameters on the stack when producing the execution token. The programmer has to explicitly manage the memory of the closure. We show a number of usage examples. We also present the current implementation, which takes 109~source lines of code (including some extra features). The programmer can mechanically convert lexical scoping (accessing a local defined outside) into code using our closures, by applying assignment conversion and flat-closure conversion. The result can do everything one expects from closures, including passing Knuth's man-or-boy test and living beyond the end of their enclosing definitions.} } > Also in a threaded >program I guess it would have to stop any threads that shared a GC'd >heap during collection of that heap. That's a tough one. My current thinking is along the lines of a per-thread allocator and garbage-collector, with no heap-allocated data passed between threads. Then thread-unaware GCs are good enough. - anton -- M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html New standard: https://forth-standard.org/ EuroForth 2023 proceedings: http://www.euroforth.org/ef23/papers/ EuroForth 2024 proceedings: http://www.euroforth.org/ef24/papers/