Rocksolid Light

Welcome to Rocksolid Light

mail  files  register  newsreader  groups  login

Message-ID:  

Single tasking: Just Say No.


devel / comp.lang.forth / FOR-EACH ... DO[ ... ]NEXT

SubjectAuthor
* FOR-EACH ... DO[ ... ]NEXTGerry Jackson
+* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
|+* Re: FOR-EACH ... DO[ ... ]NEXTnone
||`- Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
|`* Re: FOR-EACH ... DO[ ... ]NEXTminforth
| `- Re: FOR-EACH ... DO[ ... ]NEXTnone
+* Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
|+- Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
|+* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||+- Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||`* Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
|| +- Re: FOR-EACH ... DO[ ... ]NEXTnone
|| `* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||  `* Re: FOR-EACH ... DO[ ... ]NEXTHelmut Eller
||   `* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||    `* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||     +* Re: FOR-EACH ... DO[ ... ]NEXTRuvim
||     |`- Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||     +* Re: FOR-EACH ... DO[ ... ]NEXTRuvim
||     |+* Re: FOR-EACH ... DO[ ... ]NEXTdxf
||     ||`* Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
||     || `- Re: FOR-EACH ... DO[ ... ]NEXTdxf
||     |`- Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||     `* Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
||      `* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||       +* Re: FOR-EACH ... DO[ ... ]NEXTminforth
||       |`* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||       | +* Re: FOR-EACH ... DO[ ... ]NEXTminforth
||       | |+- Re: FOR-EACH ... DO[ ... ]NEXTdxf
||       | |+* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||       | ||+* Re: FOR-EACH ... DO[ ... ]NEXTRuvim
||       | |||`* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||       | ||| `* Re: FOR-EACH ... DO[ ... ]NEXTRuvim
||       | |||  +- Re: FOR-EACH ... DO[ ... ]NEXTnone
||       | |||  `* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||       | |||   `* Re: FOR-EACH ... DO[ ... ]NEXTHans Bezemer
||       | |||    `- Re: FOR-EACH ... DO[ ... ]NEXTnone
||       | ||`- Re: FOR-EACH ... DO[ ... ]NEXTminforth
||       | |+- Re: FOR-EACH ... DO[ ... ]NEXTnone
||       | |`- Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
||       | +* Documenting system-specific behavior (was: FOR-EACH ... DO[ ...Ruvim
||       | |`* Re: Documenting system-specific behaviorRuvim
||       | | `* Re: Documenting system-specific behaviordxf
||       | |  `* Re: Documenting system-specific behaviorAnton Ertl
||       | |   `* Re: Documenting system-specific behaviordxf
||       | |    `* Re: Documenting system-specific behaviorAnton Ertl
||       | |     `- Re: Documenting system-specific behaviordxf
||       | `- Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
||       `* Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
||        `* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
||         `* Re: FOR-EACH ... DO[ ... ]NEXTAnton Ertl
||          `- Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
|`* Re: FOR-EACH ... DO[ ... ]NEXTRuvim
| `* Re: FOR-EACH ... DO[ ... ]NEXTdxf
|  `* Re: FOR-EACH ... DO[ ... ]NEXTRuvim
|   `* Re: FOR-EACH ... DO[ ... ]NEXTdxf
|    `- Re: FOR-EACH ... DO[ ... ]NEXTJan Coombs
+* Re: FOR-EACH ... DO[ ... ]NEXTHans Bezemer
|`* Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson
| +- Re: FOR-EACH ... DO[ ... ]NEXTDoug Hoffman
| +- Re: FOR-EACH ... DO[ ... ]NEXTminforth
| `- Re: FOR-EACH ... DO[ ... ]NEXTHans Bezemer
`* Re: FOR-EACH ... DO[ ... ]NEXTHelmut Eller
 `- Re: FOR-EACH ... DO[ ... ]NEXTGerry Jackson

Pages:123
FOR-EACH ... DO[ ... ]NEXT

<uilq87$2tvlh$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25347&group=comp.lang.forth#25347

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!news.hispagatos.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: FOR-EACH ... DO[ ... ]NEXT
Date: Fri, 10 Nov 2023 17:45:44 +0000
Organization: A noiseless patient Spider
Lines: 101
Message-ID: <uilq87$2tvlh$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 10 Nov 2023 17:45:44 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="727ef3e85fac1fcad71054e633483ab3";
logging-data="3079857"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/YZwL2B41YLDOPIn7psWhIlzfzQ0B5YT8="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:LWyEse/DaPzf6f9DPxOEf+/OfA8=
Content-Language: en-GB
 by: Gerry Jackson - Fri, 10 Nov 2023 17:45 UTC

Complex loops with multiple WHILEs can be difficult to understand
particularly when returning to a program written some time ago. I wanted
a more readable control statement that expressed 'what' it did instead
of 'how' it did it. Also I wanted the ability to carry out a pipeline of
operations on a collection of data objects (array, linked list etc).

After some experimentation I ended up with this statement:
FOR-EACH <iterator> DO[ <pipeline operations> ]NEXT

The <iterator> is completely under the programmers control to provide
the next item in any type of data structure

Other requirements on pipeline operations:
- to be able to return to the <iterator> early i.e 'continue'
- to be able to exit the loop early i.e. 'break'
- (optional) possibly normal forth definitions

\ --------------------------------------

synonym for-each begin
synonym do[ while
synonym ]next repeat

: => ( f -- )
0 cs-pick postpone ?dup postpone 0= postpone until
; immediate

: pp=> ( -- ) postpone => ;

: p: : postpone [: ;
: ;p
postpone ;] postpone compile, postpone pp=> postpone ; immediate
; immediate

\ --------------------------------------

As can be seen this is just renaming BEGIN ... WHILE ... REPEAT for
readability with some rules that can be ignored or varied as needed by
the programmer.

- Pipeline operations can be defined using P: ... ;P or : ... ; the
difference being that P: incorporates the word => at the end to insert
the 'continue' control sequence. If normal colon definitions are used
and 'continue' is needed the word => must be used between operations

The rules to be used are:
- the <iterator> must return a non-zero value to continue the loop or a
zero to exit the loop.
- that pipeline operations must return a flag with possible values:
0 carry on to the next operation
-1 loop back to the iterator for the next iteration (continue)
+1 loop back to the iterator and exit the loop (break)

If neither 'continue' or 'break' are needed the FOR-EACH statement is
just a simple BEGIN ... WHILE ... REPEAT loop. Therefore normal colon
definitions can be used in the pipeline.

Using a simple/silly example display integers divisible by 6 that
Michael Gassanenko used to demonstrate his similar ... START ... EMERGE
.... construct, we have:

: n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f2 true when n1<n2
drop 1+ 2dup >=
;

p: /2? ( n -- n f ) dup 2 mod ;p
p: /3? ( n -- n f ) dup 3 mod ;p
: .n ( n -- n ) dup . -1 ;

: /6? ( n1 n2 -- )
0 for-each n+1 do[ /2? /3? .n ]next 2drop
;

cr 50 0 /6? .s
\ displays 6 12 18 24 30 36 42 48

Alternatively using a 'break' in \2?

: n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f1 = +/-1
0> if 0 exit then 1+ true
;

p: /2? ( n1 n2 -- n1 n2 f ) 2dup < if 1 exit then dup 2 mod 0<> ;p
p: /3? ( n -- n f ) dup 3 mod 0<> ;p
: .n ( n -- n ) dup . -1 ;

: /6? ( n1 n2 -- )
for-each n+1 do[ /2? /3? .n ]next 2drop
;

cr 63 0 true /6? .s
\ displays 6 12 18 24 30 36 42 48 54 60

Of course imposing some rules means that some efficiency is lost
compared to WHILE loops but, as I use a desktop system, speed is never a
problem for me.

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<uitpt1$qsjs$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25356&group=comp.lang.forth#25356

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Mon, 13 Nov 2023 18:28:50 +0000
Organization: A noiseless patient Spider
Lines: 95
Message-ID: <uitpt1$qsjs$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Mon, 13 Nov 2023 18:28:50 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="17faf5baf9cd30d27576f3e1efcfea33";
logging-data="881276"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+zlox1CL9Oe2CSY9Wiqk3kIqUcAZkXgO8="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:QBhD4HISLpcbw7VLgGXR3j76Ofk=
In-Reply-To: <uilq87$2tvlh$1@dont-email.me>
Content-Language: en-GB
 by: Gerry Jackson - Mon, 13 Nov 2023 18:28 UTC

On Friday, November 10, 2023 at 9:21:34 PM UTC, Brian Fox wrote:
> On Friday, November 10, 2023 at 12:45:47 PM UTC-5, Gerry Jackson wrote:
> > \ --------------------------------------
> >
> > synonym for-each begin
> > synonym do[ while
> > synonym ]next repeat
> >
> > : => ( f -- )
> > 0 cs-pick postpone ?dup postpone 0= postpone until
> > ; immediate
> >
> > : pp=> ( -- ) postpone => ;
> >
> > : p: : postpone [: ;
> > : ;p
> > postpone ;] postpone compile, postpone pp=> postpone ; immediate
> > ; immediate
> >
> > \ --------------------------------------
> >

> That's a very tidy way to do this. I was looking with lust at the
> Python functions MAP REDUCE and FILTER.

Such High Order Functions were one of the motivations for the FOR-EACH
statement

> The key insight for me was that they require an "initial value".

I'm not sure what you mean.

>
> I play with a retro machine so memory is tight so I just used the
> dictionary in a crude way to get a kind of dynamic array storage.
> This allows the HOFs to output another array which can be
> further processed. You can name an array with DATA:
> or just use the result directly from the data stack.
>
> Each array is stored as a CELL counted list of cells. SIZE converts
> a counted array into an (addr,len) pair.
>
> Here is what I came up with. (ignore the INCLUDE statements)
> https://github.com/bfox9900/CAMEL99-ITC/blob/master/LIB.ITC/MAPCELLS.FTH
>
> At the moment it only works for CELL data.
> But of course the cells could be pointers. I just haven't gone farther.
>
> I just tried it on GForth .73 and I broke the rules and didn't use CELL.
> :-)
> Now it works.
> Might give you some ideas.

Yes. Your work is with arrays only but, of course, can be extended to
other data types/structures. I am trying for a general solution that can
be applied to any type of data structure. For comparison here is a
definition of MAP with two examples of use on an integer array such as
used in your examples

: map ( ... iter-xt op-xt -- ... )
2>r for-each 2r@ drop execute do[ r@ execute ]next 2r> 2drop
;

\ The data aray
create a[] 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,
10 constant a-len

\ The iterator, ad1 is end adress, ad2' the next array item address
:noname ( ad1 ad2 -- ad1 ad2' f )
cell+ 2dup u>
; constant next-item

\ The operation on each integer in the array
:noname ( ad -- ad ) dup @ dup * over ! ; constant squared

: init ( ad n -- ad+n' ad ) cells over + swap 1 cells - ;

: square[] ( ad n -- )
init next-item squared map 2drop
;

a[] a-len square[]

\ Display the array contents using MAP again

: .a[] init next-item [: ( ad -- ad ) dup @ . ;] map 2drop ;

cr a[] a-len .a[] cr

\ Displays
\ 1 4 9 16 25 36 49 64 81 100

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<nnd$277300f8$7bf5e57a@1b5a3600d5c75027>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25357&group=comp.lang.forth#25357

  copy link   Newsgroups: comp.lang.forth
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
References: <uilq87$2tvlh$1@dont-email.me> <uitpt1$qsjs$1@dont-email.me>
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$277300f8$7bf5e57a@1b5a3600d5c75027>
Organization: KPN B.V.
Date: Mon, 13 Nov 2023 21:03:40 +0100
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!feed.abavia.com!abe004.abavia.com!abp001.abavia.com!news.kpn.nl!not-for-mail
Lines: 47
Injection-Date: Mon, 13 Nov 2023 21:03:40 +0100
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
 by: none - Mon, 13 Nov 2023 20:03 UTC

In article <uitpt1$qsjs$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
>On Friday, November 10, 2023 at 9:21:34 PM UTC, Brian Fox wrote:
> > On Friday, November 10, 2023 at 12:45:47 PM UTC-5, Gerry Jackson wrote:
> > > \ --------------------------------------
> > >
> > > synonym for-each begin
> > > synonym do[ while
> > > synonym ]next repeat
> > >
> > > : => ( f -- )
> > > 0 cs-pick postpone ?dup postpone 0= postpone until
> > > ; immediate
> > >
> > > : pp=> ( -- ) postpone => ;
> > >
> > > : p: : postpone [: ;
> > > : ;p
> > > postpone ;] postpone compile, postpone pp=> postpone ; immediate
> > > ; immediate
> > >
> > > \ --------------------------------------
> > >
>
> > That's a very tidy way to do this. I was looking with lust at the
> > Python functions MAP REDUCE and FILTER.
>
>Such High Order Functions were one of the motivations for the FOR-EACH
>statement
>
> > The key insight for me was that they require an "initial value".
>
>I'm not sure what you mean.

If you want to apply + to a set you have to start with 0, OTOH
with * you must start with 1. If you want to print every word in
a wordlist you don't need it.

>
>Gerry
>
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat spinning. - the Wise from Antrim -

Re: FOR-EACH ... DO[ ... ]NEXT

<3bf703fe10a4ae729a6449cd2fe9d7fc@news.novabbs.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25358&group=comp.lang.forth#25358

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!.POSTED!not-for-mail
From: minforth@gmx.net (minforth)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Mon, 13 Nov 2023 20:03:24 +0000
Organization: novaBBS
Message-ID: <3bf703fe10a4ae729a6449cd2fe9d7fc@news.novabbs.com>
References: <uilq87$2tvlh$1@dont-email.me> <uitpt1$qsjs$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Info: i2pn2.org;
logging-data="811877"; mail-complaints-to="usenet@i2pn2.org";
posting-account="t+lO0yBNO1zGxasPvGSZV1BRu71QKx+JE37DnW+83jQ";
User-Agent: Rocksolid Light
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on novalink.us
X-Rslight-Site: $2y$10$4Lg2gEr9mk9K/kGqwDxVy.YzsfARTgNX.GgeQ99UV6bkfYcXpgWPG
X-Rslight-Posting-User: 0d6d33dbe0e2e1ff58b82acfc1a8a32ac3b1cb72
 by: minforth - Mon, 13 Nov 2023 20:03 UTC

Gerry Jackson wrote:

> > That's a very tidy way to do this. I was looking with lust at the
> > Python functions MAP REDUCE and FILTER.

> Such High Order Functions were one of the motivations for the FOR-EACH
> statement

> > The key insight for me was that they require an "initial value".

> I'm not sure what you mean.

> >
> > I play with a retro machine so memory is tight so I just used the
> > dictionary in a crude way to get a kind of dynamic array storage.
> > This allows the HOFs to output another array which can be
> > further processed. You can name an array with DATA:
> > or just use the result directly from the data stack.

On machines with sufficient heap, it is worth implementing dynamic arrays.
I use an array stack and array values for this. They only contain a pointer
to the array structs in the heap. Then implementing HOFs for arrays is not
difficult (my arrays are mostly long 1-dimensional signal vectors with
thousands of elements).

Nice side effect: since strings are only character arrays, you get dynamic
strings for practically nothing.

Re: FOR-EACH ... DO[ ... ]NEXT

<uivgff$16eeo$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25359&group=comp.lang.forth#25359

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!usenet.goja.nl.eu.org!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 14 Nov 2023 10:00:15 +0000
Organization: A noiseless patient Spider
Lines: 45
Message-ID: <uivgff$16eeo$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me> <uitpt1$qsjs$1@dont-email.me>
<nnd$277300f8$7bf5e57a@1b5a3600d5c75027>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 14 Nov 2023 10:00:15 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="f15a7bba82ff8b4fe96a99825c40a8cf";
logging-data="1259992"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/eRVIbDuHZpdup/ZlD2LfE5hXT6VgqQ/M="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:bDHQrBFPP9JUrnR2BYUjMou6+us=
Content-Language: en-GB
In-Reply-To: <nnd$277300f8$7bf5e57a@1b5a3600d5c75027>
 by: Gerry Jackson - Tue, 14 Nov 2023 10:00 UTC

On 13/11/2023 20:03, albert wrote:
> In article <uitpt1$qsjs$1@dont-email.me>,
> Gerry Jackson <do-not-use@swldwa.uk> wrote:
>> On Friday, November 10, 2023 at 9:21:34 PM UTC, Brian Fox wrote:
>>> On Friday, November 10, 2023 at 12:45:47 PM UTC-5, Gerry Jackson wrote:
>>>> \ --------------------------------------
>>>>
>>>> synonym for-each begin
>>>> synonym do[ while
>>>> synonym ]next repeat
>>>>
>>>> : => ( f -- )
>>>> 0 cs-pick postpone ?dup postpone 0= postpone until
>>>> ; immediate
>>>>
>>>> : pp=> ( -- ) postpone => ;
>>>>
>>>> : p: : postpone [: ;
>>>> : ;p
>>>> postpone ;] postpone compile, postpone pp=> postpone ; immediate
>>>> ; immediate
>>>>
>>>> \ --------------------------------------
>>>>
>>
>>> That's a very tidy way to do this. I was looking with lust at the
>>> Python functions MAP REDUCE and FILTER.
>>
>> Such High Order Functions were one of the motivations for the FOR-EACH
>> statement
>>
>>> The key insight for me was that they require an "initial value".
>>
>> I'm not sure what you mean.
>
> If you want to apply + to a set you have to start with 0, OTOH
> with * you must start with 1. If you want to print every word in
> a wordlist you don't need it.
>

Yes, of course. I was looking for something more complicated. Thanks.

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<nnd$059c79d3$5bc6e897@f4d60baa1fd3e501>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25360&group=comp.lang.forth#25360

  copy link   Newsgroups: comp.lang.forth
Newsgroups: comp.lang.forth
References: <uilq87$2tvlh$1@dont-email.me> <uitpt1$qsjs$1@dont-email.me> <3bf703fe10a4ae729a6449cd2fe9d7fc@news.novabbs.com>
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$059c79d3$5bc6e897@f4d60baa1fd3e501>
Organization: KPN B.V.
Date: Tue, 14 Nov 2023 11:33:29 +0100
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!peer02.ams1!peer.ams1.xlned.com!news.xlned.com!peer01.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!feed.abavia.com!abe004.abavia.com!abp003.abavia.com!news.kpn.nl!not-for-mail
Lines: 40
Injection-Date: Tue, 14 Nov 2023 11:33:29 +0100
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
X-Received-Bytes: 2415
 by: none - Tue, 14 Nov 2023 10:33 UTC

In article <3bf703fe10a4ae729a6449cd2fe9d7fc@news.novabbs.com>,
minforth <minforth@gmx.net> wrote:
>Gerry Jackson wrote:
>
>> > That's a very tidy way to do this. I was looking with lust at the
>> > Python functions MAP REDUCE and FILTER.
>
>> Such High Order Functions were one of the motivations for the FOR-EACH
>> statement
>
>> > The key insight for me was that they require an "initial value".
>
>> I'm not sure what you mean.
>
>> >
>> > I play with a retro machine so memory is tight so I just used the
>> > dictionary in a crude way to get a kind of dynamic array storage.
>> > This allows the HOFs to output another array which can be
>> > further processed. You can name an array with DATA:
>> > or just use the result directly from the data stack.
>
>On machines with sufficient heap, it is worth implementing dynamic arrays.
>I use an array stack and array values for this. They only contain a pointer
>to the array structs in the heap. Then implementing HOFs for arrays is not
>difficult (my arrays are mostly long 1-dimensional signal vectors with
>thousands of elements).
>
>Nice side effect: since strings are only character arrays, you get dynamic
>strings for practically nothing.

I'm not sure what you gain here. On small machines you can hardly afford
setting aside space for a heap.

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat spinning. - the Wise from Antrim -

Re: FOR-EACH ... DO[ ... ]NEXT

<2023Nov14.183012@mips.complang.tuwien.ac.at>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25361&group=comp.lang.forth#25361

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: anton@mips.complang.tuwien.ac.at (Anton Ertl)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 14 Nov 2023 17:30:12 GMT
Organization: Institut fuer Computersprachen, Technische Universitaet Wien
Lines: 57
Message-ID: <2023Nov14.183012@mips.complang.tuwien.ac.at>
References: <uilq87$2tvlh$1@dont-email.me>
Injection-Info: dont-email.me; posting-host="e2732d31b508a467e591790e7b6b9dd9";
logging-data="1409012"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19T+JWtwikxRcI6ueS/9GeZ"
Cancel-Lock: sha1:5fFCcIIagfRO9YqHIq9oL78CkMM=
X-newsreader: xrn 10.11
 by: Anton Ertl - Tue, 14 Nov 2023 17:30 UTC

Gerry Jackson <do-not-use@swldwa.uk> writes:
>Complex loops with multiple WHILEs can be difficult to understand
>particularly when returning to a program written some time ago.

Of course this makes me think of the extended case construct (present
in development Gforth).

Your variant is interesting, but it's not clear enough to me what it
can do. So let's see:

>Using a simple/silly example display integers divisible by 6 that
>Michael Gassanenko used to demonstrate his similar ... START ... EMERGE
>... construct, we have:
>
>: n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f2 true when n1<n2
> drop 1+ 2dup >=
>;
>
>p: /2? ( n -- n f ) dup 2 mod ;p
>p: /3? ( n -- n f ) dup 3 mod ;p
>: .n ( n -- n ) dup . -1 ;
>
>: /6? ( n1 n2 -- )
> 0 for-each n+1 do[ /2? /3? .n ]next 2drop
>;
>
>cr 50 0 /6? .s
>\ displays 6 12 18 24 30 36 42 48

Let's see how this turns out with the extended CASE:

: /6? ( limit start -- )
case ( limit n )
1+ 2dup < ?of 2drop endof
dup 2 mod ?of contof
dup 3 mod ?of contof
dup .
next-case ;

cr 50 0 /6?

This produces the expected output, and you can see how the parts of
the definition relate to the code in your variant.

Maybe there is an example where FOR-EACH ... DO[ ... ]NEXT is harder
to replace.

Given the number of cases where I have written nothing between the ?OF
and the following ENDOF or CONTOF, maybe a ?ENDOF or ?CONTOF
(equivalent to 0= ?OF ENDOF or 0= ?OF CONTOF) may be useful.

- 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: https://euro.theforth.net/2023

Re: FOR-EACH ... DO[ ... ]NEXT

<2023Nov14.190528@mips.complang.tuwien.ac.at>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25362&group=comp.lang.forth#25362

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!rocksolid2!news.neodome.net!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: anton@mips.complang.tuwien.ac.at (Anton Ertl)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 14 Nov 2023 18:05:28 GMT
Organization: Institut fuer Computersprachen, Technische Universitaet Wien
Lines: 13
Message-ID: <2023Nov14.190528@mips.complang.tuwien.ac.at>
References: <uilq87$2tvlh$1@dont-email.me> <2023Nov14.183012@mips.complang.tuwien.ac.at>
Injection-Info: dont-email.me; posting-host="e2732d31b508a467e591790e7b6b9dd9";
logging-data="1409012"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19OTMB58mYuoWqDSQ0X1Rww"
Cancel-Lock: sha1:TemHb+454fHuut13Ct47x/yAlyw=
X-newsreader: xrn 10.11
 by: Anton Ertl - Tue, 14 Nov 2023 18:05 UTC

anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>Given the number of cases where I have written nothing between the ?OF
>and the following ENDOF or CONTOF, maybe a ?ENDOF or ?CONTOF
>(equivalent to 0= ?OF ENDOF or 0= ?OF CONTOF) may be useful.

Or rather, without the "0="s

- 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: https://euro.theforth.net/2023

Re: FOR-EACH ... DO[ ... ]NEXT

<5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25363&group=comp.lang.forth#25363

  copy link   Newsgroups: comp.lang.forth
X-Received: by 2002:a37:e108:0:b0:774:143e:f96a with SMTP id c8-20020a37e108000000b00774143ef96amr63959qkm.12.1699986719772;
Tue, 14 Nov 2023 10:31:59 -0800 (PST)
X-Received: by 2002:a17:90b:118e:b0:280:c576:31be with SMTP id
gk14-20020a17090b118e00b00280c57631bemr2900118pjb.4.1699986719442; Tue, 14
Nov 2023 10:31:59 -0800 (PST)
Path: i2pn2.org!i2pn.org!news.1d4.us!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.forth
Date: Tue, 14 Nov 2023 10:31:58 -0800 (PST)
In-Reply-To: <70cba185-4986-4af8-9ede-457c6e524ae1n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=77.174.47.232; posting-account=Ebqe4AoAAABfjCRL4ZqOHWv4jv5ZU4Cs
NNTP-Posting-Host: 77.174.47.232
References: <uilq87$2tvlh$1@dont-email.me> <70cba185-4986-4af8-9ede-457c6e524ae1n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com>
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
From: the.beez.speaks@gmail.com (Hans Bezemer)
Injection-Date: Tue, 14 Nov 2023 18:31:59 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 1794
 by: Hans Bezemer - Tue, 14 Nov 2023 18:31 UTC

On Friday, November 10, 2023 at 10:21:34 PM UTC+1, Brian Fox wrote:
> Now it works.
> Might give you some ideas.

Ideas like these?

: foreach ( 'f addr count -- )
cells bounds do
I @ over execute
loop drop ;

\ where : f ( n -- m )
: map ( 'f addr count -- )
cells bounds do
I @ over execute I !
loop drop ;

\ where : f ( st n -- st' )
: reduce ( st 'f addr count -- st' )
cells bounds do
I @ swap dup >r execute r>
loop drop ;

Hans Bezemer

Re: FOR-EACH ... DO[ ... ]NEXT

<uj21sp$1m789$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25364&group=comp.lang.forth#25364

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Wed, 15 Nov 2023 09:09:45 +0000
Organization: A noiseless patient Spider
Lines: 35
Message-ID: <uj21sp$1m789$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<70cba185-4986-4af8-9ede-457c6e524ae1n@googlegroups.com>
<5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Wed, 15 Nov 2023 09:09:45 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="a974f0f82901d89c7a45cc0632d71b52";
logging-data="1776905"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+zTY96gl3nMznZbDpu332WKEDJjYa/kGQ="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:jCdPbXWbNbckSRYB3VgvQo4TCrw=
Content-Language: en-GB
In-Reply-To: <5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com>
 by: Gerry Jackson - Wed, 15 Nov 2023 09:09 UTC

On 14/11/2023 18:31, Hans Bezemer wrote:
> On Friday, November 10, 2023 at 10:21:34 PM UTC+1, Brian Fox wrote:
>> Now it works.
>> Might give you some ideas.
>
> Ideas like these?
>
> : foreach ( 'f addr count -- )
> cells bounds do
> I @ over execute
> loop drop ;
>
> \ where : f ( n -- m )
> : map ( 'f addr count -- )
> cells bounds do
> I @ over execute I !
> loop drop ;
>
> \ where : f ( st n -- st' )
> : reduce ( st 'f addr count -- st' )
> cells bounds do
> I @ swap dup >r execute r>
> loop drop ;
>

You'd need a different version of these for other collections e.g.
linked list. I was trying for a more general solution.

Its easy to write solutions like this for individual cases, its also
easy to make mistakes. Shouldn't the loops be ended with:
1 cells +loop

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<0caf173b-8af0-4ff6-a318-f14663f4631en@googlegroups.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25365&group=comp.lang.forth#25365

  copy link   Newsgroups: comp.lang.forth
X-Received: by 2002:ac8:704:0:b0:421:c968:4255 with SMTP id g4-20020ac80704000000b00421c9684255mr104874qth.5.1700042515400;
Wed, 15 Nov 2023 02:01:55 -0800 (PST)
X-Received: by 2002:a17:90a:2a82:b0:281:ea1c:8198 with SMTP id
j2-20020a17090a2a8200b00281ea1c8198mr3585809pjd.8.1700042515159; Wed, 15 Nov
2023 02:01:55 -0800 (PST)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.forth
Date: Wed, 15 Nov 2023 02:01:54 -0800 (PST)
In-Reply-To: <uj21sp$1m789$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=68.36.198.233; posting-account=YrYQiQoAAAB3ECk4vm4OgA6KUu5AcEY0
NNTP-Posting-Host: 68.36.198.233
References: <uilq87$2tvlh$1@dont-email.me> <70cba185-4986-4af8-9ede-457c6e524ae1n@googlegroups.com>
<5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com> <uj21sp$1m789$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <0caf173b-8af0-4ff6-a318-f14663f4631en@googlegroups.com>
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
From: dhoffman888@gmail.com (Doug Hoffman)
Injection-Date: Wed, 15 Nov 2023 10:01:55 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: Doug Hoffman - Wed, 15 Nov 2023 10:01 UTC

On Wednesday, November 15, 2023 at 4:09:48 AM UTC-5, Gerry Jackson wrote:
> On 14/11/2023 18:31, Hans Bezemer wrote:
> > On Friday, November 10, 2023 at 10:21:34 PM UTC+1, Brian Fox wrote:
> >> Now it works.
> >> Might give you some ideas.
> >
> > Ideas like these?
> >
> > : foreach ( 'f addr count -- )
> > cells bounds do
> > I @ over execute
> > loop drop ;
> >
> > \ where : f ( n -- m )
> > : map ( 'f addr count -- )
> > cells bounds do
> > I @ over execute I !
> > loop drop ;
> >
> > \ where : f ( st n -- st' )
> > : reduce ( st 'f addr count -- st' )
> > cells bounds do
> > I @ swap dup >r execute r>
> > loop drop ;
> >
> You'd need a different version of these for other collections e.g.
> linked list. I was trying for a more general solution.
>
> Its easy to write solutions like this for individual cases, its also
> easy to make mistakes. Shouldn't the loops be ended with:
> 1 cells +loop
>
> --
> Gerry

If you used an objects extension then the same syntax could work
for any type of collection.

-Doug

Re: FOR-EACH ... DO[ ... ]NEXT

<85c264481ba831b57316ce4ce5965cbb@news.novabbs.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25366&group=comp.lang.forth#25366

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!.POSTED!not-for-mail
From: minforth@gmx.net (minforth)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Wed, 15 Nov 2023 10:04:50 +0000
Organization: novaBBS
Message-ID: <85c264481ba831b57316ce4ce5965cbb@news.novabbs.com>
References: <uilq87$2tvlh$1@dont-email.me> <70cba185-4986-4af8-9ede-457c6e524ae1n@googlegroups.com> <5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com> <uj21sp$1m789$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Info: i2pn2.org;
logging-data="980848"; mail-complaints-to="usenet@i2pn2.org";
posting-account="t+lO0yBNO1zGxasPvGSZV1BRu71QKx+JE37DnW+83jQ";
User-Agent: Rocksolid Light
X-Rslight-Posting-User: 0d6d33dbe0e2e1ff58b82acfc1a8a32ac3b1cb72
X-Spam-Level: *
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on novalink.us
X-Rslight-Site: $2y$10$Jg0CPcVOeCO4DgREOjGIcOCZSdsb0cieEz2KiNylxc47s5lPp7CCq
 by: minforth - Wed, 15 Nov 2023 10:04 UTC

Gerry Jackson wrote:
> On 14/11/2023 18:31, Hans Bezemer wrote:
>> On Friday, November 10, 2023 at 10:21:34 PM UTC+1, Brian Fox wrote:
>> Ideas like these?
>>
>> : foreach ( 'f addr count -- )
>> cells bounds do
>> I @ over execute
>> loop drop ;
>>
>> where : f ( n -- m )
>> : map ( 'f addr count -- )
>> cells bounds do
>> I @ over execute I !
>> loop drop ;
>>
>> where : f ( st n -- st' )
>> : reduce ( st 'f addr count -- st' )
>> cells bounds do
>> I @ swap dup >r execute r>
>> loop drop ;
>>

> Its easy to write solutions like this for individual cases, its also
> easy to make mistakes. Shouldn't the loops be ended with:
> 1 cells +loop

Things start getting funny when you want AVX2 instructions under the hood. ;-)
For individual vector type cases of course.

A more general approach is nevertheless useful for testing and prototyping.

Re: FOR-EACH ... DO[ ... ]NEXT

<m2cywbnw26.fsf@gmail.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25367&group=comp.lang.forth#25367

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: eller.helmut@gmail.com (Helmut Eller)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Wed, 15 Nov 2023 11:35:29 +0100
Organization: A noiseless patient Spider
Lines: 553
Message-ID: <m2cywbnw26.fsf@gmail.com>
References: <uilq87$2tvlh$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Info: dont-email.me; posting-host="b0a0950e6f240ce20ae7342fd749778c";
logging-data="1806702"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+8YfGO1gqC1lfsezfWQoez"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:DKGr4LZ6KMrMjZ9YGk6YHRWKUtE=
sha1:fO5zG4DxHCUXxzNX4mkNdcsU238=
 by: Helmut Eller - Wed, 15 Nov 2023 10:35 UTC

On Fri, Nov 10 2023, Gerry Jackson wrote:

> Also I wanted the ability to carry out a pipeline of operations on a
> collection of data objects (array, linked list etc).

I wanted to have something like Rust's iterator library and played
around with the code below. With this, the divisible-by-6 example could
be written as:

: /2? ( n -- flag ) 2 mod 0= ;
: /3? ( n -- flag ) 3 mod 0= ;

: /6? ( start end -- )
[range-iterator]
[ ' /2? ] [filter]
[ ' /3? ] [filter]
[ ' . ] [for-each]
;

This is arguably very close to the Rust expression:

(start..end)
.filter(|u| u % 2 == 0)
.filter(|u| u % 3 == 0)
.for_each(|u| print!("{u} "));

Unfortunately, my code is much more complicated that yours. On the plus
side, I'm trying to mimic Rust's operators and naming, which saves me
from re-inventing wheels and perhaps helps to communicate the intention
behind the operators.

Helmut

\ iter.fth --- Rust inspired iterators
\ \ Iterators are built around a function of type:
\ \ next ( state -- state' item flag )
\ \ i.e. the NEXT function computes the next state of the iterator and
\ yields ITEMs. FLAG is true if the item is valid and false if the
\ iterator is finished (in that case the item is invalid).
\ \ This code tries to be “generic” in the sense that STATE and ITEM can
\ be more than a single stack item. E.g. to iterate over the lines in
\ a file, ITEM can be a pair C-ADDR U to represent the string. The
\ size of STATE and ITEM must be known at compile time.
\ \ An example for client code is:
\ \ : foo ( ) 0 10 [range-iterator] [ ' . ] [for-each] ;
\ foo
\ \ As in Rust, a “range” is an interval of integers, and the example
\ prints the integers from 0 up to 9.
\ \ At compile time, [RANGE-ITERATOR] puts a data structure on the stack
\ that describes, among other things, the size of STATE and NEXT.
\ [FOR-EACH] uses this structure to assemble the loop. In this
\ example the produced code looks like this:
\ \ : foo 0 10 BEGIN %range-next 0<> WHILE . REPEAT drop 2drop ;
\ \ Here, %RANGE-NEXT is a specific next function that moves the
\ iterator from one state to the next. The STATE for a range iterator
\ requires two stack slots and the ITEM one slot. [FOR-EACH] also
\ assumes that the xt (produced by the [ ' . ] part in the example)
\ has type ( ITEM -- ).
\

forth-wordlist wordlist 2 set-order definitions

\ Define Gforth's r-r-bracket if needed
[undefined] ]] [if]
: refilling-parse-name ( -- old->in c-addr u )
begin
>in @ parse-name dup 0= while
2drop drop refill 0= -39 and throw
repeat
;

: ]] ( -- )
begin
refilling-parse-name s" [[" compare while
>in ! POSTPONE postpone
repeat
drop
; immediate
[then]

0
1 cells +field it.nargs \ number of args for the constructor
1 cells +field it.nstate \ number of stack slots for iterator state
1 cells +field it.nitem \ number of stack slots per yielded item
1 cells +field it.init \ xt: ( it -- )
1 cells +field it.next \ xt: ( it -- )
1 cells +field it.drop \ xt: ( it -- )
1 cells +field it.next-back \ xt: ( it -- )
constant /iter-type

: [for-each] {: it xt -- :}
it dup it.init @ execute
]]
begin
[[ it dup it.next @ execute ]] 0<> while
[[ xt compile, ]]
repeat
[[ it it.nitem @ 0 ?do postpone drop loop ]]
[[ it dup it.drop @ execute ]]
[[
; immediate

: init-it ( nargs nstate nitem init next drop next-back a-addr -- it )
>r
r@ it.next-back !
r@ it.drop !
r@ it.next !
r@ it.init !
r@ it.nitem !
r@ it.nstate !
r@ it.nargs !
r>
;

: make-it ( nargs nstate nitem init next drop next-back -- it )
/iter-type allocate throw init-it
;

: %range-next ( lo hi -- lo' hi lo flag )
2dup = if 0 false else over >r swap 1+ swap r> true then
;

: %range-next-back ( lo hi -- lo hi' hi' flag )
2dup = if 0 false else 1- dup true then
;

: range-next ( it -- ) drop postpone %range-next ;
: range-next-back ( it -- ) drop postpone %range-next-back ;
: range-drop ( it -- ) drop postpone 2drop ;

: todo ( -- ) true abort" not yet implemented" ;
: identity ( -- ) ;

: [range-iterator] ( -- it )
2
2
1
['] drop
['] range-next
['] range-drop
['] range-next-back
make-it
; immediate

/iter-type
1 cells +field filter.it
1 cells +field filter.xt
constant /filter

: filter-init ( it -- ) filter.it @ dup it.init @ execute ;

: %then ( orig -- ) postpone then ; immediate

: filter-next {: it -- :}
]]
begin
[[ it filter.it @ dup it.next @ execute ]]
0= if false ahead [[ 1 cs-roll ]] then
dup [[ it filter.xt @ compile, ]] if true ahead [[ 1 cs-roll ]] then
drop
[[ 2 cs-roll ]]
again %then %then
[[
;

: filter-drop ( it -- ) filter.it @ dup it.drop @ execute ;

: make-filter ( it xt -- it2 )
/filter allocate throw >r
r@ filter.xt !
r@ filter.it !
r@ filter.it @ it.nstate @
r@ filter.it @ it.nstate @
r@ filter.it @ it.nitem @
['] filter-init
['] filter-next
['] filter-drop
['] todo
r> init-it
;

: [filter] ( it xt -- it2 ) make-filter ; immediate

/iter-type
1 cells +field map.it
1 cells +field map.xt
constant /map

: map-next {: it -- :}
it map.it @ dup it.next @ execute
]]
if
[[ it map.xt @ compile, ]]
true
else
[[
it map.it @ it.nitem @ it it.nitem @ -
dup 0< if
negate 0 ?do 0 postpone literal loop
else
0 ?do postpone drop loop
then
]]
false
then
[[
;

: map-drop ( it -- ) map.it @ dup it.drop @ execute ;
: map-init ( it -- ) map.it @ dup it.init @ execute ;

: make-map ( it u xt -- it2 )
/map allocate throw >r
r@ map.xt !
r@ it.nitem !
r@ map.it !
r@ map.it @ it.nstate @
dup
r@ it.nitem @
['] map-init
['] map-next
['] map-drop
['] todo
r> init-it
;

: [map] ( it xt -- it2 ) make-map ; immediate

/iter-type
1 cells +field reverse.it
constant /reverse

: reverse-init ( it -- ) reverse.it @ dup it.init @ execute ;
: reverse-next ( it -- ) reverse.it @ dup it.next-back @ execute ;
: reverse-drop ( it -- ) reverse.it @ dup it.drop @ execute ;
: reverse-next-back ( it -- ) reverse.it @ dup it.next @ execute ;

: make-reverse ( it -- it2 )
/reverse allocate throw >r
r@ reverse.it !
0
r@ reverse.it @ it.nstate @
r@ reverse.it @ it.nitem @
['] reverse-init
['] reverse-next
['] reverse-drop
['] reverse-next-back
r> init-it
;

: [reverse] ( it -- it2 ) make-reverse ; immediate

/iter-type
1 cells +field zip.it1
1 cells +field zip.it2
constant /zip

: zip-init ( it -- )
dup zip.it1 @ dup it.init @ execute
zip.it2 @ dup it.init @ execute
;

\ Generate code to rotate SIZE items at depth DEPTH to the top of the stack,
\ i.e. the stack effect should be: ( size×x depth×x -- depth×x size×x )
\ \ 1 1 NROLL corresponds to SWAP,
\ 2 2 NROLL to 2SWAP and
\ 1 2 NROLL to ROT.
: nroll ( size depth -- )
{: s d :}
\ s d 1 1 d= if postpone swap exit then
\ s d 2 2 d= if postpone 2swap exit then
\ s d + 1- 2 = if s 0 ?do postpone rot loop exit then
\ d 0= if exit then
s 0 ?do
s d + 1- postpone literal postpone roll
loop
;

: zip-next ( it -- )
dup zip.it1 @ swap zip.it2 @ {: it1 it2 :}
it1 it.nstate @ it2 it.nstate @ nroll
it1 dup it.next @ execute
]] if
[[
it2 it.nstate @ it1 it.nstate @ it1 it.nitem @ + nroll
it2 dup it.next @ execute
it2 it.nstate @ it2 it.nitem @ 1+ nroll
it1 it.nitem @ it2 it.nitem @ 1 + + it2 it.nstate @ nroll
]]
else
[[
it2 it.nstate @ it1 it.nitem @ nroll
it1 it.nstate @ it1 it.nitem @ + it2 it.nstate @ nroll
it2 it.nitem @ 0 ?do 0 postpone literal loop
]]
false
then
[[
;

: zip-drop ( it -- )
dup zip.it2 @ dup it.drop @ execute
zip.it1 @ dup it.drop @ execute
;

: make-zip ( it1 it2 -- it3 )
/zip allocate throw >r
r@ zip.it2 !
r@ zip.it1 !
r@ zip.it1 @ it.nstate @ r@ zip.it2 @ it.nstate @ +
dup
r@ zip.it1 @ it.nitem @ r@ zip.it2 @ it.nitem @ +
['] zip-init
['] zip-next
['] zip-drop
['] todo
r> init-it
;

: [zip] ( it1 it2 -- it3 ) make-zip ; immediate

/iter-type
1 cells +field enumerate.it
constant /enumerate

: enumerate-init ( it -- )
enumerate.it @ dup it.init @ execute
0 postpone literal
;

: enumerate-next ( it -- )
enumerate.it @ {: it :}
it it.nstate @ 1 nroll
it dup it.next @ execute
1 it it.nstate @ it it.nitem @ 1+ + nroll
]] tuck 1+ [[
it it.nitem @ 2 + 1 nroll
;


Click here to read the complete article
Re: FOR-EACH ... DO[ ... ]NEXT

<uj2rs1$1qftu$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25370&group=comp.lang.forth#25370

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!newsfeed.endofthelinebbs.com!news.hispagatos.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Wed, 15 Nov 2023 16:33:06 +0000
Organization: A noiseless patient Spider
Lines: 74
Message-ID: <uj2rs1$1qftu$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 15 Nov 2023 16:33:05 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="6ced11c0176a4b257296de8dc824dd38";
logging-data="1916862"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/qkgKUHEs6qrDsJ/2kYJDcIlL6oSnUIfs="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:xf+stTQpmY0EWFYEwdv426ObRe0=
Content-Language: en-GB
In-Reply-To: <2023Nov14.183012@mips.complang.tuwien.ac.at>
 by: Gerry Jackson - Wed, 15 Nov 2023 16:33 UTC

On 14/11/2023 17:30, Anton Ertl wrote:
> Gerry Jackson <do-not-use@swldwa.uk> writes:
>> Complex loops with multiple WHILEs can be difficult to understand
>> particularly when returning to a program written some time ago.
>
> Of course this makes me think of the extended case construct (present
> in development Gforth).
>
> Your variant is interesting, but it's not clear enough to me what it
> can do. So let's see:
>
>> Using a simple/silly example display integers divisible by 6 that
>> Michael Gassanenko used to demonstrate his similar ... START ... EMERGE
>> ... construct, we have:
>>
>> : n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f2 true when n1<n2
>> drop 1+ 2dup >=
>> ;
>>
>> p: /2? ( n -- n f ) dup 2 mod ;p
>> p: /3? ( n -- n f ) dup 3 mod ;p
>> : .n ( n -- n ) dup . -1 ;
>>
>> : /6? ( n1 n2 -- )
>> 0 for-each n+1 do[ /2? /3? .n ]next 2drop
>> ;
>>
>> cr 50 0 /6? .s
>> \ displays 6 12 18 24 30 36 42 48
>
> Let's see how this turns out with the extended CASE:
>
> : /6? ( limit start -- )
> case ( limit n )
> 1+ 2dup < ?of 2drop endof
> dup 2 mod ?of contof
> dup 3 mod ?of contof
> dup .
> next-case ;
>
> cr 50 0 /6?
>
> This produces the expected output, and you can see how the parts of
> the definition relate to the code in your variant.

Your extended case is very versatile so I'm not surprised it can do the
same function. However you are missing the point of what I'm trying to
achieve. This is to have a versatile looping structure that is more
readable, one that hides the nuts and bolts of the code that implements
the loop. A solution that expresses what has to be done, not one that
dictates how it will be done i.e. a more readable solution. I think your
solution doesn't meet that readability criterion, not that such a simple
example is difficult to understand.

>
> Maybe there is an example where FOR-EACH ... DO[ ... ]NEXT is harder
> to replace.

Probably not. If you want a challenge an interesting question is whether
it is simpler than my attempt to implement the FOR-EACH construct, or
similar, using your extended CASE.

>
> Given the number of cases where I have written nothing between the ?OF
> and the following ENDOF or CONTOF, maybe a ?ENDOF or ?CONTOF
> (equivalent to 0= ?OF ENDOF or 0= ?OF CONTOF) may be useful.
>

Couldn't ?OF parse the next word to see if it is ?ENDOF or ?CONTOF and
generate the appropriate code if so?

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<0d13f948-3b92-46d2-a7d9-7f8a77ccefb5n@googlegroups.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25372&group=comp.lang.forth#25372

  copy link   Newsgroups: comp.lang.forth
X-Received: by 2002:a05:620a:8d8:b0:778:91c2:2885 with SMTP id z24-20020a05620a08d800b0077891c22885mr138206qkz.14.1700068569101;
Wed, 15 Nov 2023 09:16:09 -0800 (PST)
X-Received: by 2002:ad4:5be8:0:b0:66a:ca66:85fb with SMTP id
k8-20020ad45be8000000b0066aca6685fbmr132027qvc.13.1700068568835; Wed, 15 Nov
2023 09:16:08 -0800 (PST)
Path: i2pn2.org!rocksolid2!news.neodome.net!weretis.net!feeder6.news.weretis.net!border-2.nntp.ord.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.forth
Date: Wed, 15 Nov 2023 09:16:08 -0800 (PST)
In-Reply-To: <m2cywbnw26.fsf@gmail.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2a00:23c7:906:9601:811a:4fe4:14a1:b506;
posting-account=dZP_5goAAAC_BO-SX5ENBfo71Ro3Vnig
NNTP-Posting-Host: 2a00:23c7:906:9601:811a:4fe4:14a1:b506
References: <uilq87$2tvlh$1@dont-email.me> <m2cywbnw26.fsf@gmail.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <0d13f948-3b92-46d2-a7d9-7f8a77ccefb5n@googlegroups.com>
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
From: gwj.nexus@gmail.com (Gerry Jackson)
Injection-Date: Wed, 15 Nov 2023 17:16:09 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 52
 by: Gerry Jackson - Wed, 15 Nov 2023 17:16 UTC

On Wednesday, November 15, 2023 at 10:35:37 AM UTC, Helmut Eller wrote:
> On Fri, Nov 10 2023, Gerry Jackson wrote:
>
> > Also I wanted the ability to carry out a pipeline of operations on a
> > collection of data objects (array, linked list etc).

> I wanted to have something like Rust's iterator library and played
> around with the code below. With this, the divisible-by-6 example could
> be written as:
>
> : /2? ( n -- flag ) 2 mod 0= ;
> : /3? ( n -- flag ) 3 mod 0= ;
>
> : /6? ( start end -- )
> [range-iterator]
> [ ' /2? ] [filter]
> [ ' /3? ] [filter]
> [ ' . ] [for-each]
> ;
>
> This is arguably very close to the Rust expression:
>
> (start..end)
> .filter(|u| u % 2 == 0)
> .filter(|u| u % 3 == 0)
> .for_each(|u| print!("{u} "));
>
> Unfortunately, my code is much more complicated that yours. On the plus
> side, I'm trying to mimic Rust's operators and naming, which saves me
> from re-inventing wheels and perhaps helps to communicate the intention
> behind the operators.
>
> Helmut
>
>

Wow, you've done a lot more work on this than I have.
It's an excellent idea to mimic another language you're familiar with,
I've never looked at Rust.

Thank you for posting all your code, I shall have a more detailed
look at it. It's nice to know that someone else is attempting to
do (or has done) something similar to what I am attempting.

Gerry

\ iter.fth --- Rust inspired iterators
[ Code for the above snipped]

Re: FOR-EACH ... DO[ ... ]NEXT

<uj2uog$1qftu$2@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25373&group=comp.lang.forth#25373

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Wed, 15 Nov 2023 17:22:25 +0000
Organization: A noiseless patient Spider
Lines: 11
Message-ID: <uj2uog$1qftu$2@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at> <uj2rs1$1qftu$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 15 Nov 2023 17:22:24 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="6ced11c0176a4b257296de8dc824dd38";
logging-data="1916862"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Q6hd3EhzkvaIbJcirzkOdoiMzhbMBuow="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:IkzHjfQCjVqZpGlOm9K+n4x9cao=
In-Reply-To: <uj2rs1$1qftu$1@dont-email.me>
Content-Language: en-GB
 by: Gerry Jackson - Wed, 15 Nov 2023 17:22 UTC

On 15/11/2023 16:33, Gerry Jackson wrote:
>
> Couldn't ?OF parse the next word to see if it is ?ENDOF or ?CONTOF and
> generate the appropriate code if so?
>

Sorry I meant ENDOF or CONTOF

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<2023Nov15.185706@mips.complang.tuwien.ac.at>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25375&group=comp.lang.forth#25375

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: anton@mips.complang.tuwien.ac.at (Anton Ertl)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Wed, 15 Nov 2023 17:57:06 GMT
Organization: Institut fuer Computersprachen, Technische Universitaet Wien
Lines: 80
Message-ID: <2023Nov15.185706@mips.complang.tuwien.ac.at>
References: <uilq87$2tvlh$1@dont-email.me> <2023Nov14.183012@mips.complang.tuwien.ac.at> <uj2rs1$1qftu$1@dont-email.me>
Injection-Info: dont-email.me; posting-host="8fb31677718b54c291a8a54dcef69b93";
logging-data="1957920"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+K6bRdbPcw4/URS54pyzb9"
Cancel-Lock: sha1:H2he4QjYhz5sv2cXnVw96/gkoKA=
X-newsreader: xrn 10.11
 by: Anton Ertl - Wed, 15 Nov 2023 17:57 UTC

Gerry Jackson <do-not-use@swldwa.uk> writes:
>On 14/11/2023 17:30, Anton Ertl wrote:
>> Gerry Jackson <do-not-use@swldwa.uk> writes:
>>> : n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f2 true when n1<n2
>>> drop 1+ 2dup >=
>>> ;
>>>
>>> p: /2? ( n -- n f ) dup 2 mod ;p
>>> p: /3? ( n -- n f ) dup 3 mod ;p
>>> : .n ( n -- n ) dup . -1 ;
>>>
>>> : /6? ( n1 n2 -- )
>>> 0 for-each n+1 do[ /2? /3? .n ]next 2drop
>>> ;
>>>
>>> cr 50 0 /6? .s
>>> \ displays 6 12 18 24 30 36 42 48
>>
>> Let's see how this turns out with the extended CASE:
>>
>> : /6? ( limit start -- )
>> case ( limit n )
>> 1+ 2dup < ?of 2drop endof
>> dup 2 mod ?of contof
>> dup 3 mod ?of contof
>> dup .
>> next-case ;
>>
>> cr 50 0 /6?
>>
>> This produces the expected output, and you can see how the parts of
>> the definition relate to the code in your variant.
>
>Your extended case is very versatile so I'm not surprised it can do the
>same function. However you are missing the point of what I'm trying to
>achieve. This is to have a versatile looping structure that is more
>readable, one that hides the nuts and bolts of the code that implements
>the loop.

The reader needs to be familiar with FOR-EACH ... DO[ ... ]NEXT and

P: ... ;P to make this more readable. The question is if this will be
used frequently enough to make readers familiar with these words.
People have already argued against the extended CASE because of
unfamiliarity.

OTOH, if there are enough uses of the extended CASE for the
filter-loop pattern, one might also find it readable (and recognize
that it is a filter loop) when expressed using the extended CASE.

>> Given the number of cases where I have written nothing between the ?OF
>> and the following ENDOF or CONTOF, maybe a ?ENDOF or ?CONTOF
>> (equivalent to 0= ?OF ENDOF or 0= ?OF CONTOF) may be useful.
>>
>
>Couldn't ?OF parse the next word to see if it is ?ENDOF or ?CONTOF and
>generate the appropriate code if so?

The idea behind ?ENDOF and ?CONTOF is to increase readability by
making the code shorter, not optimization. So it might be:

: /6? ( limit start -- )
case
1+ 2dup < ?endof
dup 2 mod ?contof dup 3 mod ?contof dup . next-case
2drop ;

As for optimizing ?OF CONTOF, I would not do it with a parsing word,
because of bad experiences with parsing words. I would probably do it
by optimizing a conditional branch (?OF) that just jumps over an
unconditional branch (ENDOF): just invert the sense of the conditional
branch and let it's target be that of the unconditional branch; leave
the unconditional branch away.

- 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: https://euro.theforth.net/2023

Re: FOR-EACH ... DO[ ... ]NEXT

<nnd$1b8c788d$5cea4239@4be348d05abbab1c>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25377&group=comp.lang.forth#25377

  copy link   Newsgroups: comp.lang.forth
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
References: <uilq87$2tvlh$1@dont-email.me> <2023Nov14.183012@mips.complang.tuwien.ac.at> <uj2rs1$1qftu$1@dont-email.me> <2023Nov15.185706@mips.complang.tuwien.ac.at>
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$1b8c788d$5cea4239@4be348d05abbab1c>
Organization: KPN B.V.
Date: Thu, 16 Nov 2023 10:19:10 +0100
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!feed.abavia.com!abe005.abavia.com!abp001.abavia.com!news.kpn.nl!not-for-mail
Lines: 39
Injection-Date: Thu, 16 Nov 2023 10:19:10 +0100
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
 by: none - Thu, 16 Nov 2023 09:19 UTC

In article <2023Nov15.185706@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:

>The idea behind ?ENDOF and ?CONTOF is to increase readability by
>making the code shorter, not optimization. So it might be:
>
>: /6? ( limit start -- )
> case
> 1+ 2dup < ?endof
> dup 2 mod ?contof dup 3 mod ?contof dup . next-case
> 2drop ;
>
>As for optimizing ?OF CONTOF, I would not do it with a parsing word,
>because of bad experiences with parsing words. I would probably do it
>by optimizing a conditional branch (?OF) that just jumps over an
>unconditional branch (ENDOF): just invert the sense of the conditional
>branch and let it's target be that of the unconditional branch; leave
>the unconditional branch away.

You introduced CONDS .. THENS .
I have used this often. There is an advantage over CASE that it
is just a familiar nested THEN .
A mistake in a control structure is more cumbersome
than a stack error that is easily spotted by an interpretitive test.

Since that time I never used CASE, that I find hard to use.
If parsing words are added, that makes it worse.
CASE doesn't save on words.

>
>- anton

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat spinning. - the Wise from Antrim -

Re: FOR-EACH ... DO[ ... ]NEXT

<015d4503-aefb-4d54-b9f3-e2c7fe3f0b0cn@googlegroups.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25378&group=comp.lang.forth#25378

  copy link   Newsgroups: comp.lang.forth
X-Received: by 2002:a05:6214:5290:b0:670:d710:739a with SMTP id kj16-20020a056214529000b00670d710739amr294075qvb.3.1700159390661;
Thu, 16 Nov 2023 10:29:50 -0800 (PST)
X-Received: by 2002:ad4:5247:0:b0:66c:fef0:ce80 with SMTP id
s7-20020ad45247000000b0066cfef0ce80mr224175qvq.4.1700159390411; Thu, 16 Nov
2023 10:29:50 -0800 (PST)
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!1.us.feeder.erje.net!feeder.erje.net!border-1.nntp.ord.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.forth
Date: Thu, 16 Nov 2023 10:29:49 -0800 (PST)
In-Reply-To: <uj21sp$1m789$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=77.174.47.232; posting-account=Ebqe4AoAAABfjCRL4ZqOHWv4jv5ZU4Cs
NNTP-Posting-Host: 77.174.47.232
References: <uilq87$2tvlh$1@dont-email.me> <70cba185-4986-4af8-9ede-457c6e524ae1n@googlegroups.com>
<5aff1672-b414-4063-b016-02582e00f06en@googlegroups.com> <uj21sp$1m789$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <015d4503-aefb-4d54-b9f3-e2c7fe3f0b0cn@googlegroups.com>
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
From: the.beez.speaks@gmail.com (Hans Bezemer)
Injection-Date: Thu, 16 Nov 2023 18:29:50 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 12
 by: Hans Bezemer - Thu, 16 Nov 2023 18:29 UTC

On Wednesday, November 15, 2023 at 10:09:48 AM UTC+1, Gerry Jackson wrote:
> Its easy to write solutions like this for individual cases, its also
> easy to make mistakes. Shouldn't the loops be ended with:
> 1 cells +loop
True. But this code was before 4tH could optimize 1 CELLS +LOOP away. Since
in 4tH cells have their own segment (and hence the number of "units" per cell is
always 1) I got myself a bit of performance by writing it that way.

TL;DR - You're completely right in an ANS Forth way.

Hans Bezemer

Re: FOR-EACH ... DO[ ... ]NEXT

<ujdjoi$3tiit$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25381&group=comp.lang.forth#25381

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: do-not-use@swldwa.uk (Gerry Jackson)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Sun, 19 Nov 2023 18:22:09 +0000
Organization: A noiseless patient Spider
Lines: 114
Message-ID: <ujdjoi$3tiit$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at> <uj2rs1$1qftu$1@dont-email.me>
<2023Nov15.185706@mips.complang.tuwien.ac.at>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sun, 19 Nov 2023 18:22:10 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="5169b1cdc52a204750c3097a66a2f722";
logging-data="4115037"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/xp3y6mCidu/KXgSxolhkSBBwqOZL8Xak="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:DOV29T6bmJv/zSmUdpaYmQ7WN0s=
In-Reply-To: <2023Nov15.185706@mips.complang.tuwien.ac.at>
Content-Language: en-GB
 by: Gerry Jackson - Sun, 19 Nov 2023 18:22 UTC

On 15/11/2023 17:57, Anton Ertl wrote:
> Gerry Jackson <do-not-use@swldwa.uk> writes:
>> On 14/11/2023 17:30, Anton Ertl wrote:
>>> Gerry Jackson <do-not-use@swldwa.uk> writes:
>>>> : n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f2 true when n1<n2
>>>> drop 1+ 2dup >=
>>>> ;
>>>>
>>>> p: /2? ( n -- n f ) dup 2 mod ;p
>>>> p: /3? ( n -- n f ) dup 3 mod ;p
>>>> : .n ( n -- n ) dup . -1 ;
>>>>
>>>> : /6? ( n1 n2 -- )
>>>> 0 for-each n+1 do[ /2? /3? .n ]next 2drop
>>>> ;
>>>>
>>>> cr 50 0 /6? .s
>>>> \ displays 6 12 18 24 30 36 42 48
>>>
>>> Let's see how this turns out with the extended CASE:
>>>
>>> : /6? ( limit start -- )
>>> case ( limit n )
>>> 1+ 2dup < ?of 2drop endof
>>> dup 2 mod ?of contof
>>> dup 3 mod ?of contof
>>> dup .
>>> next-case ;
>>>
>>> cr 50 0 /6?
>>>
>>> This produces the expected output, and you can see how the parts of
>>> the definition relate to the code in your variant.
>>
>> Your extended case is very versatile so I'm not surprised it can do the
>> same function. However you are missing the point of what I'm trying to
>> achieve. This is to have a versatile looping structure that is more
>> readable, one that hides the nuts and bolts of the code that implements
>> the loop.
>
> The reader needs to be familiar with FOR-EACH ... DO[ ... ]NEXT and
>
> P: ... ;P to make this more readable. The question is if this will be
> used frequently enough to make readers familiar with these words.
> People have already argued against the extended CASE because of
> unfamiliarity.
>
> OTOH, if there are enough uses of the extended CASE for the
> filter-loop pattern, one might also find it readable (and recognize
> that it is a filter loop) when expressed using the extended CASE.
>

I think using familiarity is a weak argument. People can become familiar
with virtually anything if they use it often enough.

I think the extended case is very versatile but ISTM that it has a noisy
syntax and from one point of view is inconsistent. For example if we
take the original CASE statement, in its basic use:
(n1 n2) OF ... ENDOF i.e. n1=n2 can be regarded as success.

In the extended CASE, it can be more like a pipeline where:
( f ) ?OF ... ENDOF leaves the pipeline, there f=TRUE can be regarded as
failure. OTOH the same thing in other uses it could be regarded as success.

Anyway having said that we can probably ignore that as its flexibility
is extremely useful. But I would like to use it in a more readable form
such as the aforementioned FOR-EACH etc.

I've been experimenting with it to implement the FOR-EACH construct and
it is very easy. I started with GForth's ANS compatibilty version and
found that it isn't compatible with my system because my system uses a
separate control stack which is permitted in ANS Forth. The GForth
compatible version uses DEPTH as a way of providing the correct number
of POSTPONE THENs to resolve the ENDOFs. Hence the failure on my system
as DEPTH is unlikely to change. Then I vaguely remembered that I had
posted some similar code years ago on c.l.f and managed to track it down at:
https://groups.google.com/g/comp.lang.forth/c/64GKthsYVFs/m/1QTLZCyiHCUJ

Using that the implemention is straightforward.

: for-each ( RT: -- ) postpone case ; immediate
: do[ ( RT: f -- ) postpone ?break ; immediate
: ]next ( RT: x -- ) postpone dup postpone next-case ; immediate
: ?next ( RT: f -- ) postpone ?of postpone contof ; immediate

?BREAK is defined in the post at the above link and is equivalent to:
?OF ENDOF

if we want to us a similar syntax to Helmut Eller's excellent post, we
could define:

synonym filter ?next

The example used previously is then:

: n+1 ( n1 n2 -- n1 n2+1 f ) \ f true when n1<n2
1+ 2dup <
;

: /2? ( n -- n f ) dup 2 mod ;
: /3? ( n -- n f ) dup 3 mod ;
: .n ( n -- n ) dup . ;

: /6? ( n1 n2 -- )
for-each n+1 do[ /2? ?next /3? ?next .n ]next 2drop
;

50 0 /6? .s

Incidentally I gave up having P: ... ;P as a bad idea.

--
Gerry

Re: FOR-EACH ... DO[ ... ]NEXT

<m27cmcjtqj.fsf@gmail.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25382&group=comp.lang.forth#25382

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!news.swapon.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: eller.helmut@gmail.com (Helmut Eller)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Mon, 20 Nov 2023 17:05:08 +0100
Organization: A noiseless patient Spider
Lines: 58
Message-ID: <m27cmcjtqj.fsf@gmail.com>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at>
<uj2rs1$1qftu$1@dont-email.me>
<2023Nov15.185706@mips.complang.tuwien.ac.at>
<ujdjoi$3tiit$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="80e81bd862c85e481a5bd37406f24d3e";
logging-data="408161"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19D7cDVr0EYWNvFJzxew01n"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:AshnMmMz6nKN/YLLSparSgRim3E=
sha1:YVykcSXSJepaOGZedh6QQwJAk1M=
 by: Helmut Eller - Mon, 20 Nov 2023 16:05 UTC

On Sun, Nov 19 2023, Gerry Jackson wrote:
> Using that the implemention is straightforward.
>
> : for-each ( RT: -- ) postpone case ; immediate
> : do[ ( RT: f -- ) postpone ?break ; immediate
> : ]next ( RT: x -- ) postpone dup postpone next-case ; immediate

I think the DUP is too much as NEXT-CASE, unlike ENDCASE, doesn't drop.
Either way, the stack comment doesn't seem to match the code.

> : ?next ( RT: f -- ) postpone ?of postpone contof ; immediate
>
> ?BREAK is defined in the post at the above link and is equivalent to:
> ?OF ENDOF

I.e.:

: ?break ( RT: f -- ) postpone ?of postpone endof ; immediate

> if we want to us a similar syntax to Helmut Eller's excellent post, we
> could define:
>
> synonym filter ?next

It would probably be inverted:

: filter ( RT: f -- ) postpone 0= postpone ?next ; immediate

> The example used previously is then:
>
> : n+1 ( n1 n2 -- n1 n2+1 f ) \ f true when n1<n2
> 1+ 2dup <
> ;
>
> : /2? ( n -- n f ) dup 2 mod ;
> : /3? ( n -- n f ) dup 3 mod ;
> : .n ( n -- n ) dup . ;
>
> : /6? ( n1 n2 -- )
> for-each n+1 do[ /2? ?next /3? ?next .n ]next 2drop
> ;
>
> 50 0 /6? .s

Mathematically speaking, zero is divisible by 6. So I think 0 should be
printed too. This could probably done with a different definition for
n+1. Also the naming is a bit curious: isn't /2? supposed to read as
"is divisible by 2"? But the implementation returns the inverse: true if
it is not divisible.

> Incidentally I gave up having P: ... ;P as a bad idea.

It think there was something useful to the idea that a helper can return
three values: -1, 0, +1. In particular it could be useful to separate
the "break because we're finished" case from the "break because we've
encountered an error" situation.

Helmut

Re: FOR-EACH ... DO[ ... ]NEXT

<ujgs2m$h5im$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25385&group=comp.lang.forth#25385

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!usenet.goja.nl.eu.org!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ruvim.pinka@gmail.com (Ruvim)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 21 Nov 2023 04:02:29 +0400
Organization: A noiseless patient Spider
Lines: 77
Message-ID: <ujgs2m$h5im$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 21 Nov 2023 00:02:30 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="2cdd38e76a12ee9089dad23833f7639a";
logging-data="562774"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19gsPlwiMa7ByzzjEvWtklE"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:3M1sWy7I9JgAHAZaDFUU+gZl5b0=
Content-Language: en-US
In-Reply-To: <2023Nov14.183012@mips.complang.tuwien.ac.at>
 by: Ruvim - Tue, 21 Nov 2023 00:02 UTC

On 2023-11-14 21:30, Anton Ertl wrote:
> Gerry Jackson <do-not-use@swldwa.uk> writes:
>> Complex loops with multiple WHILEs can be difficult to understand
>> particularly when returning to a program written some time ago.
>
> Of course this makes me think of the extended case construct (present
> in development Gforth).
>
> Your variant is interesting, but it's not clear enough to me what it
> can do. So let's see:
>
>> Using a simple/silly example display integers divisible by 6 that
>> Michael Gassanenko used to demonstrate his similar ... START ... EMERGE
>> ... construct, we have:
>>
>> : n+1 ( n1 n2 f1 -- n1 n2+1 f2 ) \ f2 true when n1<n2
>> drop 1+ 2dup >=
>> ;
>>
>> p: /2? ( n -- n f ) dup 2 mod ;p
>> p: /3? ( n -- n f ) dup 3 mod ;p
>> : .n ( n -- n ) dup . -1 ;
>>
>> : /6? ( n1 n2 -- )
>> 0 for-each n+1 do[ /2? /3? .n ]next 2drop
>> ;
>>
>> cr 50 0 /6? .s
>> \ displays 6 12 18 24 30 36 42 48
>
> Let's see how this turns out with the extended CASE:
>
> : /6? ( limit start -- )
> case ( limit n )
> 1+ 2dup < ?of 2drop endof
> dup 2 mod ?of contof
> dup 3 mod ?of contof
> dup .
> next-case ;
>
> cr 50 0 /6?

I just realized that this "case" is actually a loop, and it's similar to
my fancy curly control flow structures [1], which misses an instruction
to premature continue execution from the beginning of the loop.

So I added now this instruction, and the word "/6?" can be defined as
follows:

: /6? ( limit start -- )
repeat{ ( limit n )
1+ 2dup < if-break{ 2drop }
dup 2 mod if-cont{}
dup 3 mod if-cont{}
dup .
}repeat
;

NB: any ending instruction can be written in a long or short "}" form.
So "if-cont{}" can be written as "if-cont{ ... }"
and "if-cont{ ... }if-cont", with a non-empty body, which is executed
before continue from the beginning of the loop.

[1]
https://github.com/ruv/forth-on-forth/blob/master/lib/control-flow-curly.fth
https://github.com/ruv/forth-on-forth/blob/master/lib/control-flow-curly.test.fth

--
Ruvim

Re: FOR-EACH ... DO[ ... ]NEXT

<ujh0nt$h15p$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25386&group=comp.lang.forth#25386

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: dxforth@gmail.com (dxf)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 21 Nov 2023 12:22:06 +1100
Organization: A noiseless patient Spider
Lines: 28
Message-ID: <ujh0nt$h15p$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at> <ujgs2m$h5im$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 21 Nov 2023 01:22:05 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="c1910fb9e0617203d938983d3fe21eb8";
logging-data="558265"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19LWho1S+2mmJQIbxlXPUKV"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:97j51tGJekExGxUD0sDAckNLtqM=
In-Reply-To: <ujgs2m$h5im$1@dont-email.me>
Content-Language: en-GB
 by: dxf - Tue, 21 Nov 2023 01:22 UTC

On 21/11/2023 11:02 am, Ruvim wrote:
>
> ... the word "/6?" can be defined as follows:
>
>   : /6? ( limit start -- )
>     repeat{ ( limit n )
>       1+ 2dup < if-break{ 2drop }
>       dup 2 mod if-cont{}
>       dup 3 mod if-cont{}
>       dup .
>     }repeat
>   ;

: ?six ( n -- n )
dup 2 mod if exit then
dup 3 mod if exit then
dup .
;

: /6? ( limit start -- )
begin
1+ 2dup < 0=
while
?six
repeat 2drop
;

Re: FOR-EACH ... DO[ ... ]NEXT

<ujhoe7$ogal$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25387&group=comp.lang.forth#25387

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ruvim.pinka@gmail.com (Ruvim)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 21 Nov 2023 12:06:29 +0400
Organization: A noiseless patient Spider
Lines: 39
Message-ID: <ujhoe7$ogal$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at> <ujgs2m$h5im$1@dont-email.me>
<ujh0nt$h15p$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 21 Nov 2023 08:06:31 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="2cdd38e76a12ee9089dad23833f7639a";
logging-data="803157"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/snv11ams+k7fwl1yuIWSN"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:Jkprw9EjpBWX76Y/BmfgiWe3OOk=
In-Reply-To: <ujh0nt$h15p$1@dont-email.me>
Content-Language: en-US
 by: Ruvim - Tue, 21 Nov 2023 08:06 UTC

On 2023-11-21 05:22, dxf wrote:
> On 21/11/2023 11:02 am, Ruvim wrote:
>>
>> ... the word "/6?" can be defined as follows:
>>
>>   : /6? ( limit start -- )
>>     repeat{ ( limit n )
>>       1+ 2dup < if-break{ 2drop }
>>       dup 2 mod if-cont{}
>>       dup 3 mod if-cont{}
>>       dup .
>>     }repeat
>>   ;
>
> : ?six ( n -- n )
> dup 2 mod if exit then
> dup 3 mod if exit then
> dup .
> ;
>
> : /6? ( limit start -- )
> begin
> 1+ 2dup < 0=
> while
> ?six
> repeat 2drop
> ;
>
>

Your variant is longer by 3 lines out of 8, which is 3/8 = 38%

Another rationale is the same as for quotations: sometime you don't want
to introduce a new word that is used only once.

--
Ruvim

Re: FOR-EACH ... DO[ ... ]NEXT

<ujhrtj$opea$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25391&group=comp.lang.forth#25391

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: dxforth@gmail.com (dxf)
Newsgroups: comp.lang.forth
Subject: Re: FOR-EACH ... DO[ ... ]NEXT
Date: Tue, 21 Nov 2023 20:05:56 +1100
Organization: A noiseless patient Spider
Lines: 37
Message-ID: <ujhrtj$opea$1@dont-email.me>
References: <uilq87$2tvlh$1@dont-email.me>
<2023Nov14.183012@mips.complang.tuwien.ac.at> <ujgs2m$h5im$1@dont-email.me>
<ujh0nt$h15p$1@dont-email.me> <ujhoe7$ogal$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 21 Nov 2023 09:05:55 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="c1910fb9e0617203d938983d3fe21eb8";
logging-data="812490"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/C8LRuetwgjo0dhi6WxdWs"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:Dykos2JdmAVGcIUt8rX73QfPsjA=
Content-Language: en-GB
In-Reply-To: <ujhoe7$ogal$1@dont-email.me>
 by: dxf - Tue, 21 Nov 2023 09:05 UTC

On 21/11/2023 7:06 pm, Ruvim wrote:
> On 2023-11-21 05:22, dxf wrote:
>> On 21/11/2023 11:02 am, Ruvim wrote:
>>>
>>> ... the word "/6?" can be defined as follows:
>>>
>>>    : /6? ( limit start -- )
>>>      repeat{ ( limit n )
>>>        1+ 2dup < if-break{ 2drop }
>>>        dup 2 mod if-cont{}
>>>        dup 3 mod if-cont{}
>>>        dup .
>>>      }repeat
>>>    ;
>>
>> : ?six ( n -- n )
>>    dup 2 mod if exit then
>>    dup 3 mod if exit then
>>    dup .
>> ;
>>
>> : /6? ( limit start -- )
>>    begin
>>      1+ 2dup < 0=
>>    while
>>      ?six
>>    repeat 2drop
>> ;
>>
>>
>
> Your variant is longer by 3 lines out of 8, which is 3/8 = 38%
>
> Another rationale is the same as for quotations: sometime you don't want to introduce a new word that is used only once.

Named forth subroutines were not intended as a punishment.

Pages:123
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor