RfD - N>R and NR>

2 views
Skip to first unread message

Stephen Pelc

unread,
Feb 4, 2009, 12:05:26 PM2/4/09
to
RfD: N>R and NR>
4 February 2009, Stephen Pelc


Rationale
=========

Problem
-------
Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
number of stack items. To prevent interference with other items,
these items are then saved on the return stack. Saving several
items to the return stack is tedious, especially where the number
of items is unknown at compile time.

Current practice
----------------
At least SwiftForth, VFX Forth, spForth, and some versions of
Win32Forth provide the words N>R and NR> with the following
or similar specification.

N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n
Transfer N items and count to the return stack.

NR> \ -- xn..x1 +n ; R: x1 .. xn +n --
\ *G Pull n items and count off the return stack.

These words cannot be written without carnal knowledge of the
underlying Forth.

Approach
--------
At least one system stores items on the return stack in the format
R: -- xn .. x1 n
Because coding of this word is dependent on a number of CPU and Forth
design issues, we do not propose to mandate the order of x1..xn on the
return stack, only to specify that n itself is on the top of the
return
stack.

A consequence of this is that N>R and NR> are used in pairs. I have
not yet seen any code that relies on the order of items on the return
stack, but it could be useful. It should also be noted that by
defining
the order, the ambiguous condition in the proposal can be removed.


Proposal
========
6.2.aaaa N>R
n-to-r CORE EXT

Interpretation: Interpretation semantics for this word are undefined.

Execution: ( x1..xn +n -- ) ( R: -- xn..x1 +n )

Move n+1 items to the return to the return stack such that n is the
top item on the return stack. The order of the items x1..xn on the
return stack is implementation defined.

6.2.bbbb NR>
n-r-from CORE EXT

Interpretation: Interpretation semantics for this word are undefined.

Execution: ( -- xn..x1 n ) ( R: x1..xn n -- )

Move n+1 items from the return stack to the data stack, leaving n on
the
top of the data stack. The order of the items x1..xn on the
return stack is implementation defined.

Ambiguous condition
NR> is used with data not placed on the return stack by N>R.


Reference Implementation
========================
This implementation depends on the return address being on the
return stack.

: N>R \ xn .. x1 N -- ; R: -- x1 .. xn n
\ *G Transfer N items and count to the return stack.
dup \ xn .. x1 N N --
begin
dup
while
rot r> swap >r >r \ xn .. N N -- ; R: .. x1 --
1- \ xn .. N 'N -- ; R: .. x1 --
repeat
drop \ N -- ; R: x1 .. xn --
r> swap >r >r
;

: NR> \ -- xn .. x1 N ; R: x1 .. xn N --
\ *G Pull N items and count off the return stack.
r> r> swap >r dup
begin
dup
while
r> r> swap >r -rot
1-
repeat
drop
;


Tests
=====
TBD


--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

Helmar

unread,
Feb 4, 2009, 12:31:52 PM2/4/09
to
On Feb 4, 12:05 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> RfD: N>R and NR>


I think it's nice. The 4p implementation (-A switch) is:

-------------------
: n>r [ -OPT ] dup begin ?dup while
rot >rr 1-
repeat >rr ;
: nr> [ -OPT ] rr> dup
: (nr>) ?dup and: rr> -rot 1- recurse ;
-------------------

Regards,
-Helmar

Bernd Paysan

unread,
Feb 4, 2009, 12:43:14 PM2/4/09
to
Stephen Pelc wrote:
> N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n
> Transfer N items and count to the return stack.
>
> NR> \ -- xn..x1 +n ; R: x1 .. xn +n --
> \ *G Pull n items and count off the return stack.
>
> These words cannot be written without carnal knowledge of the
> underlying Forth.

Ah, simply make them immediate and let them postpone the loops ;-).

Otherwise I support this proposal, though I must say that I don't like
juggling with a variable number of stack items. In my Audio GUI, I've
created two words to deal with them more easily: [[ and ]]. You can do
something like

[[ get-order ]] ( -- addr )

which packs the complete stack spillout of whatever is between the two
delimiters into memory, returning just one address. This hasn't been well
factored yet (there is only one buffer for it), but that idea could be
improved.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/

Marcel Hendrix

unread,
Feb 4, 2009, 11:54:12 AM2/4/09
to
steph...@mpeforth.com (Stephen Pelc) Re: RfD - N>R and NR>

> Problem
> -------
> Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
> number of stack items. To prevent interference with other items,
> these items are then saved on the return stack. Saving several
> items to the return stack is tedious, especially where the number
> of items is unknown at compile time.

Is this a problem that mandates endless debates and two new
words? What's the frequency of occurance of these N>R NR>
factors?

GET-ORDER and SAVE-INPUT are ANS already, so don't count as examples.
I can find many examples where a large number of items is put on
the return stack ( N>R would help ) but where NR> is not used.

Flabbergasted,

-marcel

Helmar

unread,
Feb 4, 2009, 12:55:02 PM2/4/09
to
On Feb 4, 12:43 pm, Bernd Paysan <bernd.pay...@gmx.de> wrote:
> Stephen Pelc wrote:
> > N>R     \ xn..x1 +n -- ; R: -- x1 .. xn +n
> > Transfer N items and count to the return stack.
>
> > NR>     \ -- xn..x1 +n ; R: x1 .. xn +n --
> > \ *G Pull n items and count off the return stack.
>
> > These words cannot be written without carnal knowledge of the
> > underlying Forth.
>
> Ah, simply make them immediate and let them postpone the loops ;-).
>
> Otherwise I support this proposal, though I must say that I don't like
> juggling with a variable number of stack items. In my Audio GUI, I've
> created two words to deal with them more easily: [[ and ]]. You can do
> something like
>
> [[ get-order ]] ( -- addr )
>
> which packs the complete stack spillout of whatever is between the two
> delimiters into memory, returning just one address. This hasn't been well
> factored yet (there is only one buffer for it), but that idea could be
> improved.

What's the word to restore the thing on stack? You need a third word.

Regards,
-Helmar

Andrew Haley

unread,
Feb 4, 2009, 1:40:27 PM2/4/09
to
Marcel Hendrix <m...@iae.nl> wrote:
> steph...@mpeforth.com (Stephen Pelc) Re: RfD - N>R and NR>

> > Problem
> > -------
> > Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
> > number of stack items. To prevent interference with other items,
> > these items are then saved on the return stack. Saving several
> > items to the return stack is tedious, especially where the number
> > of items is unknown at compile time.

> Is this a problem that mandates endless debates and two new
> words? What's the frequency of occurance of these N>R NR>
> factors?

> GET-ORDER and SAVE-INPUT are ANS already, so don't count as examples.

Why not? Surely

SAVE-INPUT N>R
... stuff ...
NR> RESTORE-INPUT

is an obvious use for these, isn't it?

Andrew.

Coos Haak

