Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #45176 > unrolled thread
| Started by | humptydumpty <ouatubi@gmail.com> |
|---|---|
| First post | 2016-01-28 23:19 -0800 |
| Last post | 2016-01-31 08:31 -0800 |
| Articles | 20 on this page of 33 — 9 participants |
Back to article view | Back to comp.lang.forth
: YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-01-28 23:19 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-01-29 09:49 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-02-02 10:00 +0000
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-02 02:32 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; hughaguilar96@gmail.com - 2016-01-29 20:42 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-01-29 23:27 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-01-29 23:30 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; hughaguilar96@gmail.com - 2016-01-30 11:32 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-01-31 10:02 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Julian Fondren <julian.fondren@gmail.com> - 2016-02-01 01:32 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-01 02:23 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; hughaguilar96@gmail.com - 2016-02-01 20:41 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-01 23:36 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; hughaguilar96@gmail.com - 2016-02-02 20:29 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-03 00:05 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-03 00:26 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-02-03 12:17 +0000
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-03 06:17 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-03 06:19 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; franck.bensusan@gmail.com - 2016-02-03 01:02 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; franck.bensusan@gmail.com - 2016-02-03 01:23 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-02-02 17:31 +0000
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; hughaguilar96@gmail.com - 2016-01-31 21:19 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-02-01 00:28 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; "WJ" <w_a_x_man@yahoo.com> - 2016-01-31 10:35 +0000
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Chris Curl <ccurl609@gmail.com> - 2016-01-31 07:47 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; hughaguilar96@gmail.com - 2016-01-31 20:37 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; "WJ" <w_a_x_man@yahoo.com> - 2016-01-30 09:43 +0000
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Julian Fondren <julian.fondren@gmail.com> - 2016-01-30 02:11 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; humptydumpty <ouatubi@gmail.com> - 2016-01-30 11:33 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; "WJ" <w_a_x_man@yahoo.com> - 2016-01-31 10:11 +0000
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Julian Fondren <julian.fondren@gmail.com> - 2016-01-31 08:04 -0800
Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Julian Fondren <julian.fondren@gmail.com> - 2016-01-31 08:31 -0800
Page 1 of 2 [1] 2 Next page →
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-01-28 23:19 -0800 |
| Subject | : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; |
| Message-ID | <090ad724-fdd4-4e5b-bacc-f1a6e6f32578@googlegroups.com> |
: xt latestxt postpone literal ; immediate \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ; \ Kick into action: ' wordname dup YC \ Example: : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ; 10 ' downcount dup YC drop --- *Factored* loop. Small. Beautiful. Deserves to be a primitive. Enjoying forth, humptydumpty
[toc] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-01-29 09:49 -0800 |
| Message-ID | <4943ae02-f15e-4c42-b134-3f983647027a@googlegroups.com> |
| In reply to | #45176 |
On Friday, January 29, 2016 at 9:19:28 AM UTC+2, humptydumpty wrote:
> : xt latestxt postpone literal ; immediate
>
> \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ;
> \ Kick into action: ' wordname dup YC
>
> \ Example:
> : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ;
> 10 ' downcount dup YC drop
>
> ---
> *Factored* loop. Small. Beautiful. Deserves to be a primitive.
>
> Enjoying forth,
> humptydumpty
Fun with YC :
---
: YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ;
0 VALUE States
VARIABLE St
: st++ cell St +! ;
: 0st States St ! ;
: ?++,0 IF st++ ELSE 0st THEN St @ @ dup ;
: <q> KEY [char] q = ?++,0 ;
: <w> KEY [char] w = ?++,0 ;
: <e> KEY [char] e = ?++,0 ;
: <r> KEY [char] r = ?++,0 ;
: <t> KEY [char] t = ?++,0 ;
: <y> KEY [char] y = IF 0 exit ELSE 0st THEN State @ @ dup ;
HERE ' <q> , ' <w> , ' <e> , ' <r> , ' <t> , ' <y> ,
TO States 0st
' <q> dup YC ." GATE DOORS OPENS SLOWLY. YOU'RE IN." cr .s cr bye
---
$> gforth gate.fs
GATE DOORS OPENS SLOWLY. YOU'RE IN.
<0>
Enjoying forth,
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2016-02-02 10:00 +0000 |
| Subject | Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; |
| Message-ID | <n8puhu$29n$1@dont-email.me> |
| In reply to | #45183 |
On 29/01/2016 17:49, humptydumpty wrote: > On Friday, January 29, 2016 at 9:19:28 AM UTC+2, humptydumpty wrote: >> : xt latestxt postpone literal ; immediate >> >> \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ; >> \ Kick into action: ' wordname dup YC >> >> \ Example: >> : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ; >> 10 ' downcount dup YC drop >> >> --- >> *Factored* loop. Small. Beautiful. Deserves to be a primitive. >> >> Enjoying forth, >> humptydumpty > > Fun with YC : > --- > : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; > > 0 VALUE States > VARIABLE St > : st++ cell St +! ; > : 0st States St ! ; > : ?++,0 IF st++ ELSE 0st THEN St @ @ dup ; > > : <q> KEY [char] q = ?++,0 ; > : <w> KEY [char] w = ?++,0 ; > : <e> KEY [char] e = ?++,0 ; > : <r> KEY [char] r = ?++,0 ; > : <t> KEY [char] t = ?++,0 ; > : <y> KEY [char] y = IF 0 exit ELSE 0st THEN State @ @ dup ; > > HERE ' <q> , ' <w> , ' <e> , ' <r> , ' <t> , ' <y> , > TO States 0st > > ' <q> dup YC ." GATE DOORS OPENS SLOWLY. YOU'RE IN." cr .s cr bye > --- > > $> gforth gate.fs > GATE DOORS OPENS SLOWLY. YOU'RE IN. > <0> > Continuing the fun, an alternative (use gforth) : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; 0 value start : ns ( xt ch -- xt xt ) key <> if drop start then dup ; \ ns = next-state [: [: [: [: [: [: [: 0 ;] 'y' ns ;] 't' ns ;] 'r' ns ;] 'e' ns ;] 'w' ns ;] 'q' ns ;] to start start dup YC cr .( GATE DOORS OPEN SLOWLY. YOU'RE IN.) cr .s cr -- Gerry
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-02 02:32 -0800 |
| Subject | Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; |
| Message-ID | <4beed8c8-79b7-4506-928e-30c07e9bacfa@googlegroups.com> |
| In reply to | #45243 |
On Tuesday, February 2, 2016 at 12:00:10 PM UTC+2, Gerry wrote: > On 29/01/2016 17:49, humptydumpty wrote: > > On Friday, January 29, 2016 at 9:19:28 AM UTC+2, humptydumpty wrote: > >> : xt latestxt postpone literal ; immediate > >> > >> \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ; > >> \ Kick into action: ' wordname dup YC > >> > >> \ Example: > >> : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ; > >> 10 ' downcount dup YC drop > >> > >> --- > >> *Factored* loop. Small. Beautiful. Deserves to be a primitive. > >> > >> Enjoying forth, > >> humptydumpty > > > > Fun with YC : > > --- > > : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; > > > > 0 VALUE States > > VARIABLE St > > : st++ cell St +! ; > > : 0st States St ! ; > > : ?++,0 IF st++ ELSE 0st THEN St @ @ dup ; > > > > : <q> KEY [char] q = ?++,0 ; > > : <w> KEY [char] w = ?++,0 ; > > : <e> KEY [char] e = ?++,0 ; > > : <r> KEY [char] r = ?++,0 ; > > : <t> KEY [char] t = ?++,0 ; > > : <y> KEY [char] y = IF 0 exit ELSE 0st THEN State @ @ dup ; > > > > HERE ' <q> , ' <w> , ' <e> , ' <r> , ' <t> , ' <y> , > > TO States 0st > > > > ' <q> dup YC ." GATE DOORS OPENS SLOWLY. YOU'RE IN." cr .s cr bye > > --- > > > > $> gforth gate.fs > > GATE DOORS OPENS SLOWLY. YOU'RE IN. > > <0> > > > > Continuing the fun, an alternative (use gforth) > > : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; > > 0 value start > > : ns ( xt ch -- xt xt ) key <> if drop start then dup ; \ ns = next-state > > [: [: [: [: [: [: [: 0 ;] 'y' ns ;] 't' ns ;] 'r' ns ;] 'e' ns ;] 'w' ns > ;] 'q' ns ;] to start > > start dup YC cr .( GATE DOORS OPEN SLOWLY. YOU'RE IN.) cr .s cr > > > -- > Gerry Wow! Cool telescoping! :-) Enjoying Forth, humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-01-29 20:42 -0800 |
| Message-ID | <7a996a61-993f-412d-bf17-b6744215a5a2@googlegroups.com> |
| In reply to | #45176 |
On Friday, January 29, 2016 at 12:19:28 AM UTC-7, humptydumpty wrote: > : xt latestxt postpone literal ; immediate > > \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ; > \ Kick into action: ' wordname dup YC > > \ Example: > : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ; > 10 ' downcount dup YC drop > > --- > *Factored* loop. Small. Beautiful. Deserves to be a primitive. > > Enjoying forth, > humptydumpty : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; Here is an alternative suggestion: \ toucher: i*x -- j*x continue? : YC ( xt -- ) >r begin r@ execute while repeat r> drop ; This way when your xt executes it has access to the data-stack that the parent set up (the i*x stuff) without anything (including its own xt value) being on top of this data getting in the way. Also, we get rid of the DUP in your example code --- I found that to be quite confusing. For the most part though, you are on the right track --- this is similar to the kind of code I have in my novice package --- I rely heavily on passing an xt into a HOF that does some iteration and executes the xt on every pass. :-)
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-01-29 23:27 -0800 |
| Message-ID | <2f129938-910a-4d50-8698-44530c57700b@googlegroups.com> |
| In reply to | #45190 |
On Saturday, January 30, 2016 at 6:42:19 AM UTC+2, hughag...@gmail.com wrote:
> On Friday, January 29, 2016 at 12:19:28 AM UTC-7, humptydumpty wrote:
> > : xt latestxt postpone literal ; immediate
> >
> > \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ;
> > \ Kick into action: ' wordname dup YC
> >
> > \ Example:
> > : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ;
> > 10 ' downcount dup YC drop
> >
> > ---
> > *Factored* loop. Small. Beautiful. Deserves to be a primitive.
> >
> > Enjoying forth,
> > humptydumpty
>
> : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ;
>
> Here is an alternative suggestion:
>
> \ toucher: i*x -- j*x continue?
>
> : YC ( xt -- ) >r begin r@ execute while repeat r> drop ;
>
> This way when your xt executes it has access to the data-stack that the parent set up (the i*x stuff) without anything (including its own xt value) being on top of this data getting in the way.
>
> Also, we get rid of the DUP in your example code --- I found that to be quite confusing.
>
> For the most part though, you are on the right track --- this is similar to the kind of code I have in my novice package --- I rely heavily on passing an xt into a HOF that does some iteration and executes the xt on every pass. :-)
Hi!
Both methods gives transparency to data-stack, but responsibility to preserve
'xt' differs.
In my version, responsibility belongs to the word that is fed to the 'YC', in yours belongs to 'YC'. My way does not clutter data-stack and can be used like
this:
: guarded-counted-loop ( .. xt xt |0 HiLim StartIdx -- .. )
DO
0= IF unloop EXIT THEN
execute
LOOP
;
About confusing 'DUP', is part of the game: the sequence 'dup execute'
I see as indication of y-combinators in forth. Hence the name 'YC';
is not a y-combinator (that provides recursion), is a factored-loop.
Enjoying forth,
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-01-29 23:30 -0800 |
| Message-ID | <36386fed-e2eb-4afc-b73b-58f040e1b84f@googlegroups.com> |
| In reply to | #45192 |
On Saturday, January 30, 2016 at 9:27:25 AM UTC+2, humptydumpty wrote: > On Saturday, January 30, 2016 at 6:42:19 AM UTC+2, hughag...@gmail.com wrote: > > On Friday, January 29, 2016 at 12:19:28 AM UTC-7, humptydumpty wrote: > > > : xt latestxt postpone literal ; immediate > > > > > > \ Use: : wordname .... test-sequence IF xt dup ELSE 0 THEN ; > > > \ Kick into action: ' wordname dup YC > > > > > > \ Example: > > > : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ; > > > 10 ' downcount dup YC drop > > > > > > --- > > > *Factored* loop. Small. Beautiful. Deserves to be a primitive. > > > > > > Enjoying forth, > > > humptydumpty > > > > : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; > > > > Here is an alternative suggestion: > > > > \ toucher: i*x -- j*x continue? > > > > : YC ( xt -- ) >r begin r@ execute while repeat r> drop ; > > > > This way when your xt executes it has access to the data-stack that the parent set up (the i*x stuff) without anything (including its own xt value) being on top of this data getting in the way. > > > > Also, we get rid of the DUP in your example code --- I found that to be quite confusing. > > > > For the most part though, you are on the right track --- this is similar to the kind of code I have in my novice package --- I rely heavily on passing an xt into a HOF that does some iteration and executes the xt on every pass. :-) > > > Hi! > > Both methods gives transparency to data-stack, but responsibility to preserve > 'xt' differs. > > In my version, responsibility belongs to the word that is fed to the 'YC', in yours belongs to 'YC'. My way does not clutter data-stack and can be used like > this: > > : guarded-counted-loop ( .. xt xt |0 HiLim StartIdx -- .. ) > DO > 0= IF unloop EXIT THEN > execute > LOOP > ; > > About confusing 'DUP', is part of the game: the sequence 'dup execute' > I see as indication of y-combinators in forth. Hence the name 'YC'; > is not a y-combinator (that provides recursion), is a factored-loop. > > Enjoying forth, > humptydumpty OOPS! Please, read > My way does not clutter data-stack and can be used like > this: as "My way does not clutter RETURN-stack and can be used like this:" Enjoying forth, humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-01-30 11:32 -0800 |
| Message-ID | <9f186b06-c421-431a-8c5b-84981d9bc40f@googlegroups.com> |
| In reply to | #45192 |
On Saturday, January 30, 2016 at 12:27:25 AM UTC-7, humptydumpty wrote: > On Saturday, January 30, 2016 at 6:42:19 AM UTC+2, hughag...@gmail.com wrote: > > : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; > > > > Here is an alternative suggestion: > > > > \ toucher: i*x -- j*x continue? > > > > : YC ( xt -- ) >r begin r@ execute while repeat r> drop ; > > > > This way when your xt executes it has access to the data-stack that the parent set up (the i*x stuff) without anything (including its own xt value) being on top of this data getting in the way. > > > > Also, we get rid of the DUP in your example code --- I found that to be quite confusing. > Both methods gives transparency to data-stack, but responsibility to preserve > 'xt' differs. > > In my version, responsibility belongs to the word that is fed to the 'YC', in yours belongs to 'YC'. My way does not clutter [the return-stack] and can be used like > this: > > : guarded-counted-loop ( .. xt xt |0 HiLim StartIdx -- .. ) > DO > 0= IF unloop EXIT THEN > execute > LOOP > ; Well, it doesn't matter if the code for YC is clunky and clutters the return-stack, because that code is written once by the implementer (you or me) and the application-programmer doesn't have to concern himself with how it works under the hood. I don't think there is any difference in speed either way. > About confusing 'DUP', is part of the game: the sequence 'dup execute' > I see as indication of y-combinators in forth. Hence the name 'YC'; > is not a y-combinator (that provides recursion), is a factored-loop. I'm thinking of your YC as being a HOF (higher-order function) in that it takes an xt as a parameter and executes the xt inside of a loop. I have several HOFs in the novice package and they vary in regard to how much internal data they work with (EACH FIND-NODE and FIND-PRIOR all work with a linked list, but they do different things). All of my HOFs leave the data-stack clean when they execute the xt so the application-programmer who writes that function doesn't have to know how the HOF works internally --- hiding the internal data is part of the game for the HOF implementer, not for the application-programmer who is using the HOF. I'm not familiar with the term "y-combinator" though, so maybe this is different from a HOF --- it looks like a HOF to me --- I should learn up on y-combinators before I criticize your implementation too much. As I said before, I think you are on the right track. This kind of code is the key to writing general-purpose data-structures. The code that traverses the data-structure is hidden inside of the HOF rather than exposed in the application-program. It is possible to switch out one data-structure for another and only the HOF has to be changed, but the application programs that use the HOF can be recompiled without change and will work. The idea is to spare the application-programmer from having to learn the details of how his data-structure works, but he can just use it having learned only a simple API for it. Of course, this would work better if Forth had quotations so that when the xt is executed it has access to the parent function's local variables --- that is a much cleaner way to communicate with the parent function than fiddling around with the data-stack. Information hiding --- always a good idea!
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-01-31 10:02 -0800 |
| Message-ID | <f00fb3c7-f785-4611-a8a8-2e478f10707f@googlegroups.com> |
| In reply to | #45207 |
On Saturday, January 30, 2016 at 9:32:55 PM UTC+2, hughag...@gmail.com wrote: > On Saturday, January 30, 2016 at 12:27:25 AM UTC-7, humptydumpty wrote: > > On Saturday, January 30, 2016 at 6:42:19 AM UTC+2, hughag...@gmail.com wrote: > > > : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; > > > > > > Here is an alternative suggestion: > > > > > > \ toucher: i*x -- j*x continue? > > > > > > : YC ( xt -- ) >r begin r@ execute while repeat r> drop ; > > > > > > This way when your xt executes it has access to the data-stack that the parent set up (the i*x stuff) without anything (including its own xt value) being on top of this data getting in the way. > > > > > > Also, we get rid of the DUP in your example code --- I found that to be quite confusing. > > > Both methods gives transparency to data-stack, but responsibility to preserve > > 'xt' differs. > > > > In my version, responsibility belongs to the word that is fed to the 'YC', in yours belongs to 'YC'. My way does not clutter [the return-stack] and can be used like > > this: > > > > : guarded-counted-loop ( .. xt xt |0 HiLim StartIdx -- .. ) > > DO > > 0= IF unloop EXIT THEN > > execute > > LOOP > > ; > > Well, it doesn't matter if the code for YC is clunky and clutters the return-stack, because that code is written once by the implementer (you or me) and the application-programmer doesn't have to concern himself with how it works under the hood. I don't think there is any difference in speed either way. > > > About confusing 'DUP', is part of the game: the sequence 'dup execute' > > I see as indication of y-combinators in forth. Hence the name 'YC'; > > is not a y-combinator (that provides recursion), is a factored-loop. > > I'm thinking of your YC as being a HOF (higher-order function) in that it takes an xt as a parameter and executes the xt inside of a loop. I have several HOFs in the novice package and they vary in regard to how much internal data they work with (EACH FIND-NODE and FIND-PRIOR all work with a linked list, but they do different things). All of my HOFs leave the data-stack clean when they execute the xt so the application-programmer who writes that function doesn't have to know how the HOF works internally --- hiding the internal data is part of the game for the HOF implementer, not for the application-programmer who is using the HOF. > > I'm not familiar with the term "y-combinator" though, so maybe this is different from a HOF --- it looks like a HOF to me --- I should learn up on y-combinators before I criticize your implementation too much. > > As I said before, I think you are on the right track. This kind of code is the key to writing general-purpose data-structures. The code that traverses the data-structure is hidden inside of the HOF rather than exposed in the application-program. It is possible to switch out one data-structure for another and only the HOF has to be changed, but the application programs that use the HOF can be recompiled without change and will work. The idea is to spare the application-programmer from having to learn the details of how his data-structure works, but he can just use it having learned only a simple API for it. Of course, this would work better if Forth had quotations so that when the xt is executed it has access to the parent function's local variables --- that is a much cleaner way to communicate with the parent function than fiddling around with the data-stack. > > Information hiding --- always a good idea! Hi! For users sake, I think is good thing to have the same stack effect for all kinds of loops. I don't tested for speed any of them. Of course, this is Forth and everyone can rewrite them for his/her needs. : XT latestxt postpone literal ; immediate : ?YC postpone IF postpone XT postpone ELSE 0 postpone LITERAL postpone THEN ; immediate \ --- 9 LOOPS : YC ( .. xt|0 -- .. ) BEGIN ?dup WHILE execute REPEAT ; : YCC ( .. xt|0 -- .. ) DO execute LOOP drop ; : YCC+ ( .. xt|0 -- .. ) DO execute +LOOP drop ; : YCCI ( .. xt|0 -- .. ) DO I swap execute LOOP drop ; : YCCI+ ( .. xt|0 -- .. ) DO I swap execute +LOOP drop ; : YCG ( .. xt|0 -- .. ) DO ?dup IF execute ELSE unloop exit THEN LOOP drop ; : YCG+ ( .. xt|0 -- .. ) DO ?dup IF execute ELSE unloop exit THEN +LOOP drop ; : YCGI ( .. xt|0 -- .. ) DO ?dup IF I swap execute ELSE unloop exit THEN LOOP drop ; : YCGI+ ( .. xt|0 -- .. ) DO ?dup IF I swap execute ELSE unloop exit THEN +LOOP drop ; Cons: slower than original loop, especially for small loops. Pro: enforce factoring, easy testing: 'execute .S' is all that is needed to test the word to be fed to a factored-loop. Enjoying forth, humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | Julian Fondren <julian.fondren@gmail.com> |
|---|---|
| Date | 2016-02-01 01:32 -0800 |
| Message-ID | <665d20c6-7ddd-44e1-80dd-766716a79c82@googlegroups.com> |
| In reply to | #45218 |
On Sunday, January 31, 2016 at 12:02:41 PM UTC-6, humptydumpty wrote: > Hi! > > For users sake, I think is good thing to have the same stack effect > for all kinds of loops. I don't tested for speed any of them. > Of course, this is Forth and everyone can rewrite them for his/her needs. > > : XT latestxt postpone literal ; immediate > : ?YC postpone IF postpone XT postpone ELSE 0 postpone LITERAL postpone THEN ; immediate > \ --- 9 LOOPS > : YC ( .. xt|0 -- .. ) BEGIN ?dup WHILE execute REPEAT ; > : YCC ( .. xt|0 -- .. ) DO execute LOOP drop ; > : YCC+ ( .. xt|0 -- .. ) DO execute +LOOP drop ; > : YCCI ( .. xt|0 -- .. ) DO I swap execute LOOP drop ; > : YCCI+ ( .. xt|0 -- .. ) DO I swap execute +LOOP drop ; > : YCG ( .. xt|0 -- .. ) DO ?dup IF execute ELSE unloop exit THEN LOOP drop ; > : YCG+ ( .. xt|0 -- .. ) DO ?dup IF execute ELSE unloop exit THEN +LOOP drop ; > : YCGI ( .. xt|0 -- .. ) DO ?dup IF I swap execute ELSE unloop exit THEN LOOP drop ; > : YCGI+ ( .. xt|0 -- .. ) DO ?dup IF I swap execute ELSE unloop exit THEN +LOOP drop ; > > Cons: slower than original loop, especially for small loops. > Pro: enforce factoring, easy testing: 'execute .S' is all that is > needed to test the word to be fed to a factored-loop. > > Enjoying forth, > humptydumpty Thanks for this list of words. I didn't like your YC , and this list helped me to say why. I know, when I start to write a word, whether it'll have a loop or not. Then it's just a question of whether I want to use DO or not. If I'm basically iterating over an array - there is a start and endpoint and they are connected by definite increments from one to other - then I use DO. Otherwise, BEGIN. I don't say, I'll use one of BEGIN ... WHILE ... REPEAT or else BEGIN ... UNTIL or else BEGIN ... AGAIN. Because these are all really just conveniences upon BEGIN ... AGAIN. If you need to do some post-loop work then you can EXIT to a caller that does it or you can branch past the loop to do it. And likewise I don't *think* about which variants of DO ... LOOP I want. It just works out that the code requires one of them. So I approach the word with an understanding that it'll be looping, I decide on DO or BEGIN , and then I no longer care about looping structures, I just care about what the word requires. With your words, I would have to ask: do I want YC, or YCC, or YCC+, or YCCI, or YCCI+, or YCG, or YCG+, or YCGI, or YCGI+ . Even if I'd memorized all of these, I would still have to decide between them. And I still have to decide between them before I write the body of the loop, because it must pass flags or increments to them. Of factoring, instead of having a bunch of words that work together to form loops, you have a fixed list of different kinds of loops that don't work with each other. And the words are still tightly bound to what would be the body of the loop: you can't just switch YC and YCC and get a different looping behavior, for example. And the those original words have a lot of value that's lost: you can no longer EXIT or UNLOOP EXIT and you can't just put -> I <- precisely wherever it's needed and if you have what would be a BEGIN loop you can't put state on the return stack before the loop begins, access it during the loop, and grab it after the loop. On teaching, if I were to teach Forth, even at the level of answering an isolated question about looping, I would say what I said above: when you start to write a looping word, ask these questions. But if Forth only had YC words I would have to say "well, memorize these words and and the fine differences between them". On the look of the language, DO I LOOP isn't so pretty, but it at least uses short real words that you can say to someone instead of spelling them out. The BEGIN words can actually look pretty good. YCG+ is of course "why see gee plus" and you might fail to distinguish between it and YCC+. -- Julian
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-01 02:23 -0800 |
| Message-ID | <b5c2be54-f635-4e36-8ece-2791240a2858@googlegroups.com> |
| In reply to | #45230 |
On Monday, February 1, 2016 at 11:32:39 AM UTC+2, Julian Fondren wrote:
> On Sunday, January 31, 2016 at 12:02:41 PM UTC-6, humptydumpty wrote:
> > Hi!
> >
> > For users sake, I think is good thing to have the same stack effect
> > for all kinds of loops. I don't tested for speed any of them.
> > Of course, this is Forth and everyone can rewrite them for his/her needs.
> >
> > : XT latestxt postpone literal ; immediate
> > : ?YC postpone IF postpone XT postpone ELSE 0 postpone LITERAL postpone THEN ; immediate
> > \ --- 9 LOOPS
> > : YC ( .. xt|0 -- .. ) BEGIN ?dup WHILE execute REPEAT ;
> > : YCC ( .. xt|0 -- .. ) DO execute LOOP drop ;
> > : YCC+ ( .. xt|0 -- .. ) DO execute +LOOP drop ;
> > : YCCI ( .. xt|0 -- .. ) DO I swap execute LOOP drop ;
> > : YCCI+ ( .. xt|0 -- .. ) DO I swap execute +LOOP drop ;
> > : YCG ( .. xt|0 -- .. ) DO ?dup IF execute ELSE unloop exit THEN LOOP drop ;
> > : YCG+ ( .. xt|0 -- .. ) DO ?dup IF execute ELSE unloop exit THEN +LOOP drop ;
> > : YCGI ( .. xt|0 -- .. ) DO ?dup IF I swap execute ELSE unloop exit THEN LOOP drop ;
> > : YCGI+ ( .. xt|0 -- .. ) DO ?dup IF I swap execute ELSE unloop exit THEN +LOOP drop ;
> >
> > Cons: slower than original loop, especially for small loops.
> > Pro: enforce factoring, easy testing: 'execute .S' is all that is
> > needed to test the word to be fed to a factored-loop.
> >
> > Enjoying forth,
> > humptydumpty
>
> Thanks for this list of words. I didn't like your YC , and this
> list helped me to say why.
>
Hi!
That list is not imposed to anyone, but give an ideea of what
could be done.
> I know, when I start to write a word, whether it'll have a loop
> or not. Then it's just a question of whether I want to use DO
> or not. If I'm basically iterating over an array - there is a
> start and endpoint and they are connected by definite increments
> from one to other - then I use DO. Otherwise, BEGIN.
>
> I don't say, I'll use one of BEGIN ... WHILE ... REPEAT or else
> BEGIN ... UNTIL or else BEGIN ... AGAIN. Because these are all
> really just conveniences upon BEGIN ... AGAIN. If you need to
> do some post-loop work then you can EXIT to a caller that does
> it or you can branch past the loop to do it.
>
Then nothing stop to write:
: BA BEGIN execute AGAIN ;
and inside word whom XT is fed to BA to write 'XT' to loop again,
'XT EXIT' to an earlier loop again and 'RDROP EXIT' to exit BA
whenever wish to.
> And likewise I don't *think* about which variants of DO ... LOOP
> I want. It just works out that the code requires one of them.
>
> So I approach the word with an understanding that it'll be
> looping, I decide on DO or BEGIN , and then I no longer care
> about looping structures, I just care about what the word
> requires.
>
> With your words, I would have to ask: do I want YC, or YCC, or
> YCC+, or YCCI, or YCCI+, or YCG, or YCG+, or YCGI, or YCGI+ .
> Even if I'd memorized all of these, I would still have to decide
> between them. And I still have to decide between them before I
> write the body of the loop, because it must pass flags or
> increments to them.
>
The names for those loops I think myself that somehow are poor chosen ...
But everyone can rewrite/use them as he/she wish. Important is ideea behind names.
> Of factoring, instead of having a bunch of words that work
> together to form loops, you have a fixed list of different kinds
> of loops that don't work with each other. And the words are
> still tightly bound to what would be the body of the loop: you
> can't just switch YC and YCC and get a different looping
> behavior, for example. And the those original words have a lot
> of value that's lost: you can no longer EXIT or UNLOOP EXIT and
> you can't just put -> I <- precisely wherever it's needed and if
When you have to factor inside a DO .. LOOP and have to invoke I
you also must pass it as parameter to helper-factoring word.
> you have what would be a BEGIN loop you can't put state on the
> return stack before the loop begins, access it during the loop,
> and grab it after the loop.
>
That way of using return-stack can enforce to write non-factored code.
As a cure for that, you can use something like:
: >{ postpone dup postpone @ postpone 2>R ; immediate
: } postpone R> postpone R> postpone ! ; immediate
VARIABLE State
\ inside factored-word use 'State' as an usual variable
... State >{ ( words modifying State ) } ( return to initial State value )
> On teaching, if I were to teach Forth, even at the level of
> answering an isolated question about looping, I would say what I
> said above: when you start to write a looping word, ask these
> questions. But if Forth only had YC words I would have to say
> "well, memorize these words and and the fine differences between
> them".
>
> On the look of the language, DO I LOOP isn't so pretty, but it
> at least uses short real words that you can say to someone
> instead of spelling them out. The BEGIN words can actually look
> pretty good. YCG+ is of course "why see gee plus" and you might
> fail to distinguish between it and YCC+.
>
> -- Julian
Enjoying Forth,
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-02-01 20:41 -0800 |
| Message-ID | <72571aea-4373-46e1-a575-e495c9683d07@googlegroups.com> |
| In reply to | #45231 |
On Monday, February 1, 2016 at 3:23:38 AM UTC-7, humptydumpty wrote: > On Monday, February 1, 2016 at 11:32:39 AM UTC+2, Julian Fondren wrote: > > Thanks for this list of words. I didn't like your YC , and this > > list helped me to say why. > > ... > > I know, when I start to write a word, whether it'll have a loop > > or not. Then it's just a question of whether I want to use DO > > or not. If I'm basically iterating over an array - there is a > > start and endpoint and they are connected by definite increments > > from one to other - then I use DO. Otherwise, BEGIN. > > > > I don't say, I'll use one of BEGIN ... WHILE ... REPEAT or else > > BEGIN ... UNTIL or else BEGIN ... AGAIN. Because these are all > > really just conveniences upon BEGIN ... AGAIN. If you need to > > do some post-loop work then you can EXIT to a caller that does > > it or you can branch past the loop to do it. > > > > Then nothing stop to write: > > : BA BEGIN execute AGAIN ; > > and inside word whom XT is fed to BA to write 'XT' to loop again, > 'XT EXIT' to an earlier loop again and 'RDROP EXIT' to exit BA > whenever wish to. > > > And likewise I don't *think* about which variants of DO ... LOOP > > I want. It just works out that the code requires one of them. > > > > So I approach the word with an understanding that it'll be > > looping, I decide on DO or BEGIN , and then I no longer care > > about looping structures, I just care about what the word > > requires. > > > > With your words, I would have to ask: do I want YC, or YCC, or > > YCC+, or YCCI, or YCCI+, or YCG, or YCG+, or YCGI, or YCGI+ . > > Even if I'd memorized all of these, I would still have to decide > > between them. And I still have to decide between them before I > > write the body of the loop, because it must pass flags or > > increments to them. > > > The names for those loops I think myself that somehow are poor chosen ... > But everyone can rewrite/use them as he/she wish. Important is ideea behind names. I agree with Julien. The problem here is the idea behind the names --- your HOFs' names describe what the loop does --- your HOFs' names should instead describe what kind of data the HOF iterates over. For example, my EACH tells the user that his xt is executed for each item in the list. The user doesn't have to know what kind of loop is used internally (whether it is a DO loop or a BEGIN loop) --- the whole point of having a HOF is to hide the internal workings of iteration from the user, which includes hiding whether it is a DO loop or a BEGIN loop --- your code isn't really hiding anything, but it is just a shorthand for what the user is already able to do with explicit iteration code. FIND-NODE and FIND-PRIOR are also examples of HOFs whose names tell the user what is being done with the data --- not what is being done with the code --- the goal is that the user should be able to think in terms of data rather than code, and his program should be a description of the resultant data rather than a procedural description of the code that produces this result. Think of your description of the data as being an axiomatic system. Saying that the items in the list are ordered from first to last is an axiom. The user could actually drop this axiom and say that the items are unordered like a set. In this case EACH and FIND-NODE still describe what is done with the data (although duplicates make for a sticky point). FIND-PRIOR no longer makes sense though. Dropping an axiom like this from our definition of a list is similar to how the parallel-line axiom can be dropped form Euclid's geometry and you still get a useful system. The point here is that we are describing the data, not the code. This post has been somewhat philosophical --- but you did say: "Important is idea behind names" --- naming things is a big part of philosophy, and many would say the entirety of philosophy, so you totally asked for a philosophical response! ;-)
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-01 23:36 -0800 |
| Message-ID | <f1dcb775-9e78-4c67-afeb-91781371050d@googlegroups.com> |
| In reply to | #45240 |
On Tuesday, February 2, 2016 at 6:41:17 AM UTC+2, hughag...@gmail.com wrote: > On Monday, February 1, 2016 at 3:23:38 AM UTC-7, humptydumpty wrote: > > On Monday, February 1, 2016 at 11:32:39 AM UTC+2, Julian Fondren wrote: > > > Thanks for this list of words. I didn't like your YC , and this > > > list helped me to say why. > > > ... > > > I know, when I start to write a word, whether it'll have a loop > > > or not. Then it's just a question of whether I want to use DO > > > or not. If I'm basically iterating over an array - there is a > > > start and endpoint and they are connected by definite increments > > > from one to other - then I use DO. Otherwise, BEGIN. > > > > > > I don't say, I'll use one of BEGIN ... WHILE ... REPEAT or else > > > BEGIN ... UNTIL or else BEGIN ... AGAIN. Because these are all > > > really just conveniences upon BEGIN ... AGAIN. If you need to > > > do some post-loop work then you can EXIT to a caller that does > > > it or you can branch past the loop to do it. > > > > > > > Then nothing stop to write: > > > > : BA BEGIN execute AGAIN ; > > > > and inside word whom XT is fed to BA to write 'XT' to loop again, > > 'XT EXIT' to an earlier loop again and 'RDROP EXIT' to exit BA > > whenever wish to. > > > > > And likewise I don't *think* about which variants of DO ... LOOP > > > I want. It just works out that the code requires one of them. > > > > > > So I approach the word with an understanding that it'll be > > > looping, I decide on DO or BEGIN , and then I no longer care > > > about looping structures, I just care about what the word > > > requires. > > > > > > With your words, I would have to ask: do I want YC, or YCC, or > > > YCC+, or YCCI, or YCCI+, or YCG, or YCG+, or YCGI, or YCGI+ . > > > Even if I'd memorized all of these, I would still have to decide > > > between them. And I still have to decide between them before I > > > write the body of the loop, because it must pass flags or > > > increments to them. > > > > > > The names for those loops I think myself that somehow are poor chosen ... > > But everyone can rewrite/use them as he/she wish. Important is ideea behind names. > > I agree with Julien. > > The problem here is the idea behind the names --- your HOFs' names describe what the loop does --- your HOFs' names should instead describe what kind of data the HOF iterates over. > Hi! I wanted just to be pragmatic of reusing allready defined DO LOOP. Maybe I failed at that. > For example, my EACH tells the user that his xt is executed for each item in the list. The user doesn't have to know what kind of loop is used internally (whether it is a DO loop or a BEGIN loop) --- the whole point of having a HOF is to hide the internal workings of iteration from the user, which includes hiding whether it is a DO loop or a BEGIN loop --- your code isn't really hiding anything, but it is just a shorthand for what the user is already able to do with explicit iteration code. > That is no problem, you can define (I reuse name 'each' here just for brevity of post): : each ( .. xt node -- .. ) ['] each YC 2drop ; \ and hide implementation details > FIND-NODE and FIND-PRIOR are also examples of HOFs whose names tell the user what is being done with the data --- not what is being done with the code --- the goal is that the user should be able to think in terms of data rather than code, and his program should be a description of the resultant data rather than a procedural description of the code that produces this result. > > Think of your description of the data as being an axiomatic system. Saying that the items in the list are ordered from first to last is an axiom. The user could actually drop this axiom and say that the items are unordered like a set. In this case EACH and FIND-NODE still describe what is done with the data (although duplicates make for a sticky point). FIND-PRIOR no longer makes sense though. Dropping an axiom like this from our definition of a list is similar to how the parallel-line axiom can be dropped form Euclid's geometry and you still get a useful system. > > The point here is that we are describing the data, not the code. > > This post has been somewhat philosophical --- but you did say: "Important is idea behind names" --- naming things is a big part of philosophy, and many would say the entirety of philosophy, so you totally asked for a philosophical response! ;-) The idea presented is beyond HOF. To express it: "Words (functions) that return handles of themselves that can be used to call again that words (functions), gives a alternative to think/use loops." In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WHILE REPEAT that should be tested in its wholeness, in alternative way as *single-word* (hmm, like a server) and word that use it (like a client). I don't say that alternative way should substitute the classic way, but may be a viable alternative when loop is too complex and hard to test. And I enjoy I discovered that using Forth :-) humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-02-02 20:29 -0800 |
| Message-ID | <5ef3d7d6-c522-4c32-86b9-74713ccaa9b1@googlegroups.com> |
| In reply to | #45242 |
On Tuesday, February 2, 2016 at 12:36:47 AM UTC-7, humptydumpty wrote:
> The idea presented is beyond HOF. To express it: "Words (functions) that return handles of themselves that can be used to call again that words (functions), gives a alternative to think/use loops."
Actually, you do have a good idea here that I didn't think of.
This was my suggestion:
\ toucher: i*x -- j*x continue?
: YC ( xt -- ) >r begin r@ execute while repeat r> drop ;
Your idea is that the word (I call it a "toucher" in my documentation) should return an xt or a FALSE rather than just a TRUE or a FALSE. The xt is typically of itself. This is a good idea because it opens the door for to having the toucher return the xt of another function rather than of itself. For example, two of them could return each other's xt in order to alternate back and forth.
So, here is my new suggestion:
\ toucher: i*x -- j*x xt|false
: YC ( xt -- )
begin execute dup while repeat drop ;
You still have the advantage that the data-stack is free of clutter when the toucher executes, so it can access the data of the parent function. As I've said 100 times here and elsewhere, this is essential. You now have the additional advantage of one toucher staging another one, rather than itself --- this is somewhat similar to a state-machine or a paced-loop in a micro-controller.
The problem here is that we need to have LATEST available --- unfortunately, the badly crippled ANS-Forth standard doesn't support LATEST so there is no easy way for the toucher to obtain its own xt.
> In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WHILE REPEAT that should be tested in its wholeness, in alternative way as *single-word* (hmm, like a server) and word that use it (like a client).
>
> I don't say that alternative way should substitute the classic way, but may be a viable alternative when loop is too complex and hard to test.
One advantage of a HOF is that the toucher can be tested in isolation. If you write a loop explicitly all the code inside hasn't been factored out, so there is no easy way to test it in isolation (I usually put a QUERY INTERPRET inside the loop to single-step through the loop; this was back in Forth-83 when we had QUERY and INTERPRET available).
BTW: I really need to think of a better term than "toucher" --- I suspect that everybody who reads that word imagines a pervert groping women in crowds.
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-03 00:05 -0800 |
| Message-ID | <080f5f39-8bc7-4178-a4d7-b5354ebd6523@googlegroups.com> |
| In reply to | #45260 |
On Wednesday, February 3, 2016 at 6:29:46 AM UTC+2, hughag...@gmail.com wrote:
> On Tuesday, February 2, 2016 at 12:36:47 AM UTC-7, humptydumpty wrote:
> > The idea presented is beyond HOF. To express it: "Words (functions) that return handles of themselves that can be used to call again that words (functions), gives a alternative to think/use loops."
>
> Actually, you do have a good idea here that I didn't think of.
>
Hi!
> This was my suggestion:
>
> \ toucher: i*x -- j*x continue?
>
> : YC ( xt -- ) >r begin r@ execute while repeat r> drop ;
>
> Your idea is that the word (I call it a "toucher" in my documentation) should return an xt or a FALSE rather than just a TRUE or a FALSE. The xt is typically of itself. This is a good idea because it opens the door for to having the toucher return the xt of another function rather than of itself. For example, two of them could return each other's xt in order to alternate back and forth.
>
> So, here is my new suggestion:
>
> \ toucher: i*x -- j*x xt|false
>
> : YC ( xt -- )
> begin execute dup while repeat drop ;
>
As suits your needs. I think I make-up my mind about my proposition of YC:
: YC ( .. selfxt n -- .. ) BEGIN WHILE execute REPEAT ;
,where n could be selfxt, a link, an data address, a count ...etc OR 0 to stop the loop.
> You still have the advantage that the data-stack is free of clutter when the toucher executes, so it can access the data of the parent function. As I've said 100 times here and elsewhere, this is essential. You now have the additional advantage of one toucher staging another one, rather than itself --- this is somewhat similar to a state-machine or a paced-loop in a micro-controller.
>
> The problem here is that we need to have LATEST available --- unfortunately, the badly crippled ANS-Forth standard doesn't support LATEST so there is no easy way for the toucher to obtain its own xt.
>
I think that this could be cured .. in time. :-)
> > In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WHILE REPEAT that should be tested in its wholeness, in alternative way as *single-word* (hmm, like a server) and word that use it (like a client).
> >
> > I don't say that alternative way should substitute the classic way, but may be a viable alternative when loop is too complex and hard to test.
>
> One advantage of a HOF is that the toucher can be tested in isolation. If you write a loop explicitly all the code inside hasn't been factored out, so there is no easy way to test it in isolation (I usually put a QUERY INTERPRET inside the loop to single-step through the loop; this was back in Forth-83 when we had QUERY and INTERPRET available).
>
> BTW: I really need to think of a better term than "toucher" --- I suspect that everybody who reads that word imagines a pervert groping women in crowds.
Uh oh! :-) Maybe a "client", "using-word" ?
Enjoying Forth,
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-03 00:26 -0800 |
| Message-ID | <3a8f6dd4-993e-4429-aedb-54399464ccbb@googlegroups.com> |
| In reply to | #45260 |
On Wednesday, February 3, 2016 at 6:29:46 AM UTC+2, hughag...@gmail.com wrote:
> On Tuesday, February 2, 2016 at 12:36:47 AM UTC-7, humptydumpty wrote:
> > The idea presented is beyond HOF. To express it: "Words (functions) that return handles of themselves that can be used to call again that words (functions), gives a alternative to think/use loops."
>
> Actually, you do have a good idea here that I didn't think of.
>
> This was my suggestion:
>
> \ toucher: i*x -- j*x continue?
>
> : YC ( xt -- ) >r begin r@ execute while repeat r> drop ;
>
> Your idea is that the word (I call it a "toucher" in my documentation) should return an xt or a FALSE rather than just a TRUE or a FALSE. The xt is typically of itself. This is a good idea because it opens the door for to having the toucher return the xt of another function rather than of itself. For example, two of them could return each other's xt in order to alternate back and forth.
>
> So, here is my new suggestion:
>
> \ toucher: i*x -- j*x xt|false
>
> : YC ( xt -- )
> begin execute dup while repeat drop ;
>
As suits your needs. I think I make-up my mind about my proposition of YC:
: YC ( .. selfxt n -- .. ) BEGIN WHILE execute REPEAT drop ;
,where n could be selfxt, a link, an data address, a count ...etc OR 0 to stop the loop.
> You still have the advantage that the data-stack is free of clutter when the toucher executes, so it can access the data of the parent function. As I've said 100 times here and elsewhere, this is essential. You now have the additional advantage of one toucher staging another one, rather than itself --- this is somewhat similar to a state-machine or a paced-loop in a micro-controller.
>
> The problem here is that we need to have LATEST available --- unfortunately, the badly crippled ANS-Forth standard doesn't support LATEST so there is no easy way for the toucher to obtain its own xt.
>
> > In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WHILE REPEAT that should be tested in its wholeness, in alternative way as *single-word* (hmm, like a server) and word that use it (like a client).
> >
> > I don't say that alternative way should substitute the classic way, but may be a viable alternative when loop is too complex and hard to test.
>
> One advantage of a HOF is that the toucher can be tested in isolation. If you write a loop explicitly all the code inside hasn't been factored out, so there is no easy way to test it in isolation (I usually put a QUERY INTERPRET inside the loop to single-step through the loop; this was back in Forth-83 when we had QUERY and INTERPRET available).
>
> BTW: I really need to think of a better term than "toucher" --- I suspect that everybody who reads that word imagines a pervert groping women in crowds.
Uh oh! :-) Maybe a "client", "using-word" ?
Enjoying Forth,
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | Albert van der Horst <albert@spenarnc.xs4all.nl> |
|---|---|
| Date | 2016-02-03 12:17 +0000 |
| Subject | Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; |
| Message-ID | <56b1efed$0$23834$e4fe514c@news.xs4all.nl> |
| In reply to | #45262 |
humptydumpty <ouatubi@gmail.com> writes:
>On Wednesday, February 3, 2016 at 6:29:46 AM UTC+2, hughag...@gmail.com wro=
>te:
>> On Tuesday, February 2, 2016 at 12:36:47 AM UTC-7, humptydumpty wrote:
>> > The idea presented is beyond HOF. To express it: "Words (functions) th=
>at return handles of themselves that can be used to call again that words (=
>functions), gives a alternative to think/use loops."
>>=20
>> Actually, you do have a good idea here that I didn't think of.=20
>>=20
>> This was my suggestion:
>>=20
>> \ toucher: i*x -- j*x continue?=20
>>=20
>> : YC ( xt -- ) >r begin r@ execute while repeat r> drop ;=20
>>=20
>> Your idea is that the word (I call it a "toucher" in my documentation) sh=
>ould return an xt or a FALSE rather than just a TRUE or a FALSE. The xt is =
>typically of itself. This is a good idea because it opens the door for to h=
>aving the toucher return the xt of another function rather than of itself. =
>For example, two of them could return each other's xt in order to alternate=
> back and forth.
>>=20
>> So, here is my new suggestion:
>>=20
>> \ toucher: i*x -- j*x xt|false
>>=20
>> : YC ( xt -- ) =20
>> begin execute dup while repeat drop ;
>>
>As suits your needs. I think I make-up my mind about my proposition of YC:
>: YC ( .. selfxt n -- .. ) BEGIN WHILE execute REPEAT drop ;
> ,where n could be selfxt, a link, an data address, a count ...etc O=
>R 0 to stop the loop.
>=20
>> You still have the advantage that the data-stack is free of clutter when =
>the toucher executes, so it can access the data of the parent function. As =
>I've said 100 times here and elsewhere, this is essential. You now have the=
> additional advantage of one toucher staging another one, rather than itsel=
>f --- this is somewhat similar to a state-machine or a paced-loop in a micr=
>o-controller.
>>=20
>> The problem here is that we need to have LATEST available --- unfortunate=
>ly, the badly crippled ANS-Forth standard doesn't support LATEST so there i=
>s no easy way for the toucher to obtain its own xt.
>>=20
>> > In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WH=
>ILE REPEAT that should be tested in its wholeness, in alternative way as *s=
>ingle-word* (hmm, like a server) and word that use it (like a client).
>> >=20
>> > I don't say that alternative way should substitute the classic way, but=
> may be a viable alternative when loop is too complex and hard to test.
>>=20
>> One advantage of a HOF is that the toucher can be tested in isolation. If=
> you write a loop explicitly all the code inside hasn't been factored out, =
>so there is no easy way to test it in isolation (I usually put a QUERY INTE=
>RPRET inside the loop to single-step through the loop; this was back in For=
>th-83 when we had QUERY and INTERPRET available).
>>=20
>> BTW: I really need to think of a better term than "toucher" --- I suspect=
> that everybody who reads that word imagines a pervert groping women in cro=
>wds.
The idea that the to be repeated action should return its own xt
could be extended with the idea that execution addresses belong
on the return stack. So
{ .... } loop
{ } puts an xt of sorts on the return stack.
Then loop executes that xt, until it is zero.
The IF EXIT THEN would be replaced by break? that replaces (
conditionally) the top of the return stack with a zero, a
very light action.
:NONAME ... ;
could be replaced by
{ ... } R>
>Uh oh! :-) Maybe a "client", "using-word" ?
>Enjoying Forth,
>humptydumpty
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-03 06:17 -0800 |
| Subject | Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; |
| Message-ID | <c2f9ca02-3d80-4314-9bc4-ed8ea3b1220e@googlegroups.com> |
| In reply to | #45268 |
On Wednesday, February 3, 2016 at 2:17:51 PM UTC+2, Albert van der Horst wrote:
> humptydumpty <> writes:
>
> >On Wednesday, February 3, 2016 at 6:29:46 AM UTC+2, hughag...@gmail.com wro=
> >te:
> >> On Tuesday, February 2, 2016 at 12:36:47 AM UTC-7, humptydumpty wrote:
> >> > The idea presented is beyond HOF. To express it: "Words (functions) th=
> >at return handles of themselves that can be used to call again that words (=
> >functions), gives a alternative to think/use loops."
> >>=20
> >> Actually, you do have a good idea here that I didn't think of.=20
> >>=20
> >> This was my suggestion:
> >>=20
> >> \ toucher: i*x -- j*x continue?=20
> >>=20
> >> : YC ( xt -- ) >r begin r@ execute while repeat r> drop ;=20
> >>=20
> >> Your idea is that the word (I call it a "toucher" in my documentation) sh=
> >ould return an xt or a FALSE rather than just a TRUE or a FALSE. The xt is =
> >typically of itself. This is a good idea because it opens the door for to h=
> >aving the toucher return the xt of another function rather than of itself. =
> >For example, two of them could return each other's xt in order to alternate=
> > back and forth.
> >>=20
> >> So, here is my new suggestion:
> >>=20
> >> \ toucher: i*x -- j*x xt|false
> >>=20
> >> : YC ( xt -- ) =20
> >> begin execute dup while repeat drop ;
> >>
>
> >As suits your needs. I think I make-up my mind about my proposition of YC:
>
> >: YC ( .. selfxt n -- .. ) BEGIN WHILE execute REPEAT drop ;
>
> > ,where n could be selfxt, a link, an data address, a count ...etc O=
> >R 0 to stop the loop.
>
> >=20
> >> You still have the advantage that the data-stack is free of clutter when =
> >the toucher executes, so it can access the data of the parent function. As =
> >I've said 100 times here and elsewhere, this is essential. You now have the=
> > additional advantage of one toucher staging another one, rather than itsel=
> >f --- this is somewhat similar to a state-machine or a paced-loop in a micr=
> >o-controller.
> >>=20
> >> The problem here is that we need to have LATEST available --- unfortunate=
> >ly, the badly crippled ANS-Forth standard doesn't support LATEST so there i=
> >s no easy way for the toucher to obtain its own xt.
> >>=20
> >> > In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WH=
> >ILE REPEAT that should be tested in its wholeness, in alternative way as *s=
> >ingle-word* (hmm, like a server) and word that use it (like a client).
> >> >=20
> >> > I don't say that alternative way should substitute the classic way, but=
> > may be a viable alternative when loop is too complex and hard to test.
> >>=20
> >> One advantage of a HOF is that the toucher can be tested in isolation. If=
> > you write a loop explicitly all the code inside hasn't been factored out, =
> >so there is no easy way to test it in isolation (I usually put a QUERY INTE=
> >RPRET inside the loop to single-step through the loop; this was back in For=
> >th-83 when we had QUERY and INTERPRET available).
> >>=20
> >> BTW: I really need to think of a better term than "toucher" --- I suspect=
> > that everybody who reads that word imagines a pervert groping women in cro=
> >wds.
>
> The idea that the to be repeated action should return its own xt
> could be extended with the idea that execution addresses belong
> on the return stack. So
>
> { .... } loop
> { } puts an xt of sorts on the return stack.
> Then loop executes that xt, until it is zero.
> The IF EXIT THEN would be replaced by break? that replaces (
> conditionally) the top of the return stack with a zero, a
> very light action.
>
Looks that is implementation dependent. AFAIK gforth-itc and lina
has in return-stack the xt of next word in definition:
: continuation R@ ; ok
' dup :noname continuation dup drop @ ; execute = . -1 ok
But appears the problem of testing in isolation of step { ... },
as '{ ... }' affects return-stack.
The only loops I founded using return-stack manipulations:
1. The simplest way to provides loop using return-stack is
'continuation >R step-sequence-of-code R@ ;', exit with 'rdrop exit',
continue with 'exit'.
2. Another, a little more complex, generator-filter:
: ENTER >R ;
: | IF EXIT THEN RDROP ;
: START BEGIN R@ ENTER AGAIN ;
: STOP IF RDROP RDROP RDROP THEN ;
I need to think more about that..
> :NONAME ... ;
> could be replaced by
> { ... } R>
>
> >Uh oh! :-) Maybe a "client", "using-word" ?
>
> >Enjoying Forth,
> >humptydumpty
> --
> Albert van der Horst, UTRECHT,THE NETHERLANDS
> Economic growth -- being exponential -- ultimately falters.
> albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
Enjoying Forth,
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2016-02-03 06:19 -0800 |
| Subject | Re: : YC ( .. xt xt |0 -- .. ) BEGIN WHILE execute REPEAT ; |
| Message-ID | <e596bccf-e42d-476c-86bf-e74e125d9869@googlegroups.com> |
| In reply to | #45273 |
On Wednesday, February 3, 2016 at 4:17:15 PM UTC+2, humptydumpty wrote:
> On Wednesday, February 3, 2016 at 2:17:51 PM UTC+2, Albert van der Horst wrote:
> > humptydumpty <> writes:
> >
> > >On Wednesday, February 3, 2016 at 6:29:46 AM UTC+2, hughag...@gmail.com wro=
> > >te:
> > >> On Tuesday, February 2, 2016 at 12:36:47 AM UTC-7, humptydumpty wrote:
> > >> > The idea presented is beyond HOF. To express it: "Words (functions) th=
> > >at return handles of themselves that can be used to call again that words (=
> > >functions), gives a alternative to think/use loops."
> > >>=20
> > >> Actually, you do have a good idea here that I didn't think of.=20
> > >>=20
> > >> This was my suggestion:
> > >>=20
> > >> \ toucher: i*x -- j*x continue?=20
> > >>=20
> > >> : YC ( xt -- ) >r begin r@ execute while repeat r> drop ;=20
> > >>=20
> > >> Your idea is that the word (I call it a "toucher" in my documentation) sh=
> > >ould return an xt or a FALSE rather than just a TRUE or a FALSE. The xt is =
> > >typically of itself. This is a good idea because it opens the door for to h=
> > >aving the toucher return the xt of another function rather than of itself. =
> > >For example, two of them could return each other's xt in order to alternate=
> > > back and forth.
> > >>=20
> > >> So, here is my new suggestion:
> > >>=20
> > >> \ toucher: i*x -- j*x xt|false
> > >>=20
> > >> : YC ( xt -- ) =20
> > >> begin execute dup while repeat drop ;
> > >>
> >
> > >As suits your needs. I think I make-up my mind about my proposition of YC:
> >
> > >: YC ( .. selfxt n -- .. ) BEGIN WHILE execute REPEAT drop ;
> >
> > > ,where n could be selfxt, a link, an data address, a count ...etc O=
> > >R 0 to stop the loop.
> >
> > >=20
> > >> You still have the advantage that the data-stack is free of clutter when =
> > >the toucher executes, so it can access the data of the parent function. As =
> > >I've said 100 times here and elsewhere, this is essential. You now have the=
> > > additional advantage of one toucher staging another one, rather than itsel=
> > >f --- this is somewhat similar to a state-machine or a paced-loop in a micr=
> > >o-controller.
> > >>=20
> > >> The problem here is that we need to have LATEST available --- unfortunate=
> > >ly, the badly crippled ANS-Forth standard doesn't support LATEST so there i=
> > >s no easy way for the toucher to obtain its own xt.
> > >>=20
> > >> > In classic way I think of a loop as a *monolithic block* (ex.) BEGIN WH=
> > >ILE REPEAT that should be tested in its wholeness, in alternative way as *s=
> > >ingle-word* (hmm, like a server) and word that use it (like a client).
> > >> >=20
> > >> > I don't say that alternative way should substitute the classic way, but=
> > > may be a viable alternative when loop is too complex and hard to test.
> > >>=20
> > >> One advantage of a HOF is that the toucher can be tested in isolation. If=
> > > you write a loop explicitly all the code inside hasn't been factored out, =
> > >so there is no easy way to test it in isolation (I usually put a QUERY INTE=
> > >RPRET inside the loop to single-step through the loop; this was back in For=
> > >th-83 when we had QUERY and INTERPRET available).
> > >>=20
> > >> BTW: I really need to think of a better term than "toucher" --- I suspect=
> > > that everybody who reads that word imagines a pervert groping women in cro=
> > >wds.
> >
> > The idea that the to be repeated action should return its own xt
> > could be extended with the idea that execution addresses belong
> > on the return stack. So
> >
> > { .... } loop
> > { } puts an xt of sorts on the return stack.
> > Then loop executes that xt, until it is zero.
> > The IF EXIT THEN would be replaced by break? that replaces (
> > conditionally) the top of the return stack with a zero, a
> > very light action.
> >
>
> Looks that is implementation dependent. AFAIK gforth-itc and lina
> has in return-stack the xt of next word in definition:
>
> : continuation R@ ; ok
> ' dup :noname continuation dup drop @ ; execute = . -1 ok
>
> But appears the problem of testing in isolation of step { ... },
> as '{ ... }' affects return-stack.
>
> The only loops I founded using return-stack manipulations:
>
> 1. The simplest way to provides loop using return-stack is
> 'continuation >R step-sequence-of-code R@ ;', exit with 'rdrop exit',
> continue with 'exit'.
>
> 2. Another, a little more complex, generator-filter:
>
> : ENTER >R ;
> : | IF EXIT THEN RDROP ;
> : START BEGIN R@ ENTER AGAIN ;
> : STOP IF RDROP RDROP RDROP THEN ;
>
> I need to think more about that..
>
> > :NONAME ... ;
> > could be replaced by
> > { ... } R>
> >
> > >Uh oh! :-) Maybe a "client", "using-word" ?
> >
> > >Enjoying Forth,
> > >humptydumpty
> > --
> > Albert van der Horst, UTRECHT,THE NETHERLANDS
> > Economic growth -- being exponential -- ultimately falters.
> > albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
>
> Enjoying Forth,
> humptydumpty
> 1. The simplest way to provides loop using return-stack is
> 'continuation >R step-sequence-of-code R@ ;', exit with 'rdrop exit',
> continue with 'exit'.
should be continue with 'R@ exit', sorry
humptydumpty
[toc] | [prev] | [next] | [standalone]
| From | franck.bensusan@gmail.com |
|---|---|
| Date | 2016-02-03 01:02 -0800 |
| Message-ID | <c0479ae3-1deb-493f-aa4b-367691c66743@googlegroups.com> |
| In reply to | #45260 |
Le mercredi 3 février 2016 05:29:46 UTC+1, hughag...@gmail.com a écrit : > The problem here is that we need to have LATEST available --- YC is really a great feature, but a rather theorical one. Until now, I didn't found any operational application (I wish I could one day). It allows (among other things) to demonstrate that a non recursive functional language can implement recursivity just with elements of the language. So, "theorically", LASTEST is allowed to write a YC. (practically, nobody cares). And YC is a subject where closures are interesting to use. For instance, in Oforth, a (recursive) version of YC could be : : YC(f) // word -- bl #[ f YC f perform ] ; And it is now possible to transform a non-recursive word into a recursive one. For instance (almost-fact is not recursive) : : almost-fact(f, n) -- n1 n ifZero: [ 1 ] else: [ n n 1 - f perform * ] ; #almost-fact YC => fact 5 fact . 120 ok Here, this demonstrates nothing, because YC itself is a recursive word, but it is easy to write a non-recursive version of YC. Franck
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.forth
csiph-web