Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #37626 > unrolled thread
| Started by | hughaguilar96@gmail.com |
|---|---|
| First post | 2015-03-24 21:42 -0700 |
| Last post | 2015-04-11 15:04 +0200 |
| Articles | 11 — 7 participants |
Back to article view | Back to comp.lang.forth
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Forth loops don't inherently loop once hughaguilar96@gmail.com - 2015-03-24 21:42 -0700
Re: Forth loops don't inherently loop once Ron Aaron <rambamist@gmail.com> - 2015-03-25 07:54 +0200
Re: Forth loops don't inherently loop once "Alex McDonald" <blog@rivadpm.com> - 2015-03-25 07:33 +0000
Re: Forth loops don't inherently loop once Ron Aaron <rambamist@gmail.com> - 2015-03-25 09:43 +0200
Re: Forth loops don't inherently loop once "Rod Pemberton" <bork@lllljunkqwer.cpm> - 2015-03-28 03:35 -0400
Re: Forth loops don't inherently loop once Ron Aaron <rambamist@gmail.com> - 2015-03-28 20:31 +0300
Re: Forth loops don't inherently loop once "WJ" <w_a_x_man@yahoo.com> - 2015-03-25 06:19 +0000
Re: Forth loops don't inherently loop once Hans Bezemer <the.beez.speaks@gmail.com> - 2015-04-10 17:34 +0200
Re: Forth loops don't inherently loop once Coos Haak <chforth@hccnet.nl> - 2015-04-11 00:24 +0200
Re: Forth loops don't inherently loop once hughaguilar96@gmail.com - 2015-04-10 18:59 -0700
Re: Forth loops don't inherently loop once Hans Bezemer <the.beez.speaks@gmail.com> - 2015-04-11 15:04 +0200
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-03-24 21:42 -0700 |
| Subject | Re: Forth loops don't inherently loop once |
| Message-ID | <08127e8c-cc3b-4d53-a9a1-2ac733df7c97@googlegroups.com> |
On Wednesday, August 7, 2013 at 11:25:21 AM UTC-7, Elizabeth D. Rather wrote: > On 8/7/13 1:46 AM, Mark Wills wrote: > > Er, exactly what problem is this trying to solve? I'm at a total loss here. I don't know what he's talking about either. BTW: Some ANS-Forth cruft that I will get rid of in my language, is UNTIL and AGAIN. All that is needed is BEGIN WHILE REPEAT with any number of WHILE (including zero, so BEGIN REPEAT does what BEGIN AGAIN currently does). > Forth offers both test-at-the-beginning loops and test-at-the-end loops: I don't like to expose any kind of loop to the application programmer, especially the novice. It should be possible to write most programs without any kind of explicit iteration. In my language, loops will be considered to be expert-only programming --- the only loop mechanisms provided will be BEGIN WHILE REPEAT and recursion, and the novice will be encouraged to not learn either of these until he has some experience writing programs (has written several non-trivial programs). ANS-Forth is very crude in that it requires the programmer to write loops manually. Iteration just complicates programs and makes them hard to read. As much as possible, iteration should hidden inside of higher-order functions (and leave it to the experts to write these) --- the typical programmer shouldn't have to deal with explicit loops and the testing of an index to a limit, either at the beginning or the end or the middle either. Loops are a major source of bugs. It is very common to write a loop that executes one too many times. Also, it is difficult to look at a loop in the source-code and tell at a glance how many times it will execute, and if this is the correct number of times. Because of this, programmers should avoid writing loops, and leave that to the experts --- the ideal should be that most programs have no loops at all --- even after the programmer becomes an expert, he should eschew iteration in order to avoid bugs and increase readability.
[toc] | [next] | [standalone]
| From | Ron Aaron <rambamist@gmail.com> |
|---|---|
| Date | 2015-03-25 07:54 +0200 |
| Message-ID | <metihq$fk$1@dont-email.me> |
| In reply to | #37626 |
On 3/25/15 06:42, hughaguilar96@gmail.com wrote: > I don't like to expose any kind of loop to the application programmer, especially the novice. It should be possible to write most programs without any kind of explicit iteration. In my language, loops will be considered to be expert-only programming --- the only loop mechanisms provided will be BEGIN WHILE REPEAT and recursion, and the novice will be encouraged to not learn either of these until he has some experience writing programs (has written several non-trivial programs). Well, that certainly is a unique approach. I think you'll find that most real-world programs will need iteration of some kind. Making that easy for the user will make your users less frustrated when they try to actually *do* something with your language. It's also a good idea to stop categorizing your users as 'novice' or 'expert' programmers. Help all of them to become 'competent' users of your system. 8th (8th-dev.com) has a number of looping constructs, serving different needs. 'loop' and 'loop-' are analogues of a typical 'for loop' in most languages, e.g. ' someword 1 10 loop It also has 'repeat...again' and 'repeat ... while' (no 'begin' word) which are familiar to most Forthers. There is also 'times' which does not provide the current iteration index: ' someword 5 times Containers like arrays and objects have 'each': [1,20,300] ' on-each-item a:each In all of these scenarios, invoking 'break' in the iterator will make the current iteration the last one to execute. And you can also use the recursive iteration technique familiar from Forth: : xyzzy .... recurse ;
[toc] | [prev] | [next] | [standalone]
| From | "Alex McDonald" <blog@rivadpm.com> |
|---|---|
| Date | 2015-03-25 07:33 +0000 |
| Message-ID | <meto9s$fv5$1@dont-email.me> |
| In reply to | #37629 |
on 25/03/2015 05:54:48, Ron Aaron wrote: > > > On 3/25/15 06:42, hughaguilar96@gmail.com wrote: > >> I don't like to expose any kind of loop to the application programmer, especially the novice. It should be possible to write most programs without any kind of explicit iteration. In my language, loops will be considered to be expert-only programming --- the only loop mechanisms provided will be BEGIN WHILE REPEAT and recursion, and the novice will be encouraged to not learn either of these until he has some experience writing programs (has written several non-trivial programs). > > Well, that certainly is a unique approach. I think you'll find that > most real-world programs will need iteration of some kind. Making that > easy for the user will make your users less frustrated when they try > to actually *do* something with your language. > Hugh's loop appears to be repeating the claim that he has a language.
[toc] | [prev] | [next] | [standalone]
| From | Ron Aaron <rambamist@gmail.com> |
|---|---|
| Date | 2015-03-25 09:43 +0200 |
| Message-ID | <metotg$hmn$1@dont-email.me> |
| In reply to | #37633 |
On 3/25/15 09:33, Alex McDonald wrote: > Hugh's loop appears to be repeating the claim that he has a language. To be fair, he only claims what his language *will* have...
[toc] | [prev] | [next] | [standalone]
| From | "Rod Pemberton" <bork@lllljunkqwer.cpm> |
|---|---|
| Date | 2015-03-28 03:35 -0400 |
| Message-ID | <op.xv651ublwa0t4m@localhost> |
| In reply to | #37634 |
On Wed, 25 Mar 2015 03:43:31 -0400, Ron Aaron <rambamist@gmail.com> wrote: > On 3/25/15 09:33, Alex McDonald wrote: >> Hugh's loop appears to be repeating the claim that he has a language. > > To be fair, he only claims what his language *will* have... I don't know why this is taking him so long ... Do you? Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | Ron Aaron <rambamist@gmail.com> |
|---|---|
| Date | 2015-03-28 20:31 +0300 |
| Message-ID | <mf6ofo$pef$1@dont-email.me> |
| In reply to | #37701 |
On 3/28/15 10:35, Rod Pemberton wrote: > I don't know why this is taking him so long ... Do you? Dunno. He's not confided in me...
[toc] | [prev] | [next] | [standalone]
| From | "WJ" <w_a_x_man@yahoo.com> |
|---|---|
| Date | 2015-03-25 06:19 +0000 |
| Message-ID | <metk11$4bg$1@dont-email.me> |
| In reply to | #37626 |
hughaguilar96@gmail.com wrote: > I don't like to expose any kind of loop to the > application programmer, especially the novice. It > should be possible to write most programs without > any kind of explicit iteration. In my language, > loops will be considered to be expert-only > programming --- the only loop mechanisms provided > will be BEGIN WHILE REPEAT and recursion, and the > novice will be encouraged to not learn either of > these until he has some experience writing > programs (has written several non-trivial > programs). > > ANS-Forth is very crude in that it requires the > programmer to write loops manually. Iteration just > complicates programs and makes them hard to read. > As much as possible, iteration should hidden > inside of higher-order functions (and leave it to > the experts to write these) --- the typical > programmer shouldn't have to deal with explicit > loops and the testing of an index to a limit, > either at the beginning or the end or the middle > either. > > Loops are a major source of bugs. It is very > common to write a loop that executes one too many > times. Also, it is difficult to look at a loop in > the source-code and tell at a glance how many > times it will execute, and if this is the correct > number of times. Because of this, programmers > should avoid writing loops, and leave that to the > experts --- the ideal should be that most programs > have no loops at all --- even after the programmer > becomes an expert, he should eschew iteration in > order to avoid bugs and increase readability. There is a lot of truth in this. One of the gurus in the K (or Q) language (similar to J and APL) has a motto: "We don't need no stinkin' loops!" Some examples in Oforth. Say you have a list or array of numbers, and you want to create a new list by incrementing each number. We don't explicitly loop, we just use the higher-order function "map", which is also found in Scheme, Lisp, Ruby, etc. (Think of a one-to-one mapping.) > seq( 9 ) dup println map( #++ ) println [1, 2, 3, 4, 5, 6, 7, 8, 9] [2, 3, 4, 5, 6, 7, 8, 9, 10] > "ABCDE" map( #[ 32 + ] ) charsAsString println abcde Say you have a sequence of numbers, and you want to keep only the odd ones: > 22 seq filter( #isOdd ) println [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21] Say you have two sequences, and you want to pair the elements: > [ 2, 3, 4, 5 ] [ "or", "a", "big", "why" ] zip println [[2, or], [3, a], [4, big], [5, why]] Say you want to add up the numbers in a list. (Oforth has the command "sum", but we'll do it the hard way.) > 0 [ 1, 3, 5, 7, 9 ] apply( #+ ) println 25 Another way: > [ 1, 3, 5, 7, 9 ] reduce( #+ ) println 25 To execute code a certain number of times: > #[ "Hello" println ] times( 3 ) Hello Hello Hello > 2 #sq times( 3 ) println 256
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2015-04-10 17:34 +0200 |
| Message-ID | <5527ed9b$0$2937$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #37626 |
hughaguilar96@gmail.com wrote:
> BTW: Some ANS-Forth cruft that I will get rid of in my language, is UNTIL
> and AGAIN. All that is needed is BEGIN WHILE REPEAT with any number of
> WHILE (including zero, so BEGIN REPEAT does what BEGIN AGAIN currently
> does).
I like your thinking. That's exactly what I did in 4tH: as many WHILE's as
you like (without ugly THEN's) and REPEAT and AGAIN are aliases. I kept
UNTIL though, since it is just a "0BRANCH" instead of a "BRANCH"
(REPEAT/AGAIN). The idea is not new though. I can remember somebody writing
an article on the same thing in FD.
I added another construct, which is "DONE". A "DONE" is connected to the
last "WHILE" defined and is triggered when that "WHILE" condition fails.
E.g.
---8<---
: test begin dup while 1- done . done ." Not ready yet!" cr repeat ;
5 test Not ready yet!
Not ready yet!
Not ready yet!
Not ready yet!
Not ready yet!
0 ok
---8<---
In ANS it is defined as:
---8<---
: DONE 1 CS-ROLL POSTPONE ELSE 1 CS-ROLL ; IMMEDIATE
---8<---
It is especially handy when the stack is different between several WHILE's,
because you can clean it up in specific ways before leaving instead of
dumping and dropping useless items on the stack, just to keep it balanced.
It is interesting to see what it compiles to (gForth):
see test
: test
BEGIN dup
IF 1-
ELSE .
ELSE .\" Not ready yet!" cr
REPEAT
or 4tH:
4tH message: No errors at word 11
Object size: 11 words
String size: 15 chars
Variables : 0 cells
Strings : 0 chars
Reliable : Yes
[ 0] branch (11)
[ 1] dup (0)
[ 2] 0branch (5)
[ 3] +literal (-1)
[ 4] branch (7)
[ 5] . (0)
[ 6] branch (10)
[ 7] ." (0) Not ready yet!
[ 8] cr (0)
[ 9] branch (1)
[ 10] exit (0)
BTW, a single "DONE" is a "NOOP".
May be this gives you some extra inspiration! ;-)
Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | Coos Haak <chforth@hccnet.nl> |
|---|---|
| Date | 2015-04-11 00:24 +0200 |
| Message-ID | <4g7c0krzd9tp.1lr72gfa11oid.dlg@40tude.net> |
| In reply to | #38085 |
Op Fri, 10 Apr 2015 17:34:43 +0200 schreef Hans Bezemer: > hughaguilar96@gmail.com wrote: >> BTW: Some ANS-Forth cruft that I will get rid of in my language, is UNTIL >> and AGAIN. All that is needed is BEGIN WHILE REPEAT with any number of >> WHILE (including zero, so BEGIN REPEAT does what BEGIN AGAIN currently >> does). > > I like your thinking. That's exactly what I did in 4tH: as many WHILE's as > you like (without ugly THEN's) and REPEAT and AGAIN are aliases. I kept > UNTIL though, since it is just a "0BRANCH" instead of a "BRANCH" > (REPEAT/AGAIN). The idea is not new though. I can remember somebody writing > an article on the same thing in FD. > > I added another construct, which is "DONE". A "DONE" is connected to the > last "WHILE" defined and is triggered when that "WHILE" condition fails. > E.g. > > ---8<--- >: test begin dup while 1- done . done ." Not ready yet!" cr repeat ; > > 5 test Not ready yet! > Not ready yet! > Not ready yet! > Not ready yet! > Not ready yet! > 0 ok > ---8<--- > > In ANS it is defined as: > > ---8<--- >: DONE 1 CS-ROLL POSTPONE ELSE 1 CS-ROLL ; IMMEDIATE > ---8<--- > > It is especially handy when the stack is different between several WHILE's, > because you can clean it up in specific ways before leaving instead of > dumping and dropping useless items on the stack, just to keep it balanced. > > It is interesting to see what it compiles to (gForth): > see test >: test > BEGIN dup > IF 1- > ELSE . > ELSE .\" Not ready yet!" cr > REPEAT > > or 4tH: > > 4tH message: No errors at word 11 > Object size: 11 words > String size: 15 chars > Variables : 0 cells > Strings : 0 chars > Reliable : Yes > > [ 0] branch (11) > [ 1] dup (0) > [ 2] 0branch (5) > [ 3] +literal (-1) > [ 4] branch (7) > [ 5] . (0) > [ 6] branch (10) > [ 7] ." (0) Not ready yet! > [ 8] cr (0) > [ 9] branch (1) > [ 10] exit (0) > > BTW, a single "DONE" is a "NOOP". > > May be this gives you some extra inspiration! ;-) > > Hans Bezemer It's the old multiple ELSE trick: .. if .. else .. else .. else .. then .. And what's the advantage above : test begin dup while 1- ." Not ready yet!" cr repeat . ; -- Coos CHForth, 16 bit DOS applications http://home.hccnet.nl/j.j.haak/forth.html
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2015-04-10 18:59 -0700 |
| Message-ID | <48b3cf51-3cc0-4364-a63e-9a585152e343@googlegroups.com> |
| In reply to | #38108 |
On Friday, April 10, 2015 at 3:34:04 PM UTC-7, Coos Haak wrote:
> Op Fri, 10 Apr 2015 17:34:43 +0200 schreef Hans Bezemer:
>
> > hughaguilar96@gmail.com wrote:
> >> BTW: Some ANS-Forth cruft that I will get rid of in my language, is UNTIL
> >> and AGAIN. All that is needed is BEGIN WHILE REPEAT with any number of
> >> WHILE (including zero, so BEGIN REPEAT does what BEGIN AGAIN currently
> >> does).
> >
> > I like your thinking. That's exactly what I did in 4tH: as many WHILE's as
> > you like (without ugly THEN's) and REPEAT and AGAIN are aliases. I kept
> > UNTIL though, since it is just a "0BRANCH" instead of a "BRANCH"
> > (REPEAT/AGAIN). The idea is not new though. I can remember somebody writing
> > an article on the same thing in FD.
> >
> > I added another construct, which is "DONE". A "DONE" is connected to the
> > last "WHILE" defined and is triggered when that "WHILE" condition fails.
> > E.g.
> >
> > ---8<---
> >: test begin dup while 1- done . done ." Not ready yet!" cr repeat ;
> >
> > 5 test Not ready yet!
> > Not ready yet!
> > Not ready yet!
> > Not ready yet!
> > Not ready yet!
> > 0 ok
> > ---8<---
> >
> > In ANS it is defined as:
> >
> > ---8<---
> >: DONE 1 CS-ROLL POSTPONE ELSE 1 CS-ROLL ; IMMEDIATE
> > ---8<---
> >
> > It is especially handy when the stack is different between several WHILE's,
> > because you can clean it up in specific ways before leaving instead of
> > dumping and dropping useless items on the stack, just to keep it balanced.
> >
> > It is interesting to see what it compiles to (gForth):
> > see test
> >: test
> > BEGIN dup
> > IF 1-
> > ELSE .
> > ELSE .\" Not ready yet!" cr
> > REPEAT
> >
> > or 4tH:
> >
> > 4tH message: No errors at word 11
> > Object size: 11 words
> > String size: 15 chars
> > Variables : 0 cells
> > Strings : 0 chars
> > Reliable : Yes
> >
> > [ 0] branch (11)
> > [ 1] dup (0)
> > [ 2] 0branch (5)
> > [ 3] +literal (-1)
> > [ 4] branch (7)
> > [ 5] . (0)
> > [ 6] branch (10)
> > [ 7] ." (0) Not ready yet!
> > [ 8] cr (0)
> > [ 9] branch (1)
> > [ 10] exit (0)
> >
> > BTW, a single "DONE" is a "NOOP".
> >
> > May be this gives you some extra inspiration! ;-)
> >
> > Hans Bezemer
>
> It's the old multiple ELSE trick:
> .. if .. else .. else .. else .. then ..
> And what's the advantage above
> : test begin dup while 1- ." Not ready yet!" cr repeat . ;
The Beez' code does something (prints the index) for the last iteration, which your code doesn't do.
I don't think I'll add DONE to my language though. Instead, I would provide this word:
: looper ( initial 'toucher -- )
\ the toucher must have this stack frame: index -- new-index continue?
>r begin r@ execute while repeat drop
r> drop ;
The user can then write his own toucher like this:
: beez-example ( index -- new-index continue? )
1- >r
r@ 0= if cr r@ . r> false exit then
cr ." not done yet!" r> true ;
Here is an example usage (tested under VFX):
5 ' beez-example looper
not done yet!
not done yet!
not done yet!
not done yet!
0 ok
LOOPER is more general purpose. The toucher adjusts the index at the beginning, and it does something depending upon what the index is. The example above is pretty simple because there is only one special-case --- the index being zero --- but it is possible to have several special-cases. Also, it is possible to have several ways of adjusting the index --- it can go up or down, and not always by the same amount --- any manner of complexity is possible.
There is a common theme throughout the novice-package: I try to hide iteration as much as possible --- I don't want the programmer to have to use BEGIN loops explicitly at all. I prefer to have the programmer pass the xt of a function into a higher-order function that contains the loop, so the BEGIN or whatever is hidden in the higher-order function --- the fewer explicit loops that there are in the application program, the more readable the application program will be. :-) LOOPER is actually pretty useful --- I think I will add this to the novice-package.
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2015-04-11 15:04 +0200 |
| Message-ID | <55291c00$0$2831$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #38108 |
Coos Haak wrote:
> It's the old multiple ELSE trick:
> .. if .. else .. else .. else .. then ..
>
> And what's the advantage above
> : test begin dup while 1- ." Not ready yet!" cr repeat . ;
NOTHING! Because it only features one WHILE. However, in 4tH it is not
unusual to have multiple WHILEs, e.g.
BEGIN cond1 WHILE cond2 WHILE body REPEAT
As in:
\ reload entire index
: (reload) ( h ix -- h ix n)
dup -> (isiz) @ cells over + (ihead) + >r dup (ihead) +
begin ( h ix ix-body r: ix-top)
refill \ get the next line
while \ if successful
dup r@ < \ check limit
while \ if successful
(number?) 0= >r over ! r> \ save index value
while \ if a positive number
cell+ \ move to next cell
repeat \ until some kind of error occurs
r> drop over (ihead) + - \ leave size ( h ix n)
;
Or:
: (convert) ( a1 n1 n2 -- a2 n3 n4 n5)
0 >r >r \ setup exponent, save accu
begin
over over \ is there any string left?
while \ if so, get digit and compare
c@ [char] 0 - dup 0< over 9 > or 0= r@ (limit) < and
while \ don't cross the cell boundary
r> 10 * + r> 1+ >r >r chop \ shift left, increment exponent
repeat drop r> r> \ drop value, get accu and exponent
;
(Note the neat trick where I use the count at one place and the address in
the next).
In this case I was able to get the stack diagram identical at all the WHILE
parts. But sometimes, you can't. In that case you can use a DONE to correct
it.
Hans Bezemer
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.forth
csiph-web