unread,
Feb 4, 2009, 1:59:23 PM2/4/09
to
Op Wed, 04 Feb 2009 12:40:27 -0600 schreef Andrew Haley:

I have had this construct for years in INCLUDE-FILE LOAD and EVALUATE ;-)

--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Jonah Thomas

unread,
Feb 4, 2009, 2:05:03 PM2/4/09
to
steph...@mpeforth.com (Stephen Pelc) wrote:

> N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n
> Transfer N items and count to the return stack.
>
> NR> \ -- xn..x1 +n ; R: x1 .. xn +n --
> \ *G Pull n items and count off the return stack.
>
> These words cannot be written without carnal knowledge of the
> underlying Forth.

: N>R
DUP BEGIN
DUP 0 - WHILE
>R 1-
REPEAT
>R
;

This would work if you were using a dummy return stack, that the system
didn't use for anything else. But in general it doesn't work. So:

: N>R
]] DUP BEGIN
DUP 0 - WHILE
ROT >R 1-
REPEAT
DROP >R [[
; IMMEDIATE

: R>N
]] R> DUP BEGIN
DUP 0 - WHILE
R> -ROT 1-
REPEAT
DROP [[
; IMMEDIATE

I believe this ought to work anywhere. But it isn't good. A 13-word
macro (bigger if 0 is a literal) every time you use either one.

Still it could provide a quick patch for a system that doesn't yet have
N>R and R>N .

]] parses the input and postponse everything, providing literals for
numbers. It quits when it finds [[ . You could get about the same result
by potting POSTPONE in front of every word between ]] and [[ . It would
look worse then. The 0 might need to become 0 POSTPONE LITERAL .

Coos Haak

unread,
Feb 4, 2009, 2:19:30 PM2/4/09
to
Op Wed, 4 Feb 2009 14:05:03 -0500 schreef Jonah Thomas:

> steph...@mpeforth.com (Stephen Pelc) wrote:
>
>> N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n
>> Transfer N items and count to the return stack.
>>
>> NR> \ -- xn..x1 +n ; R: x1 .. xn +n --
>> \ *G Pull n items and count off the return stack.
>>
>> These words cannot be written without carnal knowledge of the
>> underlying Forth.
>
>: N>R
> DUP BEGIN
> DUP 0 - WHILE

Why the '0 -' construct? You might do '0<>' but I would skip it ;-)

Andrew Haley

unread,
Feb 4, 2009, 2:44:20 PM2/4/09
to
Jonah Thomas <jeth...@gmail.com> wrote:
> steph...@mpeforth.com (Stephen Pelc) wrote:

> > N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n
> > Transfer N items and count to the return stack.
> >
> > NR> \ -- xn..x1 +n ; R: x1 .. xn +n --
> > \ *G Pull n items and count off the return stack.
> >
> > These words cannot be written without carnal knowledge of the
> > underlying Forth.

> : N>R
> DUP BEGIN
> DUP 0 - WHILE
> >R 1-
> REPEAT
> >R
> ;

> This would work if you were using a dummy return stack, that the system
> didn't use for anything else. But in general it doesn't work. So:

> : N>R
> ]] DUP BEGIN
> DUP 0 - WHILE
> ROT >R 1-
> REPEAT
> DROP >R [[
> ; IMMEDIATE

Surely it's just

]] begin ?dup while swap >r 1- repeat [[

Andrew.

Bernd Paysan

unread,
Feb 4, 2009, 2:42:48 PM2/4/09
to
Helmar wrote:
>> [[ get-order ]] ( -- addr )
>>
>> which packs the complete stack spillout of whatever is between the two
>> delimiters into memory, returning just one address. This hasn't been well
>> factored yet (there is only one buffer for it), but that idea could be
>> improved.
>
> What's the word to restore the thing on stack? You need a third word.

Yes, the word is @s (could also be "unpack" if something more readable is
necessary). I've several *s words which all do the same as the non-s words
but with these packed arrays. MAP is not a good solution, because these *s
words make use of the knowledge that this is a regular structure.

Jonah Thomas

unread,
Feb 4, 2009, 3:58:56 PM2/4/09
to
Andrew Haley <andr...@littlepinkcloud.invalid> wrote:
> Jonah Thomas <jeth...@gmail.com> wrote:

> > : N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n

> > ]] DUP BEGIN
> > DUP 0 - WHILE
> > ROT >R 1-
> > REPEAT
> > DROP >R [[
> > ; IMMEDIATE
>
> Surely it's just
>
> ]] begin ?dup while swap >r 1- repeat [[

The complications come because we need to save the count at the top of
the return stack.

Jonah Thomas

unread,
Feb 4, 2009, 4:00:12 PM2/4/09
to
Coos Haak <chf...@hccnet.nl> wrote:
> schreef Jonah Thomas:

> >: N>R
> > DUP BEGIN
> > DUP 0 - WHILE

> Why the '0 -' construct? You might do '0<>' but I would skip it ;-)

You're right. I simply missed that for no obvious reason.

Marcel Hendrix

unread,
Feb 4, 2009, 3:03:13 PM2/4/09
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes Re: RfD - N>R and NR>

> Marcel Hendrix <m...@iae.nl> wrote:
>> steph...@mpeforth.com (Stephen Pelc) Re: RfD - N>R and NR>

>> > Problem
>> > -------
>> > Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
>> > number of stack items.

[..]


>> GET-ORDER and SAVE-INPUT are ANS already, so don't count as examples.

> Why not?
[..]

Sorry, I overlooked the crucial "variable number of". I can't find
a variable number of args in my sources, nor a reason why that should
be portable, but I have a sudden insight where this is going :-)

Splendid idea!

-marcel

Alex McDonald

unread,
Feb 4, 2009, 5:01:06 PM2/4/09
to
> Stephen Pelc, stephen...@mpeforth.com

> MicroProcessor Engineering Ltd - More Real, Less Time
> 133 Hill Lane, Southampton SO15 5AF, England
> tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
> web:http://www.mpeforth.com- free VFX Forth downloads

Seconded (if that's the right thing to do). Later versions of
Win32Forth have both N>R and NR> as you note, and although
infrequently used, very useful.

--
Regards
Alex McDonald

Andrew Haley

unread,
Feb 5, 2009, 11:00:47 AM2/5/09
to

Oh duh, I didn't read the rfd properly. Sorry.

Andrew.

Bee

unread,
Feb 5, 2009, 11:40:57 AM2/5/09
to
On Feb 4, 9:05 am, stephen...@mpeforth.com (Stephen Pelc) wrote:
> RfD: N>R and NR>
> 4 February 2009, Stephen Pelc
>
> Rationale
> =========
>
> Problem
> -------
> Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
> number of stack items. To prevent interference with other items,
> these items are then saved on the return stack. Saving several
> items to the return stack is tedious, especially where the number
> of items is unknown at compile time.

Search order can be modified without the need for the words N>R and
NR>. Please note: I am not saying anything about the usefulness of N>R
and NR>.

The following work with Swiftforth and gforth.

: _-ORDER ( w wid*n n -- wid*n w n ) ( internal word )
DUP IF 1- SWAP >R ( >>> ) RECURSE ( <<< ) ( wid*n w n )
OVER R@ XOR IF 1+ R> -ROT ( >>> ) EXIT ( <<< )
THEN R> DROP THEN ;

I would like propose these words as reserved:

: -ORDER ( wid -- ) ( remove wid from search order )
GET-ORDER _-ORDER NIP SET-ORDER ;

: +ORDER ( wid -- ) ( add wid to search order, only one instance )
DUP >R -ORDER GET-ORDER R> SWAP 1+ SET-ORDER ;

--
Bill Muench
Santa Cruz, California

Helmar

unread,
Feb 5, 2009, 12:04:00 PM2/5/09
to

I guess you missed the point. The +ORDER -ORDER things are worth an
own RfD imho and they should be in a standard.
The point here is to preserve such an arbitrary state as the search
order on stack and for needs of application move that runtime-known
number of items to the return stack and move it back later. That is
just for convenience - you do not always know (bad design btw.), how
many items should be preserved before something like GET-ORDER - eg:

: FOO ... >R >R GET-ORDER R> R> ... SET-ORDER ... ;

So I guess the words are very useful - beside other possibilities to
set the search order.

Regards,
-Helmar

Stephen Pelc

unread,
Feb 5, 2009, 2:07:00 PM2/5/09
to
On Thu, 5 Feb 2009 09:04:00 -0800 (PST), Helmar <hel...@gmail.com>
wrote:

>The point here is to preserve such an arbitrary state as the search
>order on stack and for needs of application move that runtime-known
>number of items to the return stack and move it back later. That is
>just for convenience - you do not always know (bad design btw.),

For words like SAVE-INPUT, you know the number of items on *your*
system, but you don't know on how many on other systems. N>R
eases portability in these cases.

On some systems, SAVE-INPUT is entitled to vary the number of
items according to the conditions, e.g. terminal or file. N>R
and NR> cope with this situation.

Stephen

Bernd Paysan

unread,
Feb 6, 2009, 6:53:25 AM2/6/09
to
Stephen Pelc wrote:
> For words like SAVE-INPUT, you know the number of items on *your*
> system, but you don't know on how many on other systems. N>R
> eases portability in these cases.

Indeed. However, last time we redesigned the source input system of Gforth,
we just went the route to have an object oriented input buffer, which
contains all necessary variables plus the buffer space, so it ends up as a
single pointer, whatever the current input is. This takes the insanity of
variable length stack effects out of the equation.

Jonah Thomas

unread,
Feb 6, 2009, 12:45:21 PM2/6/09
to
Bernd Paysan <bernd....@gmx.de> wrote:

> However, last time we redesigned the source input system of Gforth,
> we just went the route to have an object oriented input buffer, which
> contains all necessary variables plus the buffer space, so it ends up
> as a single pointer, whatever the current input is. This takes the
> insanity of variable length stack effects out of the equation.

So for source inputs it makes sense to keep the data in data structures.
You don't have a large number of input specifications and they're
reasonably stable. Not like you were dealing with many thousands of
types with variable length data, that were created and destroyed
quickly. Even in that case you could put them in allocated memory and
remember to free the memory at the correct times.

Are there times when it makes sense to use the ( xn ... x1 n -- )
( -- xn ... x1 n ) form?

If so you might sometimes want to move things onto the return stack and
sometimes elsewhere. It might be good to arrange that flexibly.

Would it be easier to have the length at both ends? ( n xn ... x1 n -- )

I just recently saw a Forth word that started with ( xn ... x1 n ) and
it bubbled the n through a whole stack so the n would be available at
the end. It could have been saved in a variable or a local ... but if
it's already sitting at both ends then everything turns simple while you
move it around on stacks. Like a railroad train with engines facing
opposite directions at either end.

You'd have to drop it when the data was consumed, but it's easier to
DROP something you don't need than to juggle something you do.

: N->R' ( n xn ... x1 n -- ) ( R: -- n x1 ... xn n )
]] DUP 1+ 1+ BEGIN ?DUP WHILE SWAP >R 1- REPEAT [[ ; IMMEDIATE

: R->N' ( -- n x1 ... xn n ) ( R: n xn ... x1 n -- )
]] R@ 1+ 1+ BEGIN ?DUP WHILE R> SWAP 1- REPEAT [[ ; IMMEDIATE

It's half-baked. I haven't used variable-length stack trains enough to
guess whether the simplicity you get this way is worth the complexity of
removing the extra item when you no longer want it.

And it's no help for the guy who writes it in C or assembly, who can
just move the return stack pointer by n+1 cells, move the nest-sys to
its new spot, move the n just under the nest-sys, move the data just
under that, and reset the data stack pointer to delete the data there.

m_l_g3

unread,
Feb 7, 2009, 6:13:32 PM2/7/09
to
On Feb 5, 1:01 am, Alex McDonald <b...@rivadpm.com> wrote:
> On Feb 4, 5:05 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> > RfD: N>R and NR>
> > 4 February 2009, Stephen Pelc
>
> > Rationale
> > =========
>
> > Problem
> > -------
> > Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
> > number of stack items. To prevent interference with other items,
> > these items are then saved on the return stack. Saving several
> > items to the return stack is tedious, especially where the number
> > of items is unknown at compile time.
>
> > Current practice
> > ----------------
> > At least SwiftForth, VFX Forth, spForth, and some versions of
> > Win32Forth provide the words N>R and NR> with the following
> > or similar specification.
>
> > N>R     \ xn..x1 +n -- ; R: -- x1 .. xn +n
> > Transfer N items and count to the return stack.
>
> > NR>     \ -- xn..x1 +n ; R: x1 .. xn +n --
> > \ *G Pull n items and count off the return stack.
>
> > These words cannot be written without carnal knowledge of the
> > underlying Forth.
>
<snip>
> > Stephen Pelc, stephen...@mpeforth.com

>
> Seconded (if that's the right thing to do). Later versions of
> Win32Forth have both N>R and NR> as you note, and although
> infrequently used, very useful.
>
> --
> Regards
> Alex McDonald

Me too.

This word is very useful if you write a compiler or some compiler
extension(s).
In application code these words are not needed provided that the
programmer
avoids the use of ( xn .. x1 n ) arrays on the stack.

I would also prefer to have NDROP in addition to these words,
but that's definitely a different proposal.

I never used N>R like ( x y z ) 3 N>R R> DROP or 3 >R NR> DROP ( x y
z ).

Michael L Gassanenko

m_l_g3

unread,
Feb 7, 2009, 6:23:08 PM2/7/09
to
On Feb 5, 10:07 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Thu, 5 Feb 2009 09:04:00 -0800 (PST), Helmar <hel...@gmail.com>
> wrote:
>
> >The point here is to preserve such an arbitrary state as the search
> >order on stack and for needs of application move that runtime-known
> >number of items to the return stack and move it back later. That is
> >just for convenience - you do not always know (bad design btw.),
>
> For words like SAVE-INPUT, you know the number of items on *your*
> system, but you don't know on how many on other systems. N>R
> eases portability in these cases.
>

That number of items is known only up to the moment that someone
decides to *change* the number of items. At that moment everybody
involved will find out that N>R and NR> either _are_ or _would_be_
very useful.

Jonah Thomas

unread,
Feb 7, 2009, 7:58:10 PM2/7/09
to
m_l_g3 <m_l...@yahoo.com> wrote:

> stephen...@mpeforth.com (Stephen Pelc) wrote:
> > Helmar <hel...@gmail.com> wrote:
> >
> > >The point here is to preserve such an arbitrary state as the search
> > >order on stack and for needs of application move that runtime-known
> > >number of items to the return stack and move it back later. That is
> > >just for convenience - you do not always know (bad design btw.),
> >
> > For words like SAVE-INPUT, you know the number of items on *your*
> > system, but you don't know on how many on other systems. N>R
> > eases portability in these cases.
>
> That number of items is known only up to the moment that someone
> decides to *change* the number of items. At that moment everybody
> involved will find out that N>R and NR> either _are_ or _would_be_
> very useful.

The return stack is good because you can do re-entrant code etc, and
whatever else you do, when you get back to the code that did N>R the
data will be waiting on the return stack for NR> . But on some systems
the return stack is shallow, and sometimes you might want to access that
data from other code.

How about a word to move the top n datastack items to a location in
memory in reverse order?

Would that be useful too?

If you could do that simply, you could move to an existing buffer, or
create a new buffer on the spot with ALLOT or ALLOCATE .

Maybe call the words N! and N@? Or are those taken in common use, I
don't remember....

You could define them in high-level Forth but they'd be much more
elegant under-the-hood.

N@ ( addr -- xn ... x1 n )
N! ( xn ... x1 addr n -- )

Under-the-hood, you might do something like

: N@ ( addr -- xn ... x1 )
DUP @ CELLS DUP >R
SP -ROT MOVE
R> SP +! ;

: N! ( xn ... x1 addr n -- )
TUCK 1+ CELLS SP OVER +
SP SWAP MOVE ;

\ does SP point to the lowest in-use cell of the data stack?

But you'd want to do it in CODE or a different atomic task or something
so you wouldn't clobber the data stack while you were changing it. If
your system lets MOVE move data faster than a do loop with repeated @ or
! then this approach should be better.

> > On some systems, SAVE-INPUT is entitled to vary the number of
> > items according to the conditions, e.g. terminal or file. N>R
> > and NR> cope with this situation.

A lot of times it might be simpler to just save space for the maximum
size plus the count. You lose a little space but you save complexity.

But if you sometimes have a *whole lot* of items then it costs too much.

Coos Haak

unread,
Feb 7, 2009, 8:22:35 PM2/7/09
to
Op Sat, 7 Feb 2009 15:13:32 -0800 (PST) schreef m_l_g3:

<snip>


> This word is very useful if you write a compiler or some compiler
> extension(s).
> In application code these words are not needed provided that the
> programmer
> avoids the use of ( xn .. x1 n ) arrays on the stack.
>
> I would also prefer to have NDROP in addition to these words,
> but that's definitely a different proposal.
>
> I never used N>R like ( x y z ) 3 N>R R> DROP or 3 >R NR> DROP ( x y
> z ).
>

As a matter of fact, the names N>R and NR> I use for them,
I saw first in a posting from you in c.l.f. in about 1998 ;-)
Before that I used weird names like PUSH-DATA and POP-DATA.

The Beez'

unread,
Feb 8, 2009, 12:36:38 PM2/8/09
to
On Feb 8, 2:22 am, Coos Haak <chfo...@hccnet.nl> wrote:
Just for the record, I have no objection whatsoever concerning with
this RfD. If it is chosen to be adopted, I will provide the reference
implementation as an include file.

Hans Bezemer

rickman

unread,
Feb 9, 2009, 2:50:23 AM2/9/09
to
On Feb 4, 12:05 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
>
> These words cannot be written without carnal knowledge of the
> underlying Forth.

I'm pretty far from a prude, but is this really an appropriate use of
the above term? I thought maybe it had a definition other than
sexual, but I can't find one. Did I not look far enough?

I do believe I understand what you meant, but I think I would have
found another term myself.

Rick

PS This reminds me of a female technician who objected to the use of
the terms "male" and "female" for connectors. I guess I can
understand that one though. Those terms actually derive from the
images of... well you know... 8^o Good thing she didn't have to
work with plumbing where they have "nipples" on pipes.

Elizabeth D Rather

unread,
Feb 9, 2009, 1:39:42 PM2/9/09
to
rickman wrote:
> On Feb 4, 12:05 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
>> These words cannot be written without carnal knowledge of the
>> underlying Forth.
>
> I'm pretty far from a prude, but is this really an appropriate use of
> the above term? I thought maybe it had a definition other than
> sexual, but I can't find one. Did I not look far enough?
>
> I do believe I understand what you meant, but I think I would have
> found another term myself.
>
> Rick

AFAIK the term (as far as Forth relevance is concerned) developed during
discussions in the Forth94 process. We needed a term to designate
functions that couldn't be implemented without knowledge of and
dependence on implementation details such as dictionary structure, head
geography, etc. Someone started saying "kernel knowledge", and since
the movie "Carnal Knowledge" had recently been popular it was an obvious
pun which stuck. I don't know if it's used in any other
computer-related context.

I'm sorry if it offends you, and hope this explanation helps.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

Coos Haak

unread,
Feb 9, 2009, 1:54:53 PM2/9/09
to
Op Sat, 7 Feb 2009 19:58:10 -0500 schreef Jonah Thomas:

<snip>

> Maybe call the words N! and N@? Or are those taken in common use, I
> don't remember....
>
> You could define them in high-level Forth but they'd be much more
> elegant under-the-hood.
>
> N@ ( addr -- xn ... x1 n )
> N! ( xn ... x1 addr n -- )

Why not ( xn .. x1 n addr -- ) to make it analogous to ! and 2!
that have addr on top of the stack.

rickman

unread,
Feb 9, 2009, 10:54:51 PM2/9/09
to
On Feb 9, 1:39 pm, Elizabeth D Rather <erat...@forth.com> wrote:
> rickman wrote:
> > On Feb 4, 12:05 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> >> These words cannot be written without carnal knowledge of the
> >> underlying Forth.
>
> > I'm pretty far from a prude, but is this really an appropriate use of
> > the above term? I thought maybe it had a definition other than
> > sexual, but I can't find one. Did I not look far enough?
>
> > I do believe I understand what you meant, but I think I would have
> > found another term myself.
>
> > Rick
>
> AFAIK the term (as far as Forth relevance is concerned) developed during
> discussions in the Forth94 process. We needed a term to designate
> functions that couldn't be implemented without knowledge of and
> dependence on implementation details such as dictionary structure, head
> geography, etc. Someone started saying "kernel knowledge", and since
> the movie "Carnal Knowledge" had recently been popular it was an obvious
> pun which stuck. I don't know if it's used in any other
> computer-related context.
>
> I'm sorry if it offends you, and hope this explanation helps.

I's not that it offends me... I am not offended easily at all. But I
work and live by the mores of the community. I am sure that 99% of
the people I know would not blink an eye about this. But in case that
1% includes a customer, I can't take a chance of offending. This is a
term I will be avoiding.

It reminds me of a job I had where we were teamed with General
Dynamics. They even referred to themselves as GD. But you *had* to
keep a straight face when you said that, although there were plenty of
times when people wanted to use the term differently.

Rick

Alex McDonald

unread,
Feb 10, 2009, 7:58:59 AM2/10/09
to
> Rick- Hide quoted text -
>
> - Show quoted text -

GD?

I know it helps not to be offensive where possible, but honestly; this
is taking things too far. GD? What's wrong with that?

"He cocked his weapon and shot at the tits at the bottom of the black
bush". There; pick the rude ones out of that. Six? Possible 7 if using
"he" might be considered sexist? 8 with a racist reference?

Language has a context, and anyone who objects to language that might
have the slightest sexist, racist or other-ist overtones *in some
other context* has more on their minds than just the job in hand. O
bother, there I go again...

--
Regards
Alex McDonald

rickman

unread,
Feb 10, 2009, 12:37:47 PM2/10/09
to

Exactly, context is what it is all about. That is why it was
important to not let any other context show when saying GD, TO GD.
That was the problem. We used GD in totally different context when
they weren't there to hear it.

That reminds me of the Chevy Chase Family Vacation movie where they
visited Hoover Dam and got the tour of the Dam gift shop and the Dam
this and the Dam that...

My original point is that unless you are in bed with the Forth
community, you could easily not understand the context of "carnal
knowledge", especially since there is no formal meaning other than the
sexual one, (pun intended). I just think this is a poor choice of
term. I have any number of contacts with whom I would not use that
term. You never know about Colonels and Generals. They can dislike
one thing you say and you are off the project without ever knowing
why.

Rick

Jerry Avins

unread,
Feb 10, 2009, 12:48:18 PM2/10/09
to

Someone not accustomed to "carnal knowledge" in its Forth use would
likely need to have it explained anyway, so it's best avoided with your
clients anyway. "Deeply intimate knowledge if the internals"?

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

rickman

unread,
Feb 10, 2009, 1:16:26 PM2/10/09
to

That's a good rationalization. "If you need to ask, you shouldn't
know anyway."

Rick

Alex McDonald

unread,
Feb 10, 2009, 2:45:38 PM2/10/09
to

I still don't get this GD thing. Can you explain it for me (without
upsetting the regulars here, of course).

--
Regards in mystification
Alex McDonald

Jerry Avins

unread,
Feb 10, 2009, 2:55:22 PM2/10/09
to
rickman wrote:

...

>> Someone not accustomed to "carnal knowledge" in its Forth use would
>> likely need to have it explained anyway, so it's best avoided with your
>> clients anyway. "Deeply intimate knowledge if the internals"?
>
> That's a good rationalization. "If you need to ask, you shouldn't
> know anyway."

Barking up wrong tree. "If you need it explained, it's a poor joke."

rickman

unread,
Feb 10, 2009, 11:35:26 PM2/10/09
to

I have to say I never heard this when I was a kid. It was much later
that I heard people say GD instead of saying the words out loud G_d
D_mn. Is that any more clear? I guess when I was a kid no one
abbreviated things like this. Rather than trying to shield me from
words like this, it was more a matter of "do as I say, not as I do".

Rick

Alex McDonald

unread,
Feb 11, 2009, 11:34:52 AM2/11/09
to


What!?!?!

That is some stretch, and if the radius of pollution from the original
is that large, we're all doomed to insult or upset our over-sensitive
neighbours.

Thankfully, I live in a different place. Here we're agreed that the
word "feck", which sounds very much like the English F word, is not
offensive. It's an ordinary Scots/Irish word; to feck something means
to steal it, not to sexually assault it.

So we haven't banned it, regardless of the fact that to the average
English (or American?) ear it sounds very offensive. And we haven't
bowlderised it to the point where the example of GD now has the
meaning of God Damn, and even the word God must get underscore. For
that I'm grateful.

And thanks for explaining.

--
Regards
Alex McDonald

Stephen Pelc

unread,
Feb 11, 2009, 1:29:20 PM2/11/09
to
On Sun, 8 Feb 2009 23:50:23 -0800 (PST), rickman <gnu...@gmail.com>
wrote:

>I'm pretty far from a prude, but is this really an appropriate use of
>the above term? I thought maybe it had a definition other than
>sexual, but I can't find one. Did I not look far enough?

According to Chambers (1972):
adj, fleshly; sensual; unspiritual; bodily; sexual; murderous,
flesh-eating (Shak.)

An even older Shorter Oxford confirms these,

These seem relevant to my intended meaning, or do I need a new
dictionary?

Elizabeth D Rather

unread,
Feb 11, 2009, 1:45:09 PM2/11/09
to
Stephen Pelc wrote:
> On Sun, 8 Feb 2009 23:50:23 -0800 (PST), rickman <gnu...@gmail.com>
> wrote:
>
>> I'm pretty far from a prude, but is this really an appropriate use of
>> the above term? I thought maybe it had a definition other than
>> sexual, but I can't find one. Did I not look far enough?
>
> According to Chambers (1972):
> adj, fleshly; sensual; unspiritual; bodily; sexual; murderous,
> flesh-eating (Shak.)
>
> An even older Shorter Oxford confirms these,
>
> These seem relevant to my intended meaning, or do I need a new
> dictionary?
>
> Stephen
>

I particularly like the "murderous, flesh-eating" part.

Anton Ertl

unread,
Feb 12, 2009, 11:48:02 AM2/12/09
to
steph...@mpeforth.com (Stephen Pelc) writes:
>RfD: N>R and NR>
>4 February 2009, Stephen Pelc
>
>
>Rationale
>=========
>
>Problem
>-------
>Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
>number of stack items. To prevent interference with other items,
>these items are then saved on the return stack. Saving several
>items to the return stack is tedious, especially where the number
>of items is unknown at compile time.
>
>Current practice
>----------------
>At least SwiftForth, VFX Forth, spForth, and some versions of
>Win32Forth provide the words N>R and NR> with the following
>or similar specification.
>
>N>R \ xn..x1 +n -- ; R: -- x1 .. xn +n
>Transfer N items and count to the return stack.
>
>NR> \ -- xn..x1 +n ; R: x1 .. xn +n --
>\ *G Pull n items and count off the return stack.
>
>These words cannot be written without carnal knowledge of the
>underlying Forth.

Since you explicitly undefine the interpretation semantics, they can
be written in standard Forth (as macros).

Usage statistics for these words would be helpful.

In general I feel that these words should not be used, so I am not
very excited about them being standardized. OTOH, if that many
systems have them, there seems to be common practice, so we might as
well standardize them.

>Approach
>--------
>At least one system stores items on the return stack in the format
> R: -- xn .. x1 n
>Because coding of this word is dependent on a number of CPU and Forth
>design issues, we do not propose to mandate the order of x1..xn on the
>return stack, only to specify that n itself is on the top of the
>return
>stack.

The only use of the latter requirement would be to access stuff on the
return stack below the x1..xn. Does anybody do this? OTOH, given
that all implementations probably do it that way anyway, we can just
as well standardize it.

>A consequence of this is that N>R and NR> are used in pairs. I have
>not yet seen any code that relies on the order of items on the return
>stack, but it could be useful. It should also be noted that by
>defining
>the order, the ambiguous condition in the proposal can be removed.

That sounds like a rationale for mandating the order. Decide on which
way you want to go, and then leave the other paragraph away (or
rewrite it to say why you decided against it, not why you go for it).
Is there a difference in the order between the current
implementations?

Hmm, I see that there would be a difference between implementations
that use a sequence of >Rs, and implementations that transfer the
items with MOVE or somesuch.

>Proposal
>========
>6.2.aaaa N>R
>n-to-r CORE EXT
>
>Interpretation: Interpretation semantics for this word are undefined.
>
>Execution: ( x1..xn +n -- ) ( R: -- xn..x1 +n )
>
>Move n+1 items to the return to the return stack such that n is the
>top item on the return stack. The order of the items x1..xn on the
>return stack is implementation defined.

Given the last sentence, you should probably specify the stuff on the
return stack as "x1..xn +n" (also for NR>). Why +n and not u?

>
>6.2.bbbb NR>
>n-r-from CORE EXT
>
>Interpretation: Interpretation semantics for this word are undefined.
>
>Execution: ( -- xn..x1 n ) ( R: x1..xn n -- )

Why n, not +n or u?

>Tests
>=====
>TBD

Indeed.

- 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: http://www.forth200x.org/forth200x.html

Elizabeth D Rather

unread,
Feb 12, 2009, 1:25:08 PM2/12/09
to
Anton Ertl wrote:
> steph...@mpeforth.com (Stephen Pelc) writes:
...

> Usage statistics for these words would be helpful.
>
> In general I feel that these words should not be used, so I am not
> very excited about them being standardized. OTOH, if that many
> systems have them, there seems to be common practice, so we might as
> well standardize them.

IMO TOOLS EXT would be a more appropriate place than CORE EXT. Many
people regard CORE EXT as more mandatory, although technically that's
not true.

>> Approach
>> --------
>> At least one system stores items on the return stack in the format
>> R: -- xn .. x1 n
>> Because coding of this word is dependent on a number of CPU and Forth
>> design issues, we do not propose to mandate the order of x1..xn on the
>> return stack, only to specify that n itself is on the top of the
>> return
>> stack.
>
> The only use of the latter requirement would be to access stuff on the
> return stack below the x1..xn. Does anybody do this? OTOH, given
> that all implementations probably do it that way anyway, we can just
> as well standardize it.
>
>> A consequence of this is that N>R and NR> are used in pairs. I have
>> not yet seen any code that relies on the order of items on the return
>> stack, but it could be useful. It should also be noted that by
>> defining
>> the order, the ambiguous condition in the proposal can be removed.
>
> That sounds like a rationale for mandating the order. Decide on which
> way you want to go, and then leave the other paragraph away (or
> rewrite it to say why you decided against it, not why you go for it).
> Is there a difference in the order between the current
> implementations?

So long as the order coming off matches the order going on, I don't see
a need to mandate how the items are stored on the return stack. But
isn't it likely that folks will implement it the same way? In which
case, specifying the order does no harm. Surveying all the existing
implementations that Stephen cites in his proposal would give you an
answer: if they're all the same, may as well specify it. Otherwise, not.

Gerry

unread,
Feb 13, 2009, 7:27:18 AM2/13/09
to
Stephen Pelc wrote:
> RfD: N>R and NR>

[...]

> Proposal
> ========
> 6.2.aaaa N>R
> n-to-r CORE EXT
>
> Interpretation: Interpretation semantics for this word are undefined.
>
> Execution: ( x1..xn +n -- ) ( R: -- xn..x1 +n )
>
> Move n+1 items to the return to the return stack such that n is the
> top item on the return stack. The order of the items x1..xn on the
> return stack is implementation defined.
>

Given that 2>R and 2R> do mandate the order on which the items are
placed on the return stack, surely this is introducing an unnecessary
inconsistency. I much prefer that the order be mandated and that it be
kept the same as the data stack i.e.

Execution ( xn ... x1 +n -- ) ( R: -- xn ...x1 +n )

so that 2 N>R has the same effect as 2>R 2 >R

Also I can see a use for NR@, why not include this in the RfD?

[...]

Gerry

Stephen Pelc

unread,
Feb 13, 2009, 8:14:48 AM2/13/09
to
On Fri, 13 Feb 2009 12:27:18 -0000, "Gerry"
<ge...@jackson9000.fsnet.co.uk> wrote:

>Given that 2>R and 2R> do mandate the order on which the items are
>placed on the return stack, surely this is introducing an unnecessary
>inconsistency. I much prefer that the order be mandated and that it be
>kept the same as the data stack i.e.

It's a matter of current practice. Of the systems I scanned, at least
two perform the operation by repeated pushes, and one performs a block
move, leading to different stack orders. By *not* mandating order,
there's no code breakage.

>Also I can see a use for NR@, why not include this in the RfD?

A scan of ten Forth systems shows no existence of NR@.


Anton said:
>Given the last sentence, you should probably specify the stuff on the
>return stack as "x1..xn +n" (also for NR>). Why +n and not u?

Apart from the IntellaSys chips, I cannot imagine a Forth system
of bit width n for which pushing 2^(n-1) items on the return stack
causes anything other than a crash!

Anton Ertl

unread,
Feb 13, 2009, 9:15:02 AM2/13/09
to
steph...@mpeforth.com (Stephen Pelc) writes:
>On Fri, 13 Feb 2009 12:27:18 -0000, "Gerry"
><ge...@jackson9000.fsnet.co.uk> wrote:
>
>>Given that 2>R and 2R> do mandate the order on which the items are
>>placed on the return stack, surely this is introducing an unnecessary
>>inconsistency. I much prefer that the order be mandated and that it be
>>kept the same as the data stack i.e.
>
>It's a matter of current practice. Of the systems I scanned, at least
>two perform the operation by repeated pushes, and one performs a block
>move, leading to different stack orders.

That's a good reason not to mandate the order, and I don't see a
strong reason to the contrary.

>Anton said:
>>Given the last sentence, you should probably specify the stuff on the
>>return stack as "x1..xn +n" (also for NR>). Why +n and not u?
>
>Apart from the IntellaSys chips, I cannot imagine a Forth system
>of bit width n for which pushing 2^(n-1) items on the return stack
>causes anything other than a crash!

A system with 16-bit cells on a machine with more memory would fit
(e.g. on a 68000), but that's a pretty theoretical issue. The main I
see for using u here is for consistency with other counts; these are
typically "u" even though exceeding the range of "+n" is unrealistic,
impossible or ambiguous; a very appropriate example in this context is
PICK. My impression is that "+n" is typically used where some systems
might treat it is n and others as u.

Jerry Avins

unread,
Feb 13, 2009, 10:06:32 AM2/13/09
to
Gerry wrote:
> Stephen Pelc wrote:
>> RfD: N>R and NR>
>
> [...]
>
>> Proposal
>> ========
>> 6.2.aaaa N>R
>> n-to-r CORE EXT
>>
>> Interpretation: Interpretation semantics for this word are undefined.
>>
>> Execution: ( x1..xn +n -- ) ( R: -- xn..x1 +n )
>>
>> Move n+1 items to the return to the return stack such that n is the
>> top item on the return stack. The order of the items x1..xn on the
>> return stack is implementation defined.
>>
>
> Given that 2>R and 2R> do mandate the order on which the items are
> placed on the return stack, surely this is introducing an unnecessary
> inconsistency. I much prefer that the order be mandated and that it be
> kept the same as the data stack i.e.

Implementation is easier if the order is reversed.

...

Gerry

unread,
Feb 14, 2009, 2:56:32 AM2/14/09
to
Jerry Avins wrote:
> Gerry wrote:
>> Stephen Pelc wrote:
>>> RfD: N>R and NR>
>>
>> [...]
>>
>>> Proposal
>>> ========
>>> 6.2.aaaa N>R
>>> n-to-r CORE EXT
>>>
>>> Interpretation: Interpretation semantics for this word are
>>> undefined. Execution: ( x1..xn +n -- ) ( R: -- xn..x1 +n )
>>>
>>> Move n+1 items to the return to the return stack such that n is the
>>> top item on the return stack. The order of the items x1..xn on the
>>> return stack is implementation defined.
>>>
>>
>> Given that 2>R and 2R> do mandate the order on which the items are
>> placed on the return stack, surely this is introducing an unnecessary
>> inconsistency. I much prefer that the order be mandated and that it
>> be kept the same as the data stack i.e.
>
> Implementation is easier if the order is reversed.
>

Only if N>R is implemented as a series of >Rs, otherwisse there is little
in it.

Gerry


rickman

unread,
Feb 14, 2009, 4:10:37 AM2/14/09
to

From your reply, I'm still not clear that you understand the
situation. In context GD is very clear what you mean. But if you are
tossing GD around all day talking about the company you are teaming
with, when they do something you don't like it was very easy to use GD
in a different context, sometimes to very humorous result. But we had
to be careful not to make those sorts of cracks in front of GD, in a
professional setting it would be very embarrassing. Sort of like
calling someone dick who's name is Dick. It's all in how you say it!

Rick... careful!

Bruce McFarling

unread,
Feb 14, 2009, 9:32:32 AM2/14/09
to
On Feb 14, 2:56 am, "Gerry" <ge...@jackson9000.fsnet.co.uk> wrote:
> Only if N>R is implemented as a series of >Rs, otherwise there is little in it.

If implemented using a block move operation on a slow processor, if
the data stack and return stack are parallel structures, the block
will end up in the same order, while on the same processor if the data
stack and return stack are facing stacks, the block move will reverse
the order.

So best for it to be opaque, as specified.

Ed

unread,
Mar 8, 2009, 9:32:16 PM3/8/09
to
Marcel Hendrix wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes Re: RfD - N>R and NR>
>
> > Marcel Hendrix <m...@iae.nl> wrote:
> >> steph...@mpeforth.com (Stephen Pelc) Re: RfD - N>R and NR>

>
> >> > Problem
> >> > -------
> >> > Several ANS words, e.g. GET-ORDER and SAVE-INPUT, return a variable
> >> > number of stack items.
> [..]
> >> GET-ORDER and SAVE-INPUT are ANS already, so don't count as examples.
>
> > Why not?
> [..]
>
> Sorry, I overlooked the crucial "variable number of". I can't find
> a variable number of args in my sources, nor a reason why that should
> be portable, but I have a sudden insight where this is going :-)
>
> Splendid idea!

There is something inherently wrong (and unforth-like) with pushing
a large number of items to the data stack, only to then push them to
the return stack. It's what one does in desperation.

From what one sees N>R and NR> main use has been as a patch for
SAVE/RESTORE-INPUT. These latter functions shouldn't have
been specified to use the data stack if it was only going to get in the
way. It's not as if a standard program can do anything with the items
while they're on the data stack. Better to tackle the underlying
problem rather than focus on work-arounds.

Jonah Thomas

unread,
Mar 9, 2009, 12:57:35 AM3/9/09
to
"Ed" <nos...@invalid.com> wrote:

> There is something inherently wrong (and unforth-like) with pushing
> a large number of items to the data stack, only to then push them to
> the return stack. It's what one does in desperation.

The times I did that recently, I had a variable number of items on the
data stack and I wanted them in reverse order. I could do a sequence of
N ROLLs to get the ones I wanted. That didn't look good. Easier (though
still not good) to move them to the return stack and then take them off
one at a time.

Since what I was interested in was something else entirely and I just
wanted this to work well enough to get to what I actually wanted to do,
this was adequate.

It was better than putting things at HERE because HERE only guarantees
you 80 characters before you overwrite what some calling routine might
have put at PAD and less than that if a calling routine is using the <#
buffer.

It was better than putting things into a fixed-size buffer when I hadn't
decided the maximum number of items.

Of course, with a little under-the-hood magic it's easy. Just keep the
stack pointer address and point to what you want (the moral equivalent
of PICK ) and then when you're done set the stack pointer to the bottom
of your list.

And if you do know a maximum size it makes sense to just quick build a
queue.


Would it make sense to have commands to move multiple data items from
the stack to a buffer and vice versa, specifying reversed order?

You could do it with MOVE if you had an address for TOS , which you
can't do portably.

Something kind of like:

\ for data stack that builds downward
\ not tested, surely fails on many systems
: >MEM1 ( xn ... x1 n addr -- )
SP @ CELL+ CELL+ SWAP ROT CELLS DUP >R MOVE
R> SP +! ;

: >MEM2 ( xn ... x1 n addr -- )
0 ROT 1- CELLS /STRING BOUNDS ?DO
I !
-1 CELLS +LOOP ;

It isn't hard to write, but if it was standard it might be made more
efficient under-the-hood.

Ed

unread,
Mar 10, 2009, 11:08:34 PM3/10/09
to
Jonah Thomas wrote:
> "Ed" <nos...@invalid.com> wrote:
>
> > There is something inherently wrong (and unforth-like) with pushing
> > a large number of items to the data stack, only to then push them to
> > the return stack. It's what one does in desperation.

> The times I did that recently, I had a variable number of items on the
> data stack and I wanted them in reverse order. I could do a sequence of
> N ROLLs to get the ones I wanted. That didn't look good. Easier (though
> still not good) to move them to the return stack and then take them off
> one at a time.
>
> Since what I was interested in was something else entirely and I just
> wanted this to work well enough to get to what I actually wanted to do,
> this was adequate.
>
> It was better than putting things at HERE because HERE only guarantees
> you 80 characters before you overwrite what some calling routine might
> have put at PAD and less than that if a calling routine is using the <#
> buffer.
>
> It was better than putting things into a fixed-size buffer when I hadn't
> decided the maximum number of items.

A stack is a fixed-size buffer. In your case you knew (or assumed) it
would be large enough.

> Of course, with a little under-the-hood magic it's easy. Just keep the
> stack pointer address and point to what you want (the moral equivalent
> of PICK ) and then when you're done set the stack pointer to the bottom
> of your list.
>
> And if you do know a maximum size it makes sense to just quick build a
> queue.
>
>
> Would it make sense to have commands to move multiple data items from
> the stack to a buffer and vice versa, specifying reversed order?
>
> You could do it with MOVE if you had an address for TOS , which you
> can't do portably.
>
> Something kind of like:
>
> \ for data stack that builds downward
> \ not tested, surely fails on many systems
> : >MEM1 ( xn ... x1 n addr -- )
> SP @ CELL+ CELL+ SWAP ROT CELLS DUP >R MOVE
> R> SP +! ;
>
> : >MEM2 ( xn ... x1 n addr -- )
> 0 ROT 1- CELLS /STRING BOUNDS ?DO
> I !
> -1 CELLS +LOOP ;
>
> It isn't hard to write, but if it was standard it might be made more
> efficient under-the-hood.

Given forth stacks were not intended to be buffers for holding and
processing large amounts of data - indeed some stacks can be quite
small - I'm not sure it's a good thing to encourage the practice by
standardizing tools for it. Having said that, there will be instances
when sorting/manipulating a handful of items on the stacks can be
useful and convenient.

Albert van der Horst

unread,
Mar 11, 2009, 6:21:48 AM3/11/09
to
In article <gp79p5$og5$1...@news-01.bur.connect.com.au>,
Ed <nos...@invalid.com> wrote:
<SNIP>

>
>Given forth stacks were not intended to be buffers for holding and
>processing large amounts of data - indeed some stacks can be quite
>small - I'm not sure it's a good thing to encourage the practice by
>standardizing tools for it. Having said that, there will be instances
>when sorting/manipulating a handful of items on the stacks can be
>useful and convenient.
>

Like a WORDS that shows the latest defined word first.
It is not much manipulating. First put a zero on the stack,
than all DEA's ("namefields"). Then print all names till a
zero is found.

There are other examples, e.g. a bignum package.
Nobody would try to do bignums on a 8051 anyway.
Stacks are more attractive and natural in Forth than ALLOCATE/FREE.

Groetjes Albert

--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- like all pyramid schemes -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Ed

unread,
Mar 12, 2009, 9:49:22 AM3/12/09
to
Albert van der Horst wrote:
> In article <gp79p5$og5$1...@news-01.bur.connect.com.au>,
> Ed <nos...@invalid.com> wrote:
> <SNIP>
> >
> >Given forth stacks were not intended to be buffers for holding and
> >processing large amounts of data - indeed some stacks can be quite
> >small - I'm not sure it's a good thing to encourage the practice by
> >standardizing tools for it. Having said that, there will be instances
> >when sorting/manipulating a handful of items on the stacks can be
> >useful and convenient.
> >
>
> Like a WORDS that shows the latest defined word first.
> It is not much manipulating. First put a zero on the stack,
> than all DEA's ("namefields"). Then print all names till a
> zero is found.
>
> There are other examples, e.g. a bignum package.
> Nobody would try to do bignums on a 8051 anyway.
> Stacks are more attractive and natural in Forth than ALLOCATE/FREE.

But it's not a general solution. You may be forced to use a machine
which doesn't have the stack capacity, or you want the program to
run on a variety of machines. In such cases you will have to find
other strategies - where tools that move large amounts of data to
and from the stacks will have little or no value.

Jonah Thomas

unread,
Mar 12, 2009, 2:58:05 PM3/12/09
to
"Ed" <nos...@invalid.com> wrote:
> Albert van der Horst wrote:
> > Ed <nos...@invalid.com> wrote:

> > <SNIP>


> > >
> > >Having said that, there will be instances when sorting/manipulating
> > >a handful of items on the stacks can be useful and convenient.
> >

> > Stacks are more attractive and natural in Forth than ALLOCATE/FREE.
>
> But it's not a general solution. You may be forced to use a machine
> which doesn't have the stack capacity, or you want the program to
> run on a variety of machines. In such cases you will have to find
> other strategies - where tools that move large amounts of data to
> and from the stacks will have little or no value.

Sure. If there's limited RAM then you need to store intermediate results
in mass storage.

And you might run out of that, too.

There are no perfectly general solutions when you consider the minimum
resources that Forth might be running on.

But it might possibly be worthwhile to have words to move even
relatively small numbers of items between stacks.

On the other hand, you could use BLOCKs. On a 32-bit Forth one block
will hold 32 fixed-point numbers, and a 64-bit Forth can still keep 16
numbers in a block. The system won't actually save anything to disk
unless you run out of block buffers. If you run out of disk space there
probably isn't a good alternative method to solve the problem anyway on
that Forth system.

You could store the block number and the address inside the block
together as one cell-size number. There's probably a way to set it up so
you don't have to pay attention to those details while you're solving
your own problem.

Maybe blocks are a better choice.

BruceMcF

unread,
Mar 15, 2009, 12:18:11 AM3/15/09
to

The appeal of the return and data stack is that *if* you can assume
sufficient room, you do not have to specify the stack slot it goes
into. However, its only a lack of a portable facility for an
application to request a BLOCK-ALLOCATE from the system that stands in
the way of portable use of Blocks for that kind of application.

For a microcontroller where data and return stack size is an issue, an
spi serial flash is often the easiest mass storage to add, and its
natural to access that as Blocks.

The simplest system would have a space of blocks set aside as a common
pool, and:

BLOCK-PAD ( -- pad-block# blocks-available )
BLOCK-ALLOT ( n -- ior ) ... update pad-block# up or down, capped at
bottom and top of the pool

And, yes, IMHO its more general as a facility for a small Forth device
to spill or fill a variable number of items to a buffer, with the top
of stack number of items at the buffer base address.

Reply all
Reply to author
Forward
0 new messages