Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RfD: N>R and NR>

29 views
Skip to first unread message

Peter Knaggs

unread,
Mar 10, 2010, 4:13:31 AM3/10/10
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 an intimate 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
========
15.6.2.aaaa N>R n-to-r TOOLS 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.

15.6.2.bbbb NR> n-r-from TOOLS 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
;

Andrew Haley

unread,
Mar 10, 2010, 4:59:16 AM3/10/10
to
Peter Knaggs <p...@bcs.org.uk> wrote:
> RfD: N>R and NR>

I think we discussed this already. It's still a great idea, and is
well-supported by many Forths.

Andrew.

Anton Ertl

unread,
Mar 10, 2010, 12:11:36 PM3/10/10
to

What makes it great? To me it looks like a bad idea.

- 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
EuroForth 2009: http://www.euroforth.org/ef09/

Andrew Haley

unread,
Mar 10, 2010, 1:41:43 PM3/10/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Peter Knaggs <p...@bcs.org.uk> wrote:
>>> RfD: N>R and NR>
>>
>>I think we discussed this already. It's still a great idea, and is
>>well-supported by many Forths.
>
> What makes it great? To me it looks like a bad idea.

They are very useful for their stated purpose, which is stashing the
results of words with variable-length results such as GET-ORDER and
SAVE-INPUT, awful to write in Standard Forth, and easy to write with
carnal knowledge. What's not to like?

Are we just going to have the 4 Feb 2009 discussion again?

Andrew.

Marcel Hendrix

unread,
Mar 10, 2010, 1:58:11 PM3/10/10
to
"Peter Knaggs" <p...@bcs.org.uk> Re: RfD: N>R and NR>

> 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.

This proposal does not solve the latter problem (how could it?)
Instead it discusses how a *defined* number of items can be
transferred to the R-stack. The former problem: "Saving several
items to the return stack is tedious", is simply not true.

: n>r ( xn..x1 +n -- ) ( R: -- x1 .. xn +n )
POSTPONE DUP
POSTPONE BEGIN POSTPONE DUP
POSTPONE WHILE POSTPONE 1- POSTPONE ROT POSTPONE >R
POSTPONE REPEAT
POSTPONE DROP POSTPONE >R ; IMMEDIATE

: nr> ( -- xn..x1 +n ) ( R: x1 .. xn +n -- )
POSTPONE R@
POSTPONE BEGIN POSTPONE R@
POSTPONE WHILE POSTPONE R> POSTPONE 1-
POSTPONE R> POSTPONE SWAP
POSTPONE >R POSTPONE SWAP
POSTPONE REPEAT
POSTPONE R> POSTPONE DROP ; IMMEDIATE

: test 3 2 1 3 N>R R@ . NR> ; test .S

Doing it myself saves me from the arbitrary restrictions that the future
Standard seems to want to impose.

> These words cannot be written without an intimate knowledge of the
> underlying Forth.

???

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

Why is this an ambiguous condition? Of course, if the numbers on
top of the R-stack don't match, but then it's called a bug.

Using that reasoning, this would be an "ambiguous condition," too.

: test 3 2 1 3 N>R ;

> [implementation]

The coders at MPE are being spoilt by their compiler :-)

-marcel

-- -----------------

$01241700 : test
$0124170A push 3 b#
$0124170C push 2 b#
$0124170E push 1 b#
$01241710 mov rcx, 3 d#
$01241717 mov rbx, 3 d#
$0124171E nop
$0124171F nop
$01241720 cmp rbx, 0 b#
$01241724 push rcx
$01241725 je $01241740 offset NEAR
$0124172B pop rdi
$0124172C pop rax
$0124172D lea rbp, [rbp -8 +] qword
$01241731 mov [rbp 0 +] qword, rax
$01241735 push rdi
$01241736 lea rbx, [rbx -1 +] qword
$0124173A pop rcx
$0124173B jmp $01241720 offset SHORT
$0124173D push rcx
$0124173E push rbx
$0124173F pop rbx
$01241740 pop rbx
$01241741 lea rbp, [rbp -8 +] qword
$01241745 mov [rbp 0 +] qword, rbx
$01241749 push rbx
$0124174A lea rbp, [rbp -8 +] qword
$0124174E mov [rbp 0 +] qword, $0124175B d#
$01241756 jmp .+10 ( $011391C2 ) offset NEAR
$0124175B mov rbx, [rbp 0 +] qword
$0124175F nop
$01241760 mov rdi, [rbp 0 +] qword
$01241764 cmp rdi, 0 b#
$01241768 je $01241792 offset NEAR
$0124176E mov rdi, [rbp 0 +] qword
$01241772 lea rbp, [rbp 8 +] qword
$01241776 mov rax, [rbp 0 +] qword
$0124177A lea rbp, [rbp 8 +] qword
$0124177E lea rdi, [rdi -1 +] qword
$01241782 lea rbp, [rbp -8 +] qword
$01241786 mov [rbp 0 +] qword, rdi
$0124178A mov rcx, rax
$0124178D push rcx
$0124178E jmp $01241760 offset SHORT
$01241790 push rbx
$01241791 pop rbx
$01241792 mov rdi, [rbp 0 +] qword
$01241796 lea rbp, [rbp 8 +] qword
$0124179A push rbx
$0124179B ;

Peter Knaggs

unread,
Mar 10, 2010, 3:30:36 PM3/10/10
to
On Wed, 10 Mar 2010 18:41:43 -0000, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:
>
> Are we just going to have the 4 Feb 2009 discussion again?

Given the problems I have had with substitute, I decided to post this as
an RfD with a view to taking it to a CfV next week if there is little
discussion.

I did however make one changed based on the previous discussion. I have
moved the words from CORE EXT to TOOLS EXT.

I also like Leon Wagner suggestions that the signature should be:

N>R ( n*x n -- ) ( R: -- n*x n )
NR> ( -- n*x n ) ( R: n*x n -- )

Thus leaving it clear that the order of the items on the return stack is
system dependent and may differ depending on the CPU.

--
Peter Knaggs

Bruce McFarling

unread,
Mar 10, 2010, 3:35:07 PM3/10/10
to
On Mar 10, 1:58 pm, m...@iae.nl (Marcel Hendrix) wrote:
> : n>r ( xn..x1 +n -- ) ( R: -- x1 .. xn +n )
>   POSTPONE DUP
>   POSTPONE BEGIN  POSTPONE DUP  
>   POSTPONE WHILE  POSTPONE 1- POSTPONE ROT POSTPONE >R  
>   POSTPONE REPEAT  
>   POSTPONE DROP POSTPONE >R ; IMMEDIATE

oh,

POSTPONE: n>r ( xn..x1 +n -- ) ( R: -- x1 .. xn +n )
DUP BEGIN
DUP WHILE
1- ROT >R
REPEAT DROP >R ;POSTPONE

I prefer n>r, even if POSTPONE: ;POSTPONE is available. If the
implementation has a quicker way implemented, I want to use that
instead.

Bruce McFarling

unread,
Mar 10, 2010, 3:38:54 PM3/10/10
to
On Mar 10, 1:58 pm, m...@iae.nl (Marcel Hendrix) wrote:

> > Rationale
> > ... Saving several


> > items to the return stack is tedious, especially where the number
> > of items is unknown at compile time.

> This proposal does not solve the latter problem (how could it?)
> Instead it discusses how a *defined* number of items can be
> transferred to the R-stack.

Of course it solves "the latter problem" ... the number of items saved
are determined by the top of stack at runtime, which need not be known
at compile time and which can vary from one run to another.

Marcel Hendrix

unread,
Mar 10, 2010, 3:07:58 PM3/10/10
to
Bruce McFarling <agi...@netscape.net> writes Re: RfD: N>R and NR>
[..]

> POSTPONE: n>r ( xn..x1 +n -- ) ( R: -- x1 .. xn +n )
> DUP BEGIN
> DUP WHILE
> 1- ROT >R
> REPEAT DROP >R ;POSTPONE

> I prefer n>r, even if POSTPONE: ;POSTPONE is available. If the
> implementation has a quicker way implemented, I want to use that
> instead.

And for what would you use n>r ? We can't access anything
that n>r pushes.

OTOH the source for POSTPONE: ;POSTPONE looks extremely useful.
How did you handle comments, multi-line parsing, literal
and locals handling, [ and ], and other niceties in a portable
way?

-marcel

BTW, your posts are full of "=A0" enhancements.

Bruce McFarling

unread,
Mar 10, 2010, 5:26:18 PM3/10/10
to
On Mar 10, 3:07 pm, m...@iae.nl (Marcel Hendrix) wrote:
> OTOH the source for POSTPONE: ;POSTPONE looks extremely useful.
> How did you handle comments, multi-line parsing, literal
> and locals handling, [ and ], and other niceties in a portable
> way?

By only having it do what it does, which is POSTPONE one word after
another until "<char>POSTPONE" is encountered, then execute
"<char>POSTPONE".

So it only looks nice if you lay it out to make it look that way.
E.g., the name is parsed then {\} is executed, so don't put anything
there that isn't a comment. All it does is name a definition and
postpone a sequence, making the definition immediate, based on
POSTPONE{ and ;POSTPONE ("}POSTPONE" is a NOP).

Just a little sugar frosting on strings of POSTPONES.

J Thomas

unread,
Mar 10, 2010, 7:40:49 PM3/10/10
to

Your last line jumped out at me. Is this true? Can the order of the items
on the return stack vary with CPU? I can imagine that one system could
have the stack going up and another going down, but that doesn't affect
the order that a program sees.

Are you implementing the switch with MOVE so that the order on the return
stack depends on whether the return stack and data stack grow in
different directions? That's efficient but it means you can't portably do
anything with the data N>R provides except NR> . You can't get them off
the return stack one at a time unless you don't care about the order.

Is the guarantee of efficiency worth that?

Elizabeth D Rather

unread,
Mar 10, 2010, 9:02:41 PM3/10/10
to

There needs to be a guarantee that they'll come off in the same order
they went on. Mostly these commands are used to get stuff (e.g. Windows
call parameters) temporarily off the data stack, and one isn't trying to
access individual items from the return stack. That's the only reason
you'd need to know the order in the saved (return stack) state. Since
there may be a bunch of stuff, efficiency is important.

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."
==================================================

Bruce McFarling

unread,
Mar 10, 2010, 9:48:02 PM3/10/10
to
On Mar 10, 7:40 pm, J Thomas <jethom...@gmail.com> wrote:
> Are you implementing the switch with MOVE so that the order on the return
> stack depends on whether the return stack and data stack grow in
> different directions? That's efficient but it means you can't portably do
> anything with the data N>R provides except NR>

> Is the guarantee of efficiency worth that?

The efficiency is what the point is ... if you need to get the data
off the return stack in smaller pieces, construct the smaller pieces
and N>R and R>N those pieces.

"vanish", "now reappear". Thats the point of the behavior.

Gerry

unread,
Mar 11, 2010, 5:00:16 AM3/11/10
to

I disagree that efficiency is the only point, doing what you
suggest could be very fiddly, in the extreme doing >R n times.
Adding useful functionality is the most important point IMHO,
let the implementers worry about efficiency.

>
> "vanish", "now reappear". Thats the point of the behavior.

I don't think it should be restricted to this behaviour. I would like
the order items are placed on the R stack mandated for these reasons:

1. I can foresee cases where, after N>R, items would be individually
processed and it would be necessary to know the order of items on
the R stack. Not mandating the order restricts the utility of N>R,
which is useful beyond temporarily saving the results of GET-ORDER
and SAVE-INPUT.

2. If the order on the R stack is not mandated, that is yet another
portability trap, e.g. programs making use of one particular Forth's
order may not work on another Forth. We have enough of these traps
without introducing another.

3. A less important point is that 2>R mandates the order and it is
inconsistent to not do so for N>R which is a generalisation of 2>R.
For 2>R and 2 N>R to possibly leave 2 items on the R stack in
different orders is inconsistent, unnecessary and would look rather
silly.

Gerry

Stephen Pelc

unread,
Mar 11, 2010, 6:56:11 AM3/11/10
to
On Thu, 11 Mar 2010 02:00:16 -0800 (PST), Gerry
<ge...@jackson9000.fsnet.co.uk> wrote:

>I don't think it should be restricted to this behaviour. I would like
>the order items are placed on the R stack mandated for these reasons:
>
>1. I can foresee cases where, after N>R, items would be individually
>processed and it would be necessary to know the order of items on
>the R stack. Not mandating the order restricts the utility of N>R,
>which is useful beyond temporarily saving the results of GET-ORDER
>and SAVE-INPUT.

I checked this in several implementations. They differ. The least
pain is thus not to mandate the order. I did my homework before
writing the proposal!

>2. If the order on the R stack is not mandated, that is yet another
>portability trap, e.g. programs making use of one particular Forth's
>order may not work on another Forth. We have enough of these traps
>without introducing another.

We don't have a standard way to access other than TOR and NOR, so
the portability issue is the same as it was.

>3. A less important point is that 2>R mandates the order and it is
>inconsistent to not do so for N>R which is a generalisation of 2>R.
>For 2>R and 2 N>R to possibly leave 2 items on the R stack in
>different orders is inconsistent, unnecessary and would look rather
>silly.

In scanning source trees, we found that N>R and NR> are only used
to handle opaque information, i.e. you don't know what it is.
I have not seen a use of NR> that leads to the returned data being
picked apart, except by words such RESTORE-INPUT that are carnal by
definition.

N>R and NR> are used to get information out of the way for a short
time. The information is either restored or dropped after NR>.

Stephen


--
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

Bruce McFarling

unread,
Mar 11, 2010, 12:30:30 PM3/11/10
to
On Mar 11, 5:00 am, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
> I disagree that efficiency is the only point, doing what you
> suggest could be very fiddly, in the extreme doing >R n times.

Yes, it is self-limiting ... but that is the point of having the count
stored on the stack.

> Adding useful functionality is the most important point IMHO,
> let the implementers worry about efficiency.

Various implementer worried about efficiency have done this, and done
it in various ways, likely that were efficient for their systems.

( [n-cells] n -- ) ( R: -- [n-cells] n )
( R: [n-cells] n -- ) ( -- [n-cells] n )

... could not even be taken for granted, since the most efficient way
to store and retrieve might be ( n ) CELLS or the old Rack index or
some other

The support I could see as possibly being warranted to extend the
functionality would be:

NSPLIT ( [n1-cells] n1 n2 -- [n2-cells] n2 [n3-cells] n3 )
where n1>=n2, and n3=(n1-n2)

NJOIN ( [n1-cells] n1 [n2-cells] n2 -- [n3-cells] n3 )
where n3=n1+n2

> > "vanish", "now reappear". Thats the point of the behavior.

> I don't think it should be restricted to this behaviour. I would like
> the order items are placed on the R stack mandated for these reasons:

> 1. I can foresee cases where, after N>R, items would be individually
> processed and it would be necessary to know the order of items on
> the R stack.

In that case, the existing N>R and R>N on various systems cannot be
used. One cannot even have an environment query on order to choose
between two routines, since the top of the rack might hold a count, an
offset, an index, or an address.

> Not mandating the order restricts the utility of N>R,

Yes, but that restriction has already taken place. This
standardization notes that fact and calls a halt on the forking at the
point we have already reached.

> which is useful beyond temporarily saving the results of GET-ORDER
> and SAVE-INPUT.

> 2. If the order on the R stack is not mandated, that is yet another
> portability trap, e.g. programs making use of one particular Forth's
> order may not work on another Forth. We have enough of these traps
> without introducing another.

Its not being introduced, it already exists. Its a deeper portability
trap if it exists without a sign posting. That is, if there is a low
rail overpass, posting a sign "trucks over 8' should not use this
road" does not *create* the hazard.


> 3. A less important point is that 2>R mandates the order and it is
> inconsistent to not do so for N>R which is a generalisation of 2>R.

N>R may seem like a generalization of 2>R, but NR> is not a
generalization of 2R> ... its the code that says how many to get from
the rack with 2R> while its return stack state that says how many to
get from the rack with 2R>.

If you want a generalization of 2R>, it would be:

U>R ( x1 ... xu u -- ) ( R: -- x1 ... xu )
UR> ( u -- x1 ... xu ) ( R: x1 ... xu -- )

> For 2>R and 2 N>R to possibly leave 2 items on the R stack in
> different orders is inconsistent, unnecessary and would look rather
> silly.

Since you cannot do: "2 N>R 2 NR>" as "2>R 2R>", that fact that the
first part of the phrase is not equivalent is neither here nor there.

We can't get what you want from N>R NR> they are already _de facto_
defined otherwise.

U>R and UR> above still has them reversed in 2>R 2R> order, since they
are defined to be equivalent to the more intrinsic order of a "U" long
sequence of ">R" and "R>", resp. But that is the only way that:
"8 U>R X UR> 8 X - UR>"

can be made consistent for all values X={0,8}

===========================

NB. I know that sometimes in discussion of options, it reads as if I
am arguing in favor of *adoption* of an option when I am trying to
think out load about the *existence* of an option.

So for the record, between NSPLIT / NJOIN and U>R UR>, I tentatively
prefer the latter.

N>R NR> permits an implementation to export maximally efficient
temporary storage and recall of a block. Intrinsically, since NR> is
not parametrized on the datastack, the order that the items resides on
the rack is neither here nor there, because there's no reason to
expect that the top of the rack will necessarily hold a cell count.

U>R UR> permits an implementation to export an open block stack move
as efficiently as possible. For some systems, where N>R and NR> act in
a consistent way (which the implementer will of course know), that
could well be:

: U>R ( x1 ... xu u -- ) ( R: -- xu ... x1 ) N>R RDROP ;
: UR> ( R: x1 ... xu -- ) ( u -- x1 ... xu ) >R NR> ;

... for a minimal forth loading support from source, it may be factors
that do one stage set up for an UNTIL loop, eg, a hypothetical minimal
65816 Forth:

CODE U>R-stage ( x1 u -- u-1 FALSE | TRUE=[u=0] ) ( R: -- x1 )
LDA D+2,X
BEQ +
LDY DL+4,X
PHY
DEC A
STA DL+4,X
LDA #0
STA DL+2,X
JMP NEXT
+: INX
INX
LDA #$FFFF
STA DL+2,X
JMP NEXT
;CODE

: U>R POSTPONE BEGIN POSTPONE U>R-stage POSTPONE UNTIL ; IMMEDIATE

CODE U>R-stage ( x1 u -- u-1 FALSE | TRUE=[u=0] ) ( R: -- x1 )

CODE UR>-stage ( u -- x1 u-1 FALSE | TRUE=[u=0] ) ( R: x1 -- )
LDA DL+2,X
BEQ +
PLY
STY DL+2,X
STA DL,X
DEX
DEX
DEX
DEX
LDA #$FFFF
+: EOR #$FFFF
STA DL+2,X
JMP NEXT
;CODE

: UR> POSTPONE BEGIN POSTPONE UR>-stage POSTPONE UNTIL ; IMMEDIATE

Gerry

unread,
Mar 11, 2010, 1:01:10 PM3/11/10
to
On 11 Mar, 11:56, stephen...@mpeforth.com (Stephen Pelc)
wrote:

> On Thu, 11 Mar 2010 02:00:16 -0800 (PST), Gerry
>
> <ge...@jackson9000.fsnet.co.uk> wrote:
> >I don't think it should be restricted to this behaviour. I would like
> >the order items are placed on the R stack mandated for these reasons:
>
> >1. I can foresee cases where, after N>R, items would be individually
> >processed and it would be necessary to know the order of items on
> >the R stack. Not mandating the order restricts the utility of N>R,
> >which is useful beyond temporarily saving the results of GET-ORDER
> >and SAVE-INPUT.
>
> I checked this in several implementations. They differ. The least
> pain is thus not to mandate the order. I did my homework before
> writing the proposal!

Given that you run a commercial organisation I can understand your
position but it seems to me that at times too much notice is taken
of legacy code when trying to improve the language.

>
> >2. If the order on the R stack is not mandated, that is yet another
> >portability trap, e.g. programs making use of one particular Forth's
> >order may not work on another Forth. We have enough of these traps
> >without introducing another.
>
> We don't have a standard way to access other than TOR and NOR, so
> the portability issue is the same as it was.
>

You miss the point. If N>R is accepted into the standard, at some
point a hyperthetical user will process the data from the R stack
using the order provided in the Forth system being used. When that
code is ported to another system it may not work because that
system stacks the data in a different order.

> >3. A less important point is that 2>R mandates the order and it is
> >inconsistent to not do so for N>R which is a generalisation of 2>R.
> >For 2>R and 2 N>R to possibly leave 2 items on the R stack in
> >different orders is inconsistent, unnecessary and would look rather
> >silly.
>
> In scanning source trees, we found that N>R and NR> are only used
> to handle opaque information, i.e. you don't know what it is.
> I have not seen a use of NR> that leads to the returned data being
> picked apart, except by words such RESTORE-INPUT that are carnal by
> definition.

That is not to say that others won't use N>R to move known data to
the R stack in the future if N>R is available, I would say that is
a certainty.

>
> N>R and NR> are used to get information out of the way for a short
> time. The information is either restored or dropped after NR>.
>

If you want to make the whole thing invisible to the user, why specify
that the R stack be used. Why not have 2 alternative words, say N-SAVE
and N-RESTORE that move n words from the stack somewhere. That would
give implementers even more freedom for efficiency, they could use the
R stack if they wish or use some other area of memory.

Gerry

Jerry Avins

unread,
Mar 11, 2010, 1:15:09 PM3/11/10
to

No, you miss the point. Since the user sees the retrieved data, they
will be in the same order as before they were stored.

>>> 3. A less important point is that 2>R mandates the order and it is
>>> inconsistent to not do so for N>R which is a generalisation of 2>R.
>>> For 2>R and 2 N>R to possibly leave 2 items on the R stack in
>>> different orders is inconsistent, unnecessary and would look rather
>>> silly.
>> In scanning source trees, we found that N>R and NR> are only used
>> to handle opaque information, i.e. you don't know what it is.
>> I have not seen a use of NR> that leads to the returned data being
>> picked apart, except by words such RESTORE-INPUT that are carnal by
>> definition.
>
> That is not to say that others won't use N>R to move known data to
> the R stack in the future if N>R is available, I would say that is
> a certainty.
>
>> N>R and NR> are used to get information out of the way for a short
>> time. The information is either restored or dropped after NR>.
>>
>
> If you want to make the whole thing invisible to the user, why specify
> that the R stack be used. Why not have 2 alternative words, say N-SAVE
> and N-RESTORE that move n words from the stack somewhere. That would
> give implementers even more freedom for efficiency, they could use the
> R stack if they wish or use some other area of memory.

Using the return stack imposes constraints that the programmer needs to
know about.

Jerry
--
Why am I in a handbasket? Where are we going?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Gerry

unread,
Mar 11, 2010, 2:34:50 PM3/11/10
to
On 11 Mar, 18:15, Jerry Avins <j...@ieee.org> wrote:
[...]

>
> > You miss the point. If N>R is accepted into the standard, at some
> > point a hyperthetical user will process the data from the R stack
> > using the order provided in the Forth system being used. When that
> > code is ported to another system it may not work because that
> > system stacks the data in a different order.
>
> No, you miss the point. Since the user sees the retrieved data, they
> will be in the same order as before they were stored.

Given the data stack holds ( 1 2 3 4 4 )

After N>R, system A saves the data on the R stack as ( R: -- 1 2 3 4
4 )
The user's program executes 2R> to get ( -- 4 4 ) ( R: -- 1 2 3 )

System B saves the data on the R stack as ( R: -- 4 3 2 1 4 )
The user's 2R> gets ( -- 1 4 ) ( R: 4 3 2 )

How are these the same?

[...]

> > If you want to make the whole thing invisible to the user, why specify
> > that the R stack be used. Why not have 2 alternative words, say N-SAVE
> > and N-RESTORE that move n words from the stack somewhere. That would
> > give implementers even more freedom for efficiency, they could use the
> > R stack if they wish or use some other area of memory.
>
> Using the return stack imposes constraints that the programmer needs to
> know about.
>

Of course

Gerry

Bruce McFarling

unread,
Mar 11, 2010, 2:42:51 PM3/11/10
to
On Mar 11, 1:01 pm, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
> Given that you run a commercial organisation I can understand your
> position but it seems to me that at times too much notice is taken
> of legacy code when trying to improve the language.

Why are you assuming that the role of the standard process is to
improve the language *in general*, rather than to improve the language
in the way that a communication standard can usefully improve a
language.

The role of the standards process is to ease the task of porting code
from one system to another. Where there are not divergent practices in
what behavior is called by what name, an existing practice can be
standardized to allow more implementations to support that practice
under that word and ease the porting of source code from systems
possessing that behavior under that word.

Where there are divergent practices, the role of the standard is to
set out what actions can be communicated portably and what actions
need special treatment.

========================

What is the burden of proof for arguing that a behavior like this
should be assigned a standard name and standard specification of the
behavior referred to by that name is that there are implementers that
do or will comply with the specification and there are program authors
who do or will use the word as specified.

If it eases the task of *any* code authors porting code between
implementations, and/or if *any* implementers add it and *any* authors
those implementations targeting put it to use, then there is some
benefit, and the burden of proof is whether the *gross* benefit
justifies the time and trouble of the standardization.

========================

What is the burden of proof for arguing that the standards process has
to "fix" something "that some implementation is doing wrong"?

The burden of proof there is much higher. "Breaking existing code" ...
which is to say, forcing implementers to choose between standards
compliance and being able to continue to interpret existing source ...
is a cost, in pursuit of a speculative gain argued by an advocate in
the quasi-formalized standard process.

For the commercial system houses, since customers value code
stability, breaking *their* code is a substantial commercial cost, and
the advocate should not be surprised if they simply reject the
proposal to adopt a standard that they must violate in order to
maintain a stable existing code base.

If it is a genuinely useful advance, demonstrate it in action. If it
is sufficiently compelling that it causes a fork, then they can decide
whether they want to establishing a new product line that implements
the new behavior and allows them to service the capacities of the new
fork.

Bruce McFarling

unread,
Mar 11, 2010, 2:56:35 PM3/11/10
to
-[ On Mar 10, 4:13 am, "Peter Knaggs" <p...@bcs.org.uk> wrote: ]-

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

Here's a useful piece of information to have in a model constant or an
ENVIROMENT? value. Of course, for this, the contents of the return on
the return stack are entirely opaque, all you need to know is how big
it is, and if you can do it at all.

=rstate= ( -- u|TRUE )
if not TRUE, number of cells on the top of the return stack
consumed by an exit from the word, with data below available to the
caller on return.
if TRUE, data cannot be made available to the caller on the return
stack.

\ Implementation (?? uses system):
\ ... after bunches of system identity testing follow by calls to
system prelude files ...
\ ... some of which will have defined =rstate= for their system ...

?? =rstate= 0= uses 0 INVERT CONSTANT =rstate=

Bruce McFarling

unread,
Mar 11, 2010, 3:16:20 PM3/11/10
to
On Mar 11, 2:34 pm, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
> Given the data stack holds ( 1 2 3 4 4 )

> After N>R, system A saves the data on the R stack as ( R: -- 1 2 3 4
> 4 )

> The user's program executes 2R> to get ( -- 4 4 ) ( R: -- 1 2 3 )

> System B saves the data on the R stack as ( R: -- 4 3 2 1 4 )
> The user's 2R> gets ( -- 1 4 ) ( R: 4 3 2 )

> How are these the same?

They are not, and at this point in time they cannot be made the same.

However, on both system A and system B, if the user executes
... N>R ( R: -- x ) ... NR> ( R: -- ) ...

... they get identical results no matter how N>R and NR> are already
implemented or implemented once standardized ... so long as there are
no attempts to access at or below "x".

Further, if an "open" block datastack<->rstack move is defined, it
ought to be an inverted stack. For one thing, hardware-stack
processors without a datastack index cannot necessarily index down
into the datastack to grab the bottom datastack item to push it onto
the return stack, or conversely for retrieving it. For another thing,
that is *internally* consistent for multiple:
x1 U>R x2 U>R x3 U>R x4 U>R

... so long as x1+x2=x3+x4.

Elizabeth D Rather

unread,
Mar 11, 2010, 3:33:48 PM3/11/10
to
Gerry wrote:
> On 11 Mar, 18:15, Jerry Avins <j...@ieee.org> wrote:
> [...]
>
>>> You miss the point. If N>R is accepted into the standard, at some
>>> point a hyperthetical user will process the data from the R stack
>>> using the order provided in the Forth system being used. When that
>>> code is ported to another system it may not work because that
>>> system stacks the data in a different order.
>> No, you miss the point. Since the user sees the retrieved data, they
>> will be in the same order as before they were stored.
>
> Given the data stack holds ( 1 2 3 4 4 )
>
> After N>R, system A saves the data on the R stack as ( R: -- 1 2 3 4
> 4 )
> The user's program executes 2R> to get ( -- 4 4 ) ( R: -- 1 2 3 )
>
> System B saves the data on the R stack as ( R: -- 4 3 2 1 4 )
> The user's 2R> gets ( -- 1 4 ) ( R: 4 3 2 )
>
> How are these the same?

They aren't. I think the point being made here is that (as various
folks have observed) N>R etc. is not intended to push data on the Return
Stack for any reason other than just to *get it out of the way*
temporarily. It's not *intended* to be mixed with R>, 2R>, R@, etc.

>>> If you want to make the whole thing invisible to the user, why specify
>>> that the R stack be used. Why not have 2 alternative words, say N-SAVE
>>> and N-RESTORE that move n words from the stack somewhere. That would
>>> give implementers even more freedom for efficiency, they could use the
>>> R stack if they wish or use some other area of memory.
>> Using the return stack imposes constraints that the programmer needs to
>> know about.

Generalizing the names has the advantage of not implying that the saved
items are accessible in any way other than being restored, but it is
certainly important to point out that the Return Stack should be
considered to be blocked, perhaps with language similar to that used for
DO and friends.

Jerry Avins

unread,
Mar 11, 2010, 4:55:17 PM3/11/10
to
Gerry wrote:
> On 11 Mar, 18:15, Jerry Avins <j...@ieee.org> wrote:
> [...]
>
>>> You miss the point. If N>R is accepted into the standard, at some
>>> point a hyperthetical user will process the data from the R stack
>>> using the order provided in the Forth system being used. When that
>>> code is ported to another system it may not work because that
>>> system stacks the data in a different order.
>> No, you miss the point. Since the user sees the retrieved data, they
>> will be in the same order as before they were stored.
>
> Given the data stack holds ( 1 2 3 4 4 )
>
> After N>R, system A saves the data on the R stack as ( R: -- 1 2 3 4
> 4 )
> The user's program executes 2R> to get ( -- 4 4 ) ( R: -- 1 2 3 )
>
> System B saves the data on the R stack as ( R: -- 4 3 2 1 4 )
> The user's 2R> gets ( -- 1 4 ) ( R: 4 3 2 )
>
> How are these the same?

When the user wants the data back, he uses NR> . If he intends to
retrieve it in pieces, he better put it on that way. It is sufficient
that the words be fool proof. They needn't be damn-fool proof.

...

J Thomas

unread,
Mar 12, 2010, 5:08:13 AM3/12/10
to
I'm a little concerned that the only purpose for these commands is to
enable extreme stack juggling. Wouldn't it be better to get rid of the
code that requires this juggling? Maybe the real problem here is GET-
ORDER and SAVE-INPUT . If we had similar commands that return the address
of a data structure, would that be better? I'm pretty sure it would for
SAVE-INPUT where the only possible use is RESTORE-INPUT . Let Forth
systems provide those data structures however they want.

Stephen Pelc wrote:
> Gerry <ge...@jackson9000.fsnet.co.uk> wrote:

>>I don't think it should be restricted to this behaviour. I would like
>>the order items are placed on the R stack mandated for these reasons:
>

> I checked this in several implementations. They differ. The least pain
> is thus not to mandate the order. I did my homework before writing the
> proposal!

That is disingenuous.

I like the idea of knowing the order but I don't know whether that should
be specified or not. If it should, and if for most legacy code it doesn't
matter, then that legacy code will not cause pain.

And the standard approach when there is conflicting common practice is to
give new names to the new standard words.

So I'm very glad to hear you did the homework, but your results are to my
way of thinking not arguments to say which way to decide this question.

Here's a potential argument against specifying the order. As I see it, to
make it efficient then either the data stack and return stack must
increment in the same direction, or else they must increment in opposite
directions. If the order is specified then one or the other of those will
be inefficient.

So, what other reasons are there to set those directions? I remember old
Forths where the data stack and return stack were set in opposite
directions and facing each other, so that they wouldn't actually overflow
until their sum overflowed. That was an advantage. Other systems gave the
return stack say 256 items which was way more than enough, and then the
data stack wouldn't overflow until HERE overtook it. And some systems set
a limit for both data and return stacks and threw an error if either of
them overflowed that limit.

Some processors might allow only decrement or only increment? That would
be an argument to make the stacks face the same direction, if you have to
choose. Is there an important reason that sometimes they should face
opposite directions?

I see the argument not to specify the N>R order. It lets you give
*something* to programmers without costing implementors anything. The
tool has a specific use -- stack juggling -- and making it more flexible
might have a cost.

What can we say about that cost in detail?


Also, Gerry's idea that the data could be moved somewhere else than the
return stack is worth some thought. Standard programs would have to
consider the return stack blocked in case some Forth systems did use it.
But given a small return stack, it might be useful to have the N>R stack
elsewhere. If it is elsewhere then it would be possible to guarantee a
minimum size that must be available. If it shares the return stack that
is not possible. However, if the data could be elsewhere then using R@ or
R> to get the result will not work. And NR> does not take an argument, it
always returns the whole thing. So if you allow the data to go anywhere
other than the return stack and you allow users to remove just a part of
that data requires at least one new command, which is a strong argument
not to do both.

Andrew Haley

unread,
Mar 12, 2010, 5:12:08 AM3/12/10
to
Bruce McFarling <agi...@netscape.net> wrote:

> On Mar 11, 1:01?pm, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
>> Given that you run a commercial organisation I can understand your
>> position but it seems to me that at times too much notice is taken
>> of legacy code when trying to improve the language.
>
> Why are you assuming that the role of the standard process is to
> improve the language *in general*, rather than to improve the
> language in the way that a communication standard can usefully
> improve a language.
>
> The role of the standards process is to ease the task of porting
> code from one system to another.

I agree that the purpose of the standard is to standardize and not to
improve the language. Where there isn't sufficient common practice,
there may indeed be language improvement, but that's not the goal.

However, I don't agree that the role of the standards process is only
to ease the task of porting code from one system to another. I think
it's also to specify a common understanding of what the language
means. Portablility may be a result of that.

The rest of your posting makes a lot of sense.

Andrew.

J Thomas

unread,
Mar 12, 2010, 5:18:56 AM3/12/10
to
Andrew Haley wrote:

> Bruce McFarling <agi...@netscape.net> wrote:
>> Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
>>> Given that you run a commercial organisation I can understand your
>>> position but it seems to me that at times too much notice is taken of
>>> legacy code when trying to improve the language.
>>
>> Why are you assuming that the role of the standard process is to
>> improve the language *in general*, rather than to improve the language
>> in the way that a communication standard can usefully improve a
>> language.
>>
>> The role of the standards process is to ease the task of porting code
>> from one system to another.
>
> I agree that the purpose of the standard is to standardize and not to
> improve the language. Where there isn't sufficient common practice,
> there may indeed be language improvement, but that's not the goal.
>
> However, I don't agree that the role of the standards process is only to
> ease the task of porting code from one system to another. I think it's
> also to specify a common understanding of what the language means.
> Portablility may be a result of that.

Good point! A standard can also ease the task of porting code from one
mind to another.

Andrew Haley

unread,
Mar 12, 2010, 5:36:21 AM3/12/10
to
Peter Knaggs <p...@bcs.org.uk> wrote:
>
>
> Reference Implementation
> ========================
> This implementation depends on the return address being on the
> return stack.

Let's not. I suggest

: \\ postpone postpone ; immediate

: n>r \ xn .. x1 N -- ; R: -- x1 .. xn n
\\ dup
\\ begin
\\ ?dup \\ while
\\ rot \\ >r \\ 1-
\\ repeat \\ >r ; immediate

: nr> \ -- xn .. x1 N ; R: x1 .. xn N --
\\ r> \\ dup
\\ begin \\ ?dup \\ while
\\ r> \\ rot \\ rot \\ 1-
\\ repeat ; immediate

This is not very much different from Marcel Hendrix's suggestion.

Andrew.

Gerry

unread,
Mar 12, 2010, 5:42:08 AM3/12/10
to
On 11 Mar, 21:55, Jerry Avins <j...@ieee.org> wrote:
> Gerry wrote:
> > On 11 Mar, 18:15, Jerry Avins <j...@ieee.org> wrote:
> > [...]
>
> >>> You miss the point. If N>R is accepted into the standard, at some
> >>> point a hyperthetical user will process the data from the R stack
> >>> using the order provided in the Forth system being used. When that
> >>> code is ported to another system it may not work because that
> >>> system stacks the data in a different order.
> >> No, you miss the point. Since the user sees the retrieved data, they
> >> will be in the same order as before they were stored.
>
> > Given the data stack holds ( 1 2 3 4 4 )
>
> > After N>R, system A saves the data on the R stack as ( R: -- 1 2 3 4
> > 4 )
> > The user's program executes 2R> to get ( -- 4 4 ) ( R: -- 1 2 3 )
>
> > System B saves the data on the R stack as ( R: -- 4 3 2 1 4 )
> > The user's 2R> gets ( -- 1 4 ) ( R: 4 3 2 )
>
> > How are these the same?
>
> When the user wants the data back, he uses NR> . If he intends to
> retrieve it in pieces, he better put it on that way. It is sufficient
> that the words be fool proof. They needn't be damn-fool proof.
>

I get the impression that you and Ellizabeth Rather don't understand
my point.

I *know* (because it is obvious when you read it) that the RfD
states that N>R and NR> is intended to just provide temporary storage
and that different systems save data on the R stack in different
orders. My point was:

*Assume* that the order on the R stack was mandated in the RfD
for N>R. Then then a user, who had deliberately placed *known*
data on the R stack with N>R, *could* get at that known data,
item by item (using R>, R@, 2R> and 2R@) and process that data as
required, eventually removing that data from the R stack without
using NR>.

Not mandating the order on the R stack in the RfD disallows that
potentially useful feature, an unnecessary restriction in my view.

Again I repeat, if the data is inaccessible (or at least not
accessible in a meaningful way) to the user why does the RfD
state that implementations have to use the R stack - I thought
that one main driver in the development of the ANS Forth
standard was not to mandate how features should be implemented.
A precedent has been set by LOCALS which may use the R stack.
Why not follow that and have N-SAVE and N-RESTORE that
temporarily save the data somewhere.

The more I think about this RfD the worse it seems.

Gerry

Andrew Haley

unread,
Mar 12, 2010, 5:45:38 AM3/12/10
to
Peter Knaggs <p...@bcs.org.uk> wrote:

> 15.6.2.aaaa N>R n-to-r TOOLS 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.
>
> 15.6.2.bbbb NR> n-r-from TOOLS 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.

N.B. : You don't have to require that this uses the return stack, just
say that the data is put *somewhere*, and that the return stack is
blocked until the items have been removed. This gives systems with a
small return stack a bit of wiggle room, and it makes alternatives
such as allocating a chunk of memory for the data standard.

Andrew.

Gerry

unread,
Mar 12, 2010, 6:12:31 AM3/12/10
to
On 11 Mar, 19:42, Bruce McFarling <agil...@netscape.net> wrote:
> On Mar 11, 1:01 pm, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
>
> > Given that you run a commercial organisation I can understand your
> > position but it seems to me that at times too much notice is taken
> > of legacy code when trying to improve the language.
>
> Why are you assuming that the role of the standard process is to
> improve the language *in general*, rather than to improve the language
> in the way that a communication standard can usefully improve a
> language.

It is a natural assumption and, regrettably, I suppose you are right
about the Forth 200X process. Unfortunately it leads to people who
want to "improve the language *in general*" getting frustrated with
the process and going away. Forth 200X *should* be more innovative
in my view. Perhaps an experimental section should be added.

>
> The role of the standards process is to ease the task of porting code

^
Insert "Forth 200X" above, it is not true of all standardisation
processes.

> from one system to another. Where there are not divergent practices in
> what behavior is called by what name, an existing practice can be
> standardized to allow more implementations to support that practice
> under that word and ease the porting of source code from systems
> possessing that behavior under that word.
>
> Where there are divergent practices, the role of the standard is to
> set out what actions can be communicated portably and what actions
> need special treatment.

and if they cannot be reconciled to do nothing about it except agree
to disagree, which is unfortunate to say the least. For an example
look at the discussions about directory paths etc where a solution
*is* needed.

>
> ========================
>
> What is the burden of proof for arguing that a behavior like this
> should be assigned a standard name and standard specification of the
> behavior referred to by that name is that there are implementers that
> do or will comply with the specification and there are program authors
> who do or will use the word as specified.

What an awful sentence (or is it a question?). I think I get the gist
but am unsure - I hope your lectures to students are clearer:-)


[...]

Gerry

Gerry

unread,
Mar 12, 2010, 6:18:17 AM3/12/10
to
On 12 Mar, 10:45, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

Well said

Gerry

Stephen Pelc

unread,
Mar 12, 2010, 6:31:48 AM3/12/10
to
On Fri, 12 Mar 2010 02:42:08 -0800 (PST), Gerry
<ge...@jackson9000.fsnet.co.uk> wrote:

>The more I think about this RfD the worse it seems.

What you forget is:
a) that N>R and NR> are already common practice,
b) they were designed to fulfill a need,
c) they were implemented independently with the same names,
d) they were adopted by other Forths,
e) beauty is for tailors.

While we have words such as SAVE-INPUT and RESTORE-INPUT,
we need N>R and NR>. Some programming is just ugly - we
have to find a least worst solution, and this is a solution
in common use.

Gerry

unread,
Mar 12, 2010, 7:20:40 AM3/12/10
to
On 12 Mar, 11:31, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Fri, 12 Mar 2010 02:42:08 -0800 (PST), Gerry
>
> <ge...@jackson9000.fsnet.co.uk> wrote:
> >The more I think about this RfD the worse it seems.
>
> What you forget is:
> a) that N>R and NR> are already common practice,

It doesn't seem to be in GForth, BigForth or the version
of Win32 Forth I use.

> b) they were designed to fulfill a need,

Sure

> c) they were implemented independently with the same names,

Naturally enough when that's what they do, particularly if
point d) is true and the others copied you.

> d) they were adopted by other Forths,

Hence points a) and c)

> e) beauty is for tailors.

I don't recollect saying anything about beauty

>
> While we have words such as SAVE-INPUT and RESTORE-INPUT,
> we need N>R and NR>.

Surely not. The need is to temporarily store N cells of
data somewhere, and to retrieve it later, not to push it
onto the return stack. Better to meet the need with N-SAVE
and N-RESTORE (or whatever you like to call them) and let
the implementer choose where. That wouldn't break existing
code which could carry on using N>R. N-SAVE and N-RESTORE
would just be synonyms in your systems.

> Some programming is just ugly - we
> have to find a least worst solution, and this is a solution
> in common use.

And a solution that goes against the ethos of the ANS Forth
standard i.e. not restricting implementation choices. E.g.
it allows locals to use the return stack but doesn't insist
on it. So why do this with N>R and NR>? What about processors
with a small return stack?

Gerry

Anton Ertl

unread,
Mar 12, 2010, 8:45:14 AM3/12/10
to
m...@iae.nl (Marcel Hendrix) writes:
>Bruce McFarling <agi...@netscape.net> writes Re: RfD: N>R and NR>
>[..]
>> POSTPONE: n>r ( xn..x1 +n -- ) ( R: -- x1 .. xn +n )
>> DUP BEGIN
>> DUP WHILE
>> 1- ROT >R
>> REPEAT DROP >R ;POSTPONE
>
>> I prefer n>r, even if POSTPONE: ;POSTPONE is available. If the
>> implementation has a quicker way implemented, I want to use that
>> instead.
>
>And for what would you use n>r ? We can't access anything
>that n>r pushes.

>
>OTOH the source for POSTPONE: ;POSTPONE looks extremely useful.

]] ... [[ is more versatile, and you can find the source in
macros.fs in <http://www.complang.tuwien.ac.at/forth/compat.zip>.

Why is it more versatile? It can do the same as "POSTPONE:":

: N>R ( n*x n -- R: n*x n )
]] DUP BEGIN
DUP WHILE
1- ROT >R
REPEAT DROP >R [[ ; IMMEDIATE

But it can also do things that would be cumbersome with POSTPONE:,
e.g.

: gen-innerproduct ( a[row][*] -- xt )
\ xt is of type ( b[*][column] -- n )
\ this would be a candidate for using ]] ... [[
>r :noname r>
0 ]] literal swap [[
row-size 0 do
]] dup @ [[
dup @ ]] literal * under+ cell+ [[
row-byte-size +
loop
drop
]] drop ; [[ ;

>How did you handle comments,

Enclose in [[ ... ]]

> multi-line parsing

Works

> literal

use [[ <number> ]] literal or shorter [[ <number> ]]L

>and locals handling,

Depends on what you want to do, but basically the only thing that
works is to use locals outside of ]] ... [[ (or inside [[ ... ]]).

> [ and ]

If you want to get back to normal compilation, use [[ ... ]], if you
really want to do something at compile time, use [[ [ ... ] ]].

>and other niceties in a portable
>way?

It's implementing in standard Forth, so it should be portable.

- 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
EuroForth 2009: http://www.euroforth.org/ef09/

J Thomas

unread,
Mar 12, 2010, 9:17:35 AM3/12/10
to
Stephen Pelc wrote:

> While we have words such as SAVE-INPUT and RESTORE-INPUT, we need N>R
> and NR>. Some programming is just ugly - we have to find a least worst
> solution, and this is a solution in common use.

The problem is SAVE-INPUT .

SAVE-INPUT gives you an indefinite-size chunk of data clogging the data
stack, so you need special stack-juggling to deal with it. You cannot so
anything useful with that clog except RESTORE-INPUT .

It's just bad design. What would Chuck Moore do?


Here's my immediate suggestion.

-----------
MARK-INPUT ( -- iid )

MARK-INPUT returns a one-cell token. It marks the current state of the
input buffer or source file.

NEST-INPUT ( iid -- )

NEST-INPUT consumes a one-cell token. It restores the state of the
current input buffer or source file to what it was when the iid token was
created. Ambiguous result if the input buffer which was current when iid
was created is not the current input buffer.
-----------


Let the Forth system save that information however it likes so long as
programmers can ignore it. It could save into an ALLOCATEd space, into a
BLOCK , into a previously allotted buffer in memory, etc. Whatever is
appropriate for the particular Forth system.

We have seen what happens when this useless information is left in a
useless pile on the data stack. We need N>R and NR> to juggle it onto the
return stack until the time comes to juggle it back.

Similarly with GET-ORDER and SET-ORDER .

98% of the time you are only interested in the top two stack items that
GET-ORDER gives, but you get copies of all of them regardless. If the wid
you want to add is already on the stack you have to juggle it. The new
words for adding one wid and removing one wid are potentially big
improvements. When you want to keep the whole list of wordlists, do you
really want to save that on the return stack in the faith that no
exception will be thrown? This cries out for a data structure.

But wouldn't it be best if it's a system data structure? That's the least
overhead. I'm not clear what functions people need. Save the current
search order so it can be restored later? Restore a search order?
Construct a new search order one wid at a time without adding them to the
current search order? Examine the current or a noncurrent search order
looking for a particular wid or a collection of them?

A bunch of wids on the stack is better than GET-ORDER because at least
there are multiple things you might choose to do with them. But if it
makes you use N>R and NR> then isn't that a sign there's something wrong?

Is N>R NR> really better than PICK and ROLL ?

Jerry Avins

unread,
Mar 12, 2010, 9:26:49 AM3/12/10
to

Yes. The benefit provided by the flexibility you want comes at what
seems to be excessive cost. The programmer must know if the data are to
be processed in chunks smaller than the whole and can store it
accordingly. The new words are intended to stash N cells in one
operation. The implementor should be free to take best advantage of the
machine architecture when writing them.

> Again I repeat, if the data is inaccessible (or at least not
> accessible in a meaningful way) to the user why does the RfD
> state that implementations have to use the R stack - I thought
> that one main driver in the development of the ANS Forth
> standard was not to mandate how features should be implemented.
> A precedent has been set by LOCALS which may use the R stack.
> Why not follow that and have N-SAVE and N-RESTORE that
> temporarily save the data somewhere.

Would you be happier if the RfD stated that the implementation *might*
use the return stack, so that for portability, the return stack should
be considered blocked? That seems reasonable to me.

> The more I think about this RfD the worse it seems.

Your privilege.

Jerry
--
Discovery consists of seeing what everybody has seen, and thinking what
nobody has thought. .. Albert Szent-Gyorgi
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Jerry Avins

unread,
Mar 12, 2010, 9:30:28 AM3/12/10
to
Stephen Pelc wrote:

...

> e) beauty is for tailors.

Julian Noble was fond of reminding us that Boltzmann had said, "Elegance
is for tailors."

...

Jerry
--
Discovery consists of seeing what everybody has seen, and thinking what
nobody has thought. .. Albert Szent-Gyorgi

ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

Jerry Avins

unread,
Mar 12, 2010, 9:39:21 AM3/12/10
to

Yes.

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Stephen Pelc

unread,
Mar 12, 2010, 9:37:56 AM3/12/10
to
On Fri, 12 Mar 2010 04:45:38 -0600, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>N.B. : You don't have to require that this uses the return stack, just
>say that the data is put *somewhere*, and that the return stack is
>blocked until the items have been removed. This gives systems with a
>small return stack a bit of wiggle room, and it makes alternatives
>such as allocating a chunk of memory for the data standard.

That's a good solution that doesn't break existing code or require
renaming. How about wordsmithing it yourself?

Anton Ertl

unread,
Mar 12, 2010, 9:31:31 AM3/12/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:

>>>Peter Knaggs <p...@bcs.org.uk> wrote:
>>>> RfD: N>R and NR>
>>>
>>>I think we discussed this already. It's still a great idea, and is
>>>well-supported by many Forths.
>>
>> What makes it great? To me it looks like a bad idea.
>
>They are very useful for their stated purpose, which is stashing the
>results of words with variable-length results such as GET-ORDER and
>SAVE-INPUT,

A very limited purpose, both because these words are rarely used
(especially in a way that requires stashing away the results), and
because the stashing is to the return stack, which limits the stashing
to stuff within a colon definition and also results in restrictions
wrt counted loops and locals.

GET-ORDER and SAVE-INPUT are unidiomatic in having a dynamic stack
depth with a count. My first reaction is that we should not
standardize more words with that kind of interface.

Alternatively, if we want to better support this kind of interface, we
should not start and end with moving to the return stack and back, we
should also have words for allocating and storing such things in
memory, and getting it back from memory. And maybe others. I am not
sure if we should go that way, though.

> awful to write in Standard Forth, and easy to write with
>carnal knowledge.

It's not awful to write in standard Forth, as the reference
implementation demonstrates. And I don't think that an implementation
with carncal knowledge of Gforth (or any other Forth system) will be
significantly shorter.

> What's not to like?

A word that will be rarely used, if at all, with an unidiomatic
interface? Why should I like it? And what makes it a great idea?

>Are we just going to have the 4 Feb 2009 discussion again?

I don't know. Message-Id or URL?

Andrew Haley

unread,
Mar 12, 2010, 10:31:48 AM3/12/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>Peter Knaggs <p...@bcs.org.uk> wrote:
>>>>> RfD: N>R and NR>
>>>>
>>>>I think we discussed this already. It's still a great idea, and is
>>>>well-supported by many Forths.
>>>
>>> What makes it great? To me it looks like a bad idea.
>>
>>They are very useful for their stated purpose, which is stashing the
>>results of words with variable-length results such as GET-ORDER and
>>SAVE-INPUT,
>
> A very limited purpose, both because these words are rarely used
> (especially in a way that requires stashing away the results), and
> because the stashing is to the return stack, which limits the
> stashing to stuff within a colon definition and also results in
> restrictions wrt counted loops and locals.

It's hard to argue about how useful stuff is. The system implementors
that already use it find it so, and it seems to me simple and
well-designed. AIUI this word is already in use in applications and
has proved to be approriate.

> Alternatively, if we want to better support this kind of interface, we
> should not start and end with moving to the return stack and back, we
> should also have words for allocating and storing such things in
> memory, and getting it back from memory. And maybe others. I am not
> sure if we should go that way, though.

I'm sure we shouldn't: that would be a case of needless
generalization. This is Forth, where the argument "if was have one
like this, we have to have a full set in order to be orthogonal"
doesn't apply.

>> awful to write in Standard Forth, and easy to write with
>>carnal knowledge.
>
> It's not awful to write in standard Forth, as the reference
> implementation demonstrates.

The RI is not written in standard Forth. It's one of these words that
can be trivial and super-fast with carnal knowledge and rather clumsy
without.

> And I don't think that an implementation with carncal knowledge of
> Gforth (or any other Forth system) will be significantly shorter.
>
>> What's not to like?
>
> A word that will be rarely used, if at all, with an unidiomatic
> interface? Why should I like it? And what makes it a great idea?
>
>>Are we just going to have the 4 Feb 2009 discussion again?

>
> I don't know. Message-Id or URL?

http://groups.google.co.uk/group/comp.lang.forth/browse_thread/thread/ebaaf0c57ddbbc58/331a52ccfacef340#331a52ccfacef340

Andrew.

David N. Williams

unread,
Mar 12, 2010, 10:39:14 AM3/12/10
to
On 3/12/10 5:36 AM, Andrew Haley wrote:
> [...]

>
> Let's not. I suggest
>
> : \\ postpone postpone ; immediate

Just a nit about the name. My impression is that the following
is common practice:

: \\ ( -- ) -1 parse 2drop BEGIN refill 0= UNTIL ;

-- David

David N. Williams

unread,
Mar 12, 2010, 10:53:28 AM3/12/10
to
On 3/12/10 6:12 AM, Gerry wrote:
> On 11 Mar, 19:42, Bruce McFarling<agil...@netscape.net> wrote:
>> On Mar 11, 1:01 pm, Gerry<ge...@jackson9000.fsnet.co.uk> wrote:
>>
>>> Given that you run a commercial organisation I can understand your
>>> position but it seems to me that at times too much notice is taken
>>> of legacy code when trying to improve the language.
>>
>> Why are you assuming that the role of the standard process is to
>> improve the language *in general*, rather than to improve the language
>> in the way that a communication standard can usefully improve a
>> language.
>
> It is a natural assumption and, regrettably, I suppose you are right
> about the Forth 200X process. Unfortunately it leads to people who
> want to "improve the language *in general*" getting frustrated with
> the process and going away. Forth 200X *should* be more innovative
> in my view. Perhaps an experimental section should be added.

Maybe an experimental section is a good idea, but I don't
*think* I'm the only one who believes that the best solution to
this problem is to make libraries a prominent part of Forth
culture and practice?

-- David

Bruce McFarling

unread,
Mar 12, 2010, 11:11:29 AM3/12/10
to
On Mar 12, 9:17 am, J Thomas <jethom...@gmail.com> wrote:
> Is N>R NR> really better than PICK and ROLL ?

To perform the task that N>R and NR> are performing? Quite definitely
better, because no deep stack access is required, while if it makes
for a more efficient primitive, it is permitted.

There are two basic cases: the sequence reversing N>R is faster or the
sequence maintaining N>R is faster. No matter which defined-sequence
is selected, implementations that fall in the other case will have a
slower N>R NR> ... and so will implement the alternate but give it a
different name, which is exactly opposite to the desired impact.

For Forth implementations for widely used processors, since the
existing implementations seem to be superior to anything I could ever
do, and most things I do are I/O-bound, all I want from a standard
word is that it is implemented and it works.

When not working, if I ever implement a system it will be in some
context where there is no implementation available that fits my goals.
Hence my apologies that when I think implementation, its always in
terms of fringe or wildly obsolete hardware.

But consider a hardware stack processor without accessible stack
indices and with only a couple of stash/count registers and access to
the top of each stack.

Each individual PICK or ROLL with n above 1 entails shifting all the
items above the target to the return stack, pulling or copying the
target. then pulling all the items back from the return stack, or IOW
"2(n-1)" stack>stack transfers. So a sequence-maintaining:
5 N>R

performed by successively rolling from the bottom is 8+6+4+2=20
additional stack>stack transfers in addition to the 5 stack transfers
of the actual value to where it goes. And the bigger "n", the bigger
the multiple.

Or consider hardware like the 65816, where one or both stacks will be
implemented in software and both stacks are accessible memory, where
using the hardware block move and computing the new offsets when done
will for fairly small "n" be faster than a sequence of (assuming that
the data stack builds down, so "INX" is a normal pop and "DEX" is
reading from a low:
LP: PHA
LDA DS,X
DEX
DEX
CPX TOP
BNE LP

... since the hardware versus software move is over 67% faster. Doing
it the slow way order-reversing is only slightly faster, but doing it
in hardware, order maintaining is faster if the stacks point in the
same direction and order reversing is faster if the stacks point
toward each other.

Bruce McFarling

unread,
Mar 12, 2010, 11:14:42 AM3/12/10
to
On Mar 12, 5:12 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> > The role of the standards process is to ease the task of porting
> > code from one system to another.

> I agree that the purpose of the standard is to standardize and not to
> improve the language.  Where there isn't sufficient common practice,
> there may indeed be language improvement, but that's not the goal.

> However, I don't agree that the role of the standards process is only
> to ease the task of porting code from one system to another.  I think
> it's also to specify a common understanding of what the language
> means.  Portablility may be a result of that.

OK:

The role of the standards process is to support communication
involving the language, including, importantly, easing the task of

Bruce McFarling

unread,
Mar 12, 2010, 11:22:37 AM3/12/10
to
On Mar 12, 6:12 am, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
> It is a natural assumption and, regrettably, I suppose you are right
> about the Forth 200X process. Unfortunately it leads to people who
> want to "improve the language *in general*" getting frustrated with
> the process and going away.

That is the "its not a silver bullet" argument, and IMO the correct
response is, "silver bullets only exist in fiction".

If I should specify that this is the role of a *communication*
standard, fine. But its generic for communication standards, and not
specific to Forth200x nor to computer language communication standards
in particular.

There is no problem if those uninterested in hammering out a
communication standard do not participate. The "go away in
frustration" would be problematic if "go away" means someone
abandoning working with the language, since the size of the language
using community is a public interest for any niche language.

OTOH, asking the systems houses to drive away customers is likely to
involve quite a bit more loss of users to the language community. And
at the same time, the answer is to get a clear idea of what a
communications standard process involves, and if you are not
interested in that, get involved in something else, like the FLAG
project.

Anton Ertl

unread,
Mar 12, 2010, 11:11:46 AM3/12/10
to
Gerry <ge...@jackson9000.fsnet.co.uk> writes:
>On 11 Mar, 19:42, Bruce McFarling <agil...@netscape.net> wrote:
>> Why are you assuming that the role of the standard process is to
>> improve the language *in general*, rather than to improve the language
>> in the way that a communication standard can usefully improve a
>> language.
>
>It is a natural assumption and, regrettably, I suppose you are right
>about the Forth 200X process. Unfortunately it leads to people who
>want to "improve the language *in general*" getting frustrated with
>the process and going away. Forth 200X *should* be more innovative
>in my view. Perhaps an experimental section should be added.

I think the RfD proposal process is more open-ended than the Forth200x
standardization process proper (the one with the committee that
results in a document), and can be used for experimental proposals.

So you could propose some experimental stuff that you don't expect to
be accepted by the committee, refine it with feedback from the
discussion, and finally freeze it in a CfV. Then see if it is picked
up by some systems, and maybe a few years down the road, the proposal
may have common practice, and may even take the additional steps
(although a more likely outcome is that there will be some conflict,
so there will be another proposal for the same functionality, with a
few words renamed, or some additional ambiguous conditions or
somesuch).

A reference implementation in standard Forth will help a lot with that
kind of stuff. Or alternatively, an implementation in one or more
Forth systems.

In some sense the X:xchar proposal went that way, except that it was
out there in the RfD stage for several years and revised before it was
frozen into a CfV. I think that in the meantime it has gotten enough
mindshare that it stands a chance at the committee, even though it was
completely new when it was first introduced.

>> The role of the standards process is to ease the task of porting code
> ^
>Insert "Forth 200X" above, it is not true of all standardisation
>processes.

As far as I know, it's true of most standardization processes of
existing programming languages. The only exception I can think of is
Java, where they invent heaps of new library stuff in each revision.

Bruce McFarling

unread,
Mar 12, 2010, 11:39:30 AM3/12/10
to
On Mar 12, 5:08 am, J Thomas <jethom...@gmail.com> wrote:
> I'm a little concerned that the only purpose for these commands is to
> enable extreme stack juggling.

Their purpose is precisely the opposite - to enable the avoidance of
extreme stack juggling. If their purposes was to enable extreme stack
juggling, there's be an NR@ or NDUP.

Without those, you can either get a chunk from elsewhere, stash it out
of the way, then put it back (sometimes internal system state like
input stack or search order stack, sometimes external from calling an
external function), build a chunk, stash it out of the way, then get
it back to use it, or get a chunk, stash it out of the way, then get
it back to discard what you don't need and use what do do.

If you are concerned about encouraging stack juggling, rather than
being agnostic about having the order specified on the R-stack, you
ought to be directly opposed to having the order specified on the R-
stack.

I'm agnostic on no order specified ... in the abstract, I'd be equally
happy with no order specified and with order-reversing specified. So
as long as its not specified to be stack-order-maintaining, that's
sufficient for me.

Since not specifying (1) enables the standard to be adopted and (2)
enables an implementation to do it the most efficient way for its
local circumstances (including, for hobbyist implementation, whichever
is easiest to code), I'm happy to go with no order specified.

Bruce McFarling

unread,
Mar 12, 2010, 12:08:09 PM3/12/10
to
On Mar 12, 9:26 am, Jerry Avins <j...@ieee.org> wrote:
> Would you be happier if the RfD stated that the implementation *might*
> use the return stack, so that for portability, the return stack should
> be considered blocked? That seems reasonable to me.

Having "( ... n )" is useful information on smaller datastacks, and if
all existing implementations do "( R: n*j n )", that is a proper
subset.

For memory unconstrained systems, its not an issue. For memory
constrained systems, if the datastack and the return stack face each
other in a stack block (think a memory block inside a FPGA), the
proposed specification always works, either an item at a time or else
with an internal block moveup and movedn.

And if an implementation *really* wants to stash the info elsewhere
and just leave retrieval info on the return stack ... well, hell, do
it, just call it something else.

Stash>R ( x*u u -- ) ( R: -- addr u )
R>Stash ( -- x*u u ) ( R: addr u -- )

Bruce McFarling

unread,
Mar 12, 2010, 12:11:41 PM3/12/10
to
On Mar 12, 8:45 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> ]] ... [[ is more versatile, and you can find the source in
> macros.fs in <http://www.complang.tuwien.ac.at/forth/compat.zip>.

I have a feeling that ]] and [[ may be different names for the factors
of POSTPONE: and ;POSTPONE, POSTPONE{ and }POSTPONE

Bruce McFarling

unread,
Mar 12, 2010, 12:28:03 PM3/12/10
to
On Mar 12, 9:37 am, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Fri, 12 Mar 2010 04:45:38 -0600, Andrew Haley
>
> <andre...@littlepinkcloud.invalid> wrote:
> >N.B. : You don't have to require that this uses the return stack, just
> >say that the data is put *somewhere*, and that the return stack is
> >blocked until the items have been removed.  This gives systems with a
> >small return stack a bit of wiggle room, and it makes alternatives
> >such as allocating a chunk of memory for the data standard.
>
> That's a good solution that doesn't break existing code or require
> renaming. How about wordsmithing it yourself?
>
> Stephen
>
> --
> 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

The tricky part of the casual wording would be misreading it so it
does not work like a stack operation. I think the text below specifies
that it is either on the return stack or acts like it is.


Proposal
========


15.6.2.aaaa N>R n-to-r TOOLS EXT

Interpretation: Interpretation semantics for this word are undefined.

Execution: ( x1..xn +n -- ) ( R: -- x*j +n )

Remove n+1 items and store them for later retrieval by R>N, such that
n is the top item on the return stack. The return stack may be used to
store the items. Until these items are retrieved, they will not be
overwritten by a following invocation of N>R.

15.6.2.bbbb NR> n-r-from TOOLS EXT

Interpretation: Interpretation semantics for this word are undefined.

Execution: ( -- xn..x1 n ) ( R: x*j n -- )

Retrieve the n+1 items stored by the invocation of N>R that placed n
on the return stack. n and any other information placed on the return
stack by N>R is removed from the return stack.

Ambiguous condition
NR> is used with data not stored by N>R.

Elizabeth D Rather

unread,
Mar 12, 2010, 2:08:19 PM3/12/10
to
Gerry wrote:
> On 11 Mar, 19:42, Bruce McFarling <agil...@netscape.net> wrote:
...

>> Why are you assuming that the role of the standard process is to
>> improve the language *in general*, rather than to improve the language
>> in the way that a communication standard can usefully improve a
>> language.
>
> It is a natural assumption and, regrettably, I suppose you are right
> about the Forth 200X process. Unfortunately it leads to people who
> want to "improve the language *in general*" getting frustrated with
> the process and going away. Forth 200X *should* be more innovative
> in my view. Perhaps an experimental section should be added.
>
>> The role of the standards process is to ease the task of porting code
> ^
> Insert "Forth 200X" above, it is not true of all standardisation
> processes.

From time to time other standards bodies have undertaken to "improve
the language." When the ANS Forth group was under way, ANSI sent us all
the messages being circulated by other language groups. There was a
firestorm beyond belief over the recently released FORTRAN standard, and
a somewhat later revision to the COBOL standard generated massive
(multi-million$) lawsuits against its TC (I don't know how they were
resolved).

It is ANSI's official position that standards should be conservative,
reflect common practice as much as necessary, should represent a
consensus from a group representing both the implementor and user
communities, should be subject to full public review, and all public
review comments (which pass through ANSI) should be responded to
responsibly.

IMO the place for innovations that "improve the language in general" is
in the implementor community. All of us try things to improve our
systems, and the more successful innovations either occur spontaneously
in multiple implementations (and thus become "common practice" and
subject to future standardization) or are copied from their origins.
colorFORTH, for example, is a very innovative approach that some folks
are experimenting with. If it is a successful innovation (meaning more
and more people elect to use it in commercial projects) it may influence
future Forth standards. So far that doesn't appear to be the case.

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."
==================================================

Stephen Pelc

unread,
Mar 12, 2010, 2:12:40 PM3/12/10
to
On Fri, 12 Mar 2010 10:53:28 -0500, "David N. Williams"
<will...@umich.edu> wrote:

>Maybe an experimental section is a good idea, but I don't
>*think* I'm the only one who believes that the best solution to
>this problem is to make libraries a prominent part of Forth
>culture and practice?

Agreed. See
http://soton.mpeforth.com/flag/

Stephen

--
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

Stephen Pelc

unread,
Mar 12, 2010, 2:16:50 PM3/12/10
to
On Fri, 12 Mar 2010 09:28:03 -0800 (PST), Bruce McFarling
<agi...@netscape.net> wrote:

>15.6.2.aaaa N>R n-to-r TOOLS EXT
>
>Interpretation: Interpretation semantics for this word are undefined.
>
>Execution: ( x1..xn +n -- ) ( R: -- x*j +n )
>
>Remove n+1 items and store them for later retrieval by R>N, such that

.......................................................NR>


>n is the top item on the return stack. The return stack may be used to
>store the items. Until these items are retrieved, they will not be
>overwritten by a following invocation of N>R.
>
>15.6.2.bbbb NR> n-r-from TOOLS EXT
>
>Interpretation: Interpretation semantics for this word are undefined.
>
>Execution: ( -- xn..x1 n ) ( R: x*j n -- )
>
>Retrieve the n+1 items stored by the invocation of N>R that placed n
>on the return stack. n and any other information placed on the return
>stack by N>R is removed from the return stack.
>
>Ambiguous condition
>NR> is used with data not stored by N>R.

Please update and send this to Peter Knaggs.

Stephen


--
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

Bruce McFarling

unread,
Mar 12, 2010, 3:01:19 PM3/12/10
to
On Mar 12, 2:16 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> .......................................................NR>

{Oops} Done.

Elizabeth D Rather

unread,
Mar 12, 2010, 3:16:54 PM3/12/10
to
Bruce McFarling wrote:

Minor editorial fixes:

> Proposal
> ========
> 15.6.2.aaaa N>R n-to-r TOOLS EXT
>
> Interpretation: Interpretation semantics for this word are undefined.
>
> Execution: ( x1..xn +n -- ) ( R: -- x*j +n )
>
> Remove n+1 items and store them for later retrieval by R>N, such that

...later retrieval by NR> ...

> n is the top item on the return stack. The return stack may be used to
> store the items. Until these items are retrieved, they will not be
> overwritten by a following invocation of N>R.

...overwritten by a subsequent invocation of N>R...

>
> 15.6.2.bbbb NR> n-r-from TOOLS EXT
>
> Interpretation: Interpretation semantics for this word are undefined.
>
> Execution: ( -- xn..x1 n ) ( R: x*j n -- )
>
> Retrieve the n+1 items stored by the invocation of N>R that placed n
> on the return stack. n and any other information placed on the return
> stack by N>R is removed from the return stack.
>
> Ambiguous condition
> NR> is used with data not stored by N>R.

...An ambiguous condition exists if ...

I don't see any language concerning the fact that the return stack is
blocked (i.e., you can't make a net change to the return stack between
N>R and NR>).

Is it worth explicitly stating that the order of items is not
guaranteed? At the very least, I'd think you'd want a advisory in an
appendix against trying to access subsets of the block.

Bruce McFarling

unread,
Mar 12, 2010, 5:32:51 PM3/12/10
to
On Mar 12, 3:16 pm, Elizabeth D Rather <erat...@forth.com> wrote:

Yes, subsequent invocation, I realize that while cycling home this
evening. I caught invocation in the edited version I sent, but not
subsequent.

> I don't see any language concerning the fact that the return stack is
> blocked (i.e., you can't make a net change to the return stack between
> N>R and NR>).

That is specified in:

( R: -- x*j u ) and ( R: x*j u -- )

since there is no way to find out if "j" is 0, 1, or u, there is no
way to portably do anything further up the R-stack until NR> clears it
out ... but it could be added to the text part of the specification as
well.

Peter Knaggs

unread,
Mar 12, 2010, 8:49:07 PM3/12/10
to
On Fri, 12 Mar 2010 19:16:50 -0000, Stephen Pelc <steph...@mpeforth.com>
wrote:

>
> Please update and send this to Peter Knaggs.

Hay, how come I get the joy of editing your proposal. It's bad enough
having to edit the final version into something that actually works in
the final document.

--
Peter Knaggs

J Thomas

unread,
Mar 13, 2010, 2:27:58 AM3/13/10
to
Bruce McFarling wrote:
> J Thomas <jethom...@gmail.com> wrote:

>> Is N>R NR> really better than PICK and ROLL ?
>
> To perform the task that N>R and NR> are performing? Quite definitely
> better, because no deep stack access is required, while if it makes for
> a more efficient primitive, it is permitted.

I guess I did not get my meaning across. Sure, N>R does N>R better than
ROLL does N>R .

Many Forth programmers say that use of PICK and ROLL is usually a sign of
poor Forth practice. It's good to have them for occasions when you don't
have time to find a good way to get the job done, but when you use them
don't you feel like there has been a mistake somewhere? At least I do.

N>R is designed to be used only when you have a blog of items on the data
stack which is just plain in your way and you need to get it out of your
way. It is used only as an extreme form of stack juggling.

I don't particularly object to standardizing N>R NR> -- we have PICK and
ROLL after all -- but wouldn't it make sense to spend more effort on
avoiding the things that make them necessary?

At this point I see three times to use them.

1. SAVE-INPUT
2. GET-ORDER
3. Bad practice.

Elizabeth D Rather

unread,
Mar 13, 2010, 2:53:42 AM3/13/10
to
J Thomas wrote:
...

> At this point I see three times to use them.
>
> 1. SAVE-INPUT
> 2. GET-ORDER
> 3. Bad practice.

Your experience is limited. There are a host of issues such as Windows
calls that involve lengthy arrays of parameters that are awkward to deal
with. SAVE-INPUT and GET-ORDER barely scratch the surface, and it's
impractical to make up new pairs of words for each of these situations.

If you have a paid version of SwiftForth or VFX, you could look at all
the instances where N>R is used and get a feel for what they are.

Gerry

unread,
Mar 13, 2010, 5:18:14 AM3/13/10
to

Yes, that seems to be the way it is going

Gerry

unread,
Mar 13, 2010, 5:29:19 AM3/13/10
to
On 12 Mar, 16:22, Bruce McFarling <agil...@netscape.net> wrote:
> On Mar 12, 6:12 am, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
>
> > It is a natural assumption and, regrettably, I suppose you are right
> > about the Forth 200X process. Unfortunately it leads to people who
> > want to "improve the language *in general*" getting frustrated with
> > the process and going away.
>
> That is the "its not a silver bullet" argument, and IMO the correct
> response is, "silver bullets only exist in fiction".

I'm don't know what you mean by this. If you think it means that my
statements lead to the conclusion that the Forth 200X process is a
waste
of time; or that I won't take further part then you are very much
mistaken. I was simply remembering that 2 or 3 people over recent
years
have declared that they have lost interest in Forth 200X.

>
> If I should specify that this is the role of a *communication*
> standard, fine. But its generic for communication standards, and not
> specific to Forth200x nor to computer language communication standards
> in particular.
>
> There is no problem if those uninterested in hammering out a
> communication standard do not participate. The "go away in
> frustration" would be problematic if "go away" means someone
> abandoning working with the language,  since the size of the language
> using community is a public interest for any niche language.
>
> OTOH, asking the systems houses to drive away customers is likely to
> involve quite a bit more loss of users to the language community. And
> at the same time, the answer is to get a clear idea of what a
> communications standard process involves, and if you are not
> interested in that, get involved in something else, like the FLAG
> project.

I've already volunbteered to help - it seems to be stalled at present

Gerry

Anton Ertl

unread,
Mar 13, 2010, 5:43:03 AM3/13/10
to
Bruce McFarling <agi...@netscape.net> writes:
>On Mar 12, 8:45=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

Maybe. In any case, since ]] ... [[ is more versatile, POSTPONE: and
;POSTONE are not needed. And ]] ... [[ was invented (by IIRC
J. Thomas) at least 15 years ago, and has been implemented in Gforth
since 0.6 (2003). It also makes for more readable code than POSTPONE{
... }POSTPONE.

Stephen Pelc

unread,
Mar 13, 2010, 6:26:48 AM3/13/10
to
On Sat, 13 Mar 2010 01:49:07 -0000, "Peter Knaggs" <p...@bcs.org.uk>
wrote:

>> Please update and send this to Peter Knaggs.
>
>Hay, how come I get the joy of editing your proposal. It's bad enough
>having to edit the final version into something that actually works in
>the final document.

Oops! I thought that this one had gone to you. I'll update and reissue
in my "ample spare time".

J Thomas

unread,
Mar 13, 2010, 9:51:16 AM3/13/10
to
Elizabeth D Rather wrote:
> J Thomas wrote:
> ...
>> At this point I see three times to use them.
>>
>> 1. SAVE-INPUT
>> 2. GET-ORDER
>> 3. Bad practice.
>
> Your experience is limited. There are a host of issues such as Windows
> calls that involve lengthy arrays of parameters that are awkward to deal
> with.

Thank you! That was the missing piece. Things like Windows calls where
the Forth user or Forth implementer have no choice in the matter.

> SAVE-INPUT and GET-ORDER barely scratch the surface, and it's
> impractical to make up new pairs of words for each of these situations.

OK, that's reasonable. I still believe that SAVE-INPUT and GET-ORDER are
badly designed. They could be replaced by better words. But N>R and NR>
are needed for things like system calls that are themselves poorly
designed but outside Forth's control. So now I have:

1. SAVE-INPUT
2. GET-ORDER
3. Bad practice

4. Unavoidable complexity

Anton Ertl

unread,
Mar 13, 2010, 9:47:00 AM3/13/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>>Peter Knaggs <p...@bcs.org.uk> wrote:
>>>>>> RfD: N>R and NR>
>>>>>
>>>>>I think we discussed this already. It's still a great idea, and is
>>>>>well-supported by many Forths.
>>>>
>>>> What makes it great? To me it looks like a bad idea.
>>>
>>>They are very useful for their stated purpose, which is stashing the
>>>results of words with variable-length results such as GET-ORDER and
>>>SAVE-INPUT,
>>
>> A very limited purpose, both because these words are rarely used
>> (especially in a way that requires stashing away the results), and
>> because the stashing is to the return stack, which limits the
>> stashing to stuff within a colon definition and also results in
>> restrictions wrt counted loops and locals.
>
>It's hard to argue about how useful stuff is.

And yet you did so.

>The system implementors
>that already use it find it so, and it seems to me simple and
>well-designed.

I have serious doubts about the quality of the design. As far as
simplicity is concerned, it's much more complex than any of the
existing stack and return stack words, both in concept and in
implementation, with the possible exception of ROLL.

>AIUI this word is already in use in applications and
>has proved to be approriate.

That does not make it a great idea. E.g., STATE exists in many
systems and is used in many applications, and it's still a bad idea.

>> Alternatively, if we want to better support this kind of interface, we
>> should not start and end with moving to the return stack and back, we
>> should also have words for allocating and storing such things in
>> memory, and getting it back from memory. And maybe others. I am not
>> sure if we should go that way, though.
>
>I'm sure we shouldn't: that would be a case of needless
>generalization. This is Forth, where the argument "if was have one
>like this, we have to have a full set in order to be orthogonal"
>doesn't apply.

My argument is more along the lines of: If we don't have the others,
we probably should not have this less useful word, either.

>>> awful to write in Standard Forth, and easy to write with
>>>carnal knowledge.
>>
>> It's not awful to write in standard Forth, as the reference
>> implementation demonstrates.
>
>The RI is not written in standard Forth.

True; another weakness of the proposal. Anyway, a fairly
straightforward variation of the reference implementation has been
posted which is written in standard Forth
<9277159...@frunobulax.edu>:

: n>r ( xn..x1 +n -- ) ( R: -- x1 .. xn +n )
POSTPONE DUP
POSTPONE BEGIN POSTPONE DUP
POSTPONE WHILE POSTPONE 1- POSTPONE ROT POSTPONE >R
POSTPONE REPEAT
POSTPONE DROP POSTPONE >R ; IMMEDIATE

: nr> ( -- xn..x1 +n ) ( R: x1 .. xn +n -- )
POSTPONE R@
POSTPONE BEGIN POSTPONE R@
POSTPONE WHILE POSTPONE R> POSTPONE 1-
POSTPONE R> POSTPONE SWAP
POSTPONE >R POSTPONE SWAP
POSTPONE REPEAT
POSTPONE R> POSTPONE DROP ; IMMEDIATE

>It's one of these words that
>can be trivial and super-fast with carnal knowledge and rather clumsy
>without.

With carnal knowledge it will be hardly simpler.

>>>Are we just going to have the 4 Feb 2009 discussion again?
>
>>
>> I don't know. Message-Id or URL?
>
>http://groups.google.co.uk/group/comp.lang.forth/browse_thread/thread/ebaaf0c57ddbbc58/331a52ccfacef340#331a52ccfacef340

I have not reread all of that discussion, but my own contributions to
that discussion were along different lines. That's because I think
that nobody at the time claimed that this proposal was a "great idea".

Anton Ertl

unread,
Mar 13, 2010, 10:11:02 AM3/13/10
to
"Peter Knaggs" <p...@bcs.org.uk> writes:

>On Wed, 10 Mar 2010 18:41:43 -0000, Andrew Haley
><andr...@littlepinkcloud.invalid> wrote:
>>
>> Are we just going to have the 4 Feb 2009 discussion again?
>
>Given the problems I have had with substitute, I decided to post this as
>an RfD with a view to taking it to a CfV next week if there is little
>discussion.
>
>I did however make one changed based on the previous discussion. I have
>moved the words from CORE EXT to TOOLS EXT.
>
>I also like Leon Wagner suggestions that the signature should be:
>
>N>R ( n*x n -- ) ( R: -- n*x n )
>NR> ( -- n*x n ) ( R: n*x n -- )

Certainly not n. Either +n, or better u. See
http://groups.google.co.uk/group/comp.lang.forth/msg/3713b3b26507ed07.

Anton Ertl

unread,
Mar 13, 2010, 10:12:10 AM3/13/10
to
"Peter Knaggs" <p...@bcs.org.uk> writes:
>RfD: N>R and NR>
>4 February 2009, Stephen Pelc

Judging from the date and the lack of change notes, it looks like the
feedback after the first posting of this proposal has been ignored.
This seems to be customary for this proponent who takes pride in doing
his homework.

Hmm, not quite: This time around, the test section is not even "TBD",
but is missing altogether.

Just to remind you, that discussion was
<http://groups.google.co.uk/group/comp.lang.forth/browse_thread/thread/ebaaf0c57ddbbc58/331a52ccfacef340>
and my feedback was
http://groups.google.co.uk/group/comp.lang.forth/msg/20a0d9eb58b5d45f
http://groups.google.co.uk/group/comp.lang.forth/msg/3713b3b26507ed07

To make it easier for you, here's the text of these two postings:

Date: Thu, 12 Feb 2009 16:48:02 GMT
Message-ID: <2009Feb1...@mips.complang.tuwien.ac.at>

stephen...@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.

==================================================================

Date: Fri, 13 Feb 2009 14:15:02 GMT
Message-ID: <2009Feb1...@mips.complang.tuwien.ac.at>

stephen...@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.

Anton Ertl

unread,
Mar 13, 2010, 10:25:45 AM3/13/10
to
J Thomas <jeth...@gmail.com> writes:

>Elizabeth D Rather wrote:
>> Your experience is limited. There are a host of issues such as Windows
>> calls that involve lengthy arrays of parameters that are awkward to deal
>> with.

I don't see how N>R and NR> help here. Could you give an example?

>OK, that's reasonable. I still believe that SAVE-INPUT and GET-ORDER are
>badly designed.

Especially SAVE-INPUT. I don't think a portable program has ever used
it for a useful purpose.

>They could be replaced by better words. But N>R and NR>
>are needed for things like system calls that are themselves poorly
>designed but outside Forth's control. So now I have:
>
>1. SAVE-INPUT
>2. GET-ORDER
>3. Bad practice
>4. Unavoidable complexity

Maybe 4 is 3a.

J Thomas

unread,
Mar 13, 2010, 11:41:24 AM3/13/10
to
Anton Ertl wrote:

> I have serious doubts about the quality of the design. As far as
> simplicity is concerned, it's much more complex than any of the existing
> stack and return stack words, both in concept and in implementation,
> with the possible exception of ROLL.

Yes. But if it will go into an optional wordset, then it can be a bad
idea and still there can be value in standardizing it, so that the people
who want it can all be on the same page.



>>AIUI this word is already in use in applications and has proved to be
>>approriate.
>
> That does not make it a great idea. E.g., STATE exists in many systems
> and is used in many applications, and it's still a bad idea.

Agreed. But nobody has to make state-smart words, except for the few that
are standard. Actually, state-smart words are not that bad provided they
are used only in the ways that they work and never in the ways that they
don't work. My complaint is that there are things that are occasionally
worth doing that state-smart words do badly, and there is no portable
alternative.

Well, suppose that the data stack and the return stack both build
downward, and we know where the "top" of return stack and "top" of data
stack are. Could we do:

: N>R ( xn..x1 +n -- ) ( R: *xn +n )
SP@ OVER
RP@ SWAP CELLS DUP NEGATE RP +! MOVE R@ CElLS SP +! ;

No, because the return stack is being used for calls and returns by the
commands that move things onto the return stack. Maybe there's a good way
to fix that, I haven't tried.

But a primitive could do something very similar to this, and it would be
far simpler and efficient compared to the standard Forth version.

So regardless whether this is worth doing, it's less wasteful to do it as
a system word than as a portable Forth word.

There's an aphorism that goes "If it isn't worth doing at all, then it
isn't worth doing well.". I don't think that applies here. If somebody
else is going to do it, then we might as well give them the chance to do
it well regardless whether it's worth doing.

If it isn't worth doing but it doesn't do any great harm, then it isn't
worth arguing with people who want to do it that they shouldn't do it.

Anton Ertl

unread,
Mar 13, 2010, 11:50:47 AM3/13/10
to
J Thomas <jeth...@gmail.com> writes:
>Anton Ertl wrote:
>
>> I have serious doubts about the quality of the design. As far as
>> simplicity is concerned, it's much more complex than any of the existing
>> stack and return stack words, both in concept and in implementation,
>> with the possible exception of ROLL.
>
>Yes. But if it will go into an optional wordset, then it can be a bad
>idea and still there can be value in standardizing it, so that the people
>who want it can all be on the same page.

Yes. But that does not make it a great idea.

Try it with the assumption of the reference implementation that you
can get the return address out of the way with R>...>R (or use the
POSTPONEing approach again). But also get rid of the "RP +!" and "SP
+!". These are not variables in serious Forth systems, and the
traditional words for changing them are RP! and SP!.

>But a primitive could do something very similar to this, and it would be
>far simpler and efficient compared to the standard Forth version.

Please implement it as a primitive for a Forth system of your choice
and show me how it is "far" simpler. And for Forth systems that
compile to decent native code, it also won't be "far" faster, if at
all.

>So regardless whether this is worth doing, it's less wasteful to do it as
>a system word than as a portable Forth word.

It's a waste of the system implementor's time to optimize it for the
system when a portable solution exists.

>If it isn't worth doing but it doesn't do any great harm, then it isn't
>worth arguing with people who want to do it that they shouldn't do it.

Maybe. But I guess we would not have most of the discussions about
the standard if everyone subscribed to this point of view.

Gerry

unread,
Mar 13, 2010, 12:14:01 PM3/13/10
to
On 13 Mar, 15:25, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:

> J Thomas <jethom...@gmail.com> writes:
> >Elizabeth D Rather wrote:
> >> Your experience is limited. There are a host of issues such as Windows
> >> calls that involve lengthy arrays of parameters that are awkward to deal
> >> with.
>
> I don't see how N>R and NR> help here. Could you give an example?
>
> >OK, that's reasonable. I still believe that SAVE-INPUT and GET-ORDER are
> >badly designed.
>
> Especially SAVE-INPUT. I don't think a portable program has ever used
> it for a useful purpose.
>

Well take a look at:
http://www.qlikz.org/forth/library/lambda.html

which I think is portable, at least it runs on several systems,
but, of course, may not pass your "useful purpose" condition.

Less conveniently FILE-POSITION and REPOSITION-FILE could probably
have been used but then it wouldn't work with blocks as an
input source without additional code - which is why SAVE-INPUT
is useful.

[...]

Gerry

J Thomas

unread,
Mar 13, 2010, 12:46:13 PM3/13/10
to
Anton Ertl wrote:
> J Thomas <jeth...@gmail.com> writes:

>>: N>R ( xn..x1 +n -- ) ( R: *xn +n )
>> SP@ OVER
>> RP@ SWAP CELLS DUP NEGATE RP +! MOVE R@ CElLS SP +! ;
>>
>>No, because the return stack is being used for calls and returns by the
>>commands that move things onto the return stack. Maybe there's a good
>>way to fix that, I haven't tried.
>
> Try it with the assumption of the reference implementation that you can
> get the return address out of the way with R>...>R (or use the
> POSTPONEing approach again). But also get rid of the "RP +!" and "SP
> +!". These are not variables in serious Forth systems, and the
> traditional words for changing them are RP! and SP!.

It was only pseudocode, I don't think there's any portable way to do that
sort of thing.

>>But a primitive could do something very similar to this, and it would be
>>far simpler and efficient compared to the standard Forth version.
>
> Please implement it as a primitive for a Forth system of your choice and
> show me how it is "far" simpler. And for Forth systems that compile to
> decent native code, it also won't be "far" faster, if at all.

OK, you have a strong point there. MOVE is potentially far more efficient
than a BEGIN loop which moves things a cell at a time. But in a primitive
the difference is not so big.

>>If it isn't worth doing but it doesn't do any great harm, then it isn't
>>worth arguing with people who want to do it that they shouldn't do it.
>
> Maybe. But I guess we would not have most of the discussions about the
> standard if everyone subscribed to this point of view.

Yes, but imagine what the discussions would be like if nobody did it. ;)

Anton Ertl

unread,
Mar 13, 2010, 1:28:28 PM3/13/10
to
J Thomas <jeth...@gmail.com> writes:
>Anton Ertl wrote:
>> J Thomas <jeth...@gmail.com> writes:
>
>>>: N>R ( xn..x1 +n -- ) ( R: *xn +n )
>>> SP@ OVER
>>> RP@ SWAP CELLS DUP NEGATE RP +! MOVE R@ CElLS SP +! ;
>>>
>>>No, because the return stack is being used for calls and returns by the
>>>commands that move things onto the return stack. Maybe there's a good
>>>way to fix that, I haven't tried.
>>
>> Try it with the assumption of the reference implementation that you can
>> get the return address out of the way with R>...>R (or use the
>> POSTPONEing approach again). But also get rid of the "RP +!" and "SP
>> +!". These are not variables in serious Forth systems, and the
>> traditional words for changing them are RP! and SP!.
>
>It was only pseudocode, I don't think there's any portable way to do that
>sort of thing.

Then do it for one system. However, I think that you can do it for
the systems that have SP@ RP@ SP! RP!, the return address as a single
cell on the return stack, and downwards growing stacks. That probably
covers several systems (including Gforth), and should be portable
between these systems.

>>>But a primitive could do something very similar to this, and it would be
>>>far simpler and efficient compared to the standard Forth version.
>>
>> Please implement it as a primitive for a Forth system of your choice and
>> show me how it is "far" simpler. And for Forth systems that compile to
>> decent native code, it also won't be "far" faster, if at all.
>
>OK, you have a strong point there. MOVE is potentially far more efficient
>than a BEGIN loop which moves things a cell at a time.

No. MOVE does not know that it moves cells, and so has to first
exclude or cater for misalignment and odd sizes. It could then move 2
or 4 cells per loop iteration, but if there are only 3 cells to move,
that won't help much, and probably won't make up for the overhead.
And for large amounts of data, the performance is limited by the
memory system anyway.

Peter Knaggs

unread,
Mar 13, 2010, 3:43:04 PM3/13/10
to
On Fri, 12 Mar 2010 22:32:51 -0000, Bruce McFarling <agi...@netscape.net>
wrote:

The stack descriptions should read:

N>R ( i*x n -- ) ( R: -- j*x n )
NR> ( -- i*x n ) ( R: j*x n -- )

Using "i" and "j" breaks the implicit indication that they are the
same number of items. Thus allowing the a system to store the items
in a buffer and only place the address of that buffer on the return
stack. As "j" is an unknown value, this has the effect of blocking
any acrobatics with the return stack.

Also note that the multiplier goes before the type according to
table 3.1 (data types).

An alternative would be to define an opaque type along the lines of
loop-sys but that would mean adding it to table 3.1.

--
Peter Knaggs

Bruce McFarling

unread,
Mar 13, 2010, 4:32:05 PM3/13/10
to
On Mar 13, 2:27 am, J Thomas <jethom...@gmail.com> wrote:
> I guess I did not get my meaning across. Sure, N>R does N>R better than
> ROLL does N>R .

> Many Forth programmers say that use of PICK and ROLL is usually a sign of
> poor Forth practice. It's good to have them for occasions when you don't
> have time to find a good way to get the job done, but when you use them
> don't you feel like there has been a mistake somewhere? At least I do.

I don't use them.

> N>R is designed to be used only when you have a blog of items on the data
> stack which is just plain in your way and you need to get it out of your
> way. It is used only as an extreme form of stack juggling.

When you say, "only as an extreme form of stack juggling", what do you
*mean* by stack juggling? Do you include writing a chunk of data to a
structure and then later retrieving it exactly as you wrote it,
"juggling"?

I have a mental picture of an actual juggler, and balls or plates
moving through the air in an intricate pattern which falls apart if
the coordination of the hands or execution of either hand fails.

>R >R >R >R >R foo bar >stash R> R> R> R> R>

Its repetitive and boring, but there's no juggling happening. Its like
putting the balls into a canister, setting them to one side, then
getting them out of the canister again, or putting the plates in a
box, setting it under the table, then getting the plates out of the
box again.

Its the opposite of juggling, and indeed the kind of repetitive,
boring task that they invented these "computer" things to do for us.

> I don't particularly object to standardizing N>R NR> -- we have PICK and
> ROLL after all -- but wouldn't it make sense to spend more effort on
> avoiding the things that make them necessary?

> At this point I see three times to use them.
> 1. SAVE-INPUT
> 2. GET-ORDER
> 3. Bad practice.

Suppose you have a set of data that you are going to use atomically -
for example, for a function call. I see nothing that is
*intrinsically* bad practice about building one chunk of the function
call, setting it to one side, build the rest of the function call,
than getting the part you built first back.

If the external function call interface involves handing an address of
a structure to the external function, or using an external structure
(say, CP/M 2.2 and FCB's), then of course you build it in the
structure and its all nicely random access.

If it involves calling the function with the parameters on the top of
the Forth datastack, then you do that. In authoring the application, I
have the information I need to hand to the external function, and the
mechanism the implementation provides for making the call.

Bruce McFarling

unread,
Mar 13, 2010, 4:42:12 PM3/13/10
to
On Mar 13, 5:29 am, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
> I was simply remembering that 2 or 3 people over recent years have declared that they have lost interest in Forth 200X.

"2 or 3 people over recent years have declared they have lost interest
in Forth 200x"
... an observation.

"Unfortunately it leads to people who want to "improve the language

*in general*" getting frustrated with the process and going away.".

... is a couple of claims in addition to the observation.

"Going away" in response to frustration with the process suggests
unrealistic expectations coming in, and its just as much the
unrealistic expectations that caused the going away as the
frustration. After all, hammering out a communication protocol between
already existing systems in use is an intrinsically frustrating
process.

Since the frustration is intrinsic, its the unrealistic expectations
coming into the process that can be addressed.

Bruce McFarling

unread,
Mar 13, 2010, 4:46:52 PM3/13/10
to
On Mar 13, 11:50 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> Please implement it as a primitive for a Forth system of your choice
> and show me how it is "far" simpler.  And for Forth systems that
> compile to decent native code, it also won't be "far" faster, if at
> all.

But won't it be far more compact? After all, the primitive can take
advantage of carnal knowledge of what is the initial state of the
return stack on entering a primitive to *do* the process in the
primitive rather than compiling it into each user of NR> and N>R.

Bruce McFarling

unread,
Mar 13, 2010, 4:53:26 PM3/13/10
to
On Mar 13, 5:43 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> Maybe.  In any case, since ]] ... [[ is more versatile, POSTPONE: and


> ;POSTONE are not needed.  And ]] ... [[ was invented (by IIRC
> J. Thomas) at least 15 years ago, and has been implemented in Gforth
> since 0.6 (2003).  It also makes for more readable code than POSTPONE{
> ... }POSTPONE.

For me, the bracketing points the wrong way, and there is nothing
in ]] and [[ to infer that its about POSTPONE rather than, say
[[ ... ]] being about interpreting the words in some distinctive
way ... a subordinate or superordinate system when two systems are
connected, or the shell.

Anyway, *because* POSTPONE{ }POSTPONE is versatile, POSTPONE:
and ;POSTPONE does not have to be, they can be simple for the most
common form of postpone macro.

Bruce McFarling

unread,
Mar 13, 2010, 4:55:12 PM3/13/10
to
On Mar 13, 6:26 am, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Sat, 13 Mar 2010 01:49:07 -0000, "Peter Knaggs" <p...@bcs.org.uk>
> wrote:
>
> >> Please update and send this to Peter Knaggs.
>
> >Hay, how come I get the joy of editing your proposal.  It's bad enough
> >having to edit the final version into something that actually works in
> >the final document.
>
> Oops! I thought that this one had gone to you. I'll update and reissue
> in my "ample spare time".
>
> Stephen
>
> --
> 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

Luckily I emailed to both, so put those changes in the stack comments.

Andrew Haley

unread,
Mar 13, 2010, 5:23:34 PM3/13/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>>>Peter Knaggs <p...@bcs.org.uk> wrote:
>>>>>>> RfD: N>R and NR>
>>>>>>
>>>>>>I think we discussed this already. It's still a great idea, and is
>>>>>>well-supported by many Forths.
>>>>>
>>>>> What makes it great? To me it looks like a bad idea.
>>>>
>>>>They are very useful for their stated purpose, which is stashing the
>>>>results of words with variable-length results such as GET-ORDER and
>>>>SAVE-INPUT,
>>>
>>> A very limited purpose, both because these words are rarely used
>>> (especially in a way that requires stashing away the results), and
>>> because the stashing is to the return stack, which limits the
>>> stashing to stuff within a colon definition and also results in
>>> restrictions wrt counted loops and locals.
>>
>>It's hard to argue about how useful stuff is.
>
> And yet you did so.

It takes two to argue! What I'm saying is that this is almost
entirely a matter of opinion. However, the use of these words in real
applications has been described by both MPE and Forth Inc.

>>AIUI this word is already in use in applications and
>>has proved to be approriate.
>
> That does not make it a great idea. E.g., STATE exists in many
> systems and is used in many applications, and it's still a bad idea.

That's a good point, but the evil of STATE gets everywhere, whereas
whatever small amount of evil N>R has, it's very limited in scope.

>>>> awful to write in Standard Forth, and easy to write with
>>>>carnal knowledge.
>>>
>>> It's not awful to write in standard Forth, as the reference
>>> implementation demonstrates.
>>
>>The RI is not written in standard Forth.
>
> True; another weakness of the proposal. Anyway, a fairly
> straightforward variation of the reference implementation has been
> posted which is written in standard Forth
> <9277159...@frunobulax.edu>:

Mine was nicer. Certainly shorter. But neither has the simplicity of
a version with carnal knowledge that can just MOVE from one stack to
the other, even when they grow in opposite directions.

>>http://groups.google.co.uk/group/comp.lang.forth/browse_thread/thread/ebaaf0c57ddbbc58/331a52ccfacef340#331a52ccfacef340
>
> I have not reread all of that discussion, but my own contributions to
> that discussion were along different lines. That's because I think
> that nobody at the time claimed that this proposal was a "great idea".

Eh? Surely the proponent thought so.

Andrew.

J Thomas

unread,
Mar 13, 2010, 10:19:12 PM3/13/10
to
Peter Knaggs wrote:

> The stack descriptions should read:
>
> N>R ( i*x n -- ) ( R: -- j*x n )
> NR> ( -- i*x n ) ( R: j*x n -- )
>
> Using "i" and "j" breaks the implicit indication that they are the same
> number of items. Thus allowing the a system to store the items in a
> buffer and only place the address of that buffer on the return stack.
> As "j" is an unknown value, this has the effect of blocking any
> acrobatics with the return stack.
>
> Also note that the multiplier goes before the type according to table
> 3.1 (data types).
>
> An alternative would be to define an opaque type along the lines of
> loop-sys but that would mean adding it to table 3.1.

That looks like a good thing to me.

N>R ( i*n i*n-1 ... i*1 n ) ( R: -- n>r-sys )

NR> ( -- i*n i*n-1 ... i*1 n ) ( R: n>r-sys -- )

There is nothing you can do with the data on the return stack except NR>
so why specify anything about what it looks like there?

Bruce McFarling

unread,
Mar 14, 2010, 12:21:01 AM3/14/10
to
On Mar 13, 10:19 pm, J Thomas <jethom...@gmail.com> wrote:
> Peter Knaggs wrote:
> > The stack descriptions should read:
>
> > N>R  ( i*x n -- ) ( R: -- j*x n )
> > NR>  ( -- i*x n ) ( R: j*x n -- )
> > An alternative would be to define an opaque type along the lines of
> > loop-sys but that would mean adding it to table 3.1.
>
> That looks like a good thing to me.
>
> N>R ( i*n i*n-1 ... i*1 n ) ( R: -- n>r-sys )
>
> NR> ( -- i*n i*n-1 ... i*1 n ) ( R: n>r-sys -- )
>
> There is nothing you can do with the data on the return stack except NR>
> so why specify anything about what it looks like there?

You can check n to see the size to work out if the datastack has
enough space to cope, or for any other reason why you might need to
know how big the chunk is. You just can't pop it.

Don't forget that the *other* way it can go away is with a THROW, and
its oftimes better to THROW because you'll not have enough space, than
to overflow the stack to find out there is a problem.

J Thomas

unread,
Mar 14, 2010, 7:39:36 AM3/14/10
to
Bruce McFarling wrote:
> J Thomas <jethom...@gmail.com> wrote:

>> I guess I did not get my meaning across. Sure, N>R does N>R better than
>> ROLL does N>R .
>
>> Many Forth programmers say that use of PICK and ROLL is usually a sign
>> of poor Forth practice. It's good to have them for occasions when you
>> don't have time to find a good way to get the job done, but when you
>> use them don't you feel like there has been a mistake somewhere? At
>> least I do.
>
> I don't use them.
>
>> N>R is designed to be used only when you have a blog of items on the
>> data stack which is just plain in your way and you need to get it out
>> of your way. It is used only as an extreme form of stack juggling.
>
> When you say, "only as an extreme form of stack juggling", what do you
> *mean* by stack juggling? Do you include writing a chunk of data to a
> structure and then later retrieving it exactly as you wrote it,
> "juggling"?

Yes, I think so. You have arranged to put a glob of data on the stack now
which you have no immediate use for, so you juggle it away until the one
single time you will use it.



>> At this point I see three times to use them. 1. SAVE-INPUT
>> 2. GET-ORDER
>> 3. Bad practice.
>
> Suppose you have a set of data that you are going to use atomically -
> for example, for a function call. I see nothing that is *intrinsically*
> bad practice about building one chunk of the function call, setting it
> to one side, build the rest of the function call, than getting the part
> you built first back.

I expect it would generally be better to build the pieces in the order
you need them. But there could be times when it's better to build them
out of order and juggle them into place.



> If the external function call interface involves handing an address of a
> structure to the external function, or using an external structure (say,
> CP/M 2.2 and FCB's), then of course you build it in the structure and
> its all nicely random access.
>
> If it involves calling the function with the parameters on the top of
> the Forth datastack, then you do that. In authoring the application, I
> have the information I need to hand to the external function, and the
> mechanism the implementation provides for making the call.

If you can generate your parameters in the right order, then you don't
need N>R . If you need N>R it means you have created a stack jam, you
have a clog of data on the stack which is covering up other data that you
need, so you have to get rid of the clog for awhile and later bring it
back.

Perhaps this means you are trying to solve a problem that Forth is too
limited to handle. But with extra special stack juggling words you can
use Forth anyway. Or maybe it means you have made a mistake.

J Thomas

unread,
Mar 14, 2010, 7:52:52 AM3/14/10
to
Bruce McFarling wrote:
> J Thomas <jethom...@gmail.com> wrote:

>> N>R ( i*n i*n-1 ... i*1 n ) ( R: -- n>r-sys )
>>
>> NR> ( -- i*n i*n-1 ... i*1 n ) ( R: n>r-sys -- )
>>
>> There is nothing you can do with the data on the return stack except
>> NR> so why specify anything about what it looks like there?

> You can check n to see the size to work out if the datastack has enough
> space to cope, or for any other reason why you might need to know how
> big the chunk is. You just can't pop it.

No, you can't use R@ to check the size unless the data is guaranteed to
be on the return stack. Unless you make a new command to get just the top
item, then absolutely the only thing you can do with the N>R data is
NR> . Anything else fails.

As you pointed out you can throw it away with THROW , but that's a
failure mode. If you could have found out that you wouldn't need that
data then you could have avoided generating it to use N>R on.

Albert van der Horst

unread,
Mar 14, 2010, 9:47:38 AM3/14/10
to
In article <2010Mar1...@mips.complang.tuwien.ac.at>,

Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>J Thomas <jeth...@gmail.com> writes:
>>Elizabeth D Rather wrote:
>>> Your experience is limited. There are a host of issues such as Windows
>>> calls that involve lengthy arrays of parameters that are awkward to deal
>>> with.
>
>I don't see how N>R and NR> help here. Could you give an example?
>
>>OK, that's reasonable. I still believe that SAVE-INPUT and GET-ORDER are
>>badly designed.
>
>Especially SAVE-INPUT. I don't think a portable program has ever used
>it for a useful purpose.

I thought that was just me.
Is it even used as a factor within a Forth implementation?
(If so it is probably in combination with N>R.)

Groetjes Albert

--
--
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

Anton Ertl

unread,
Mar 14, 2010, 10:43:13 AM3/14/10
to
"Peter Knaggs" <p...@bcs.org.uk> writes:
>The stack descriptions should read:
>
>N>R ( i*x n -- ) ( R: -- j*x n )
>NR> ( -- i*x n ) ( R: j*x n -- )
>
>Using "i" and "j" breaks the implicit indication that they are the
>same number of items.

But at least on the data stack it should be n*x (if you use n for the
count (+n or u would be better).

>Thus allowing the a system to store the items
>in a buffer and only place the address of that buffer on the return
>stack. As "j" is an unknown value, this has the effect of blocking
>any acrobatics with the return stack.

It would still require the count to be stored on the return stack.

Given that all existing implementations put this stuff on the return
stack, what would be the point of making this proposal weaker (or
wider)?

>An alternative would be to define an opaque type along the lines of
>loop-sys but that would mean adding it to table 3.1.

Sounds like the better approach if you want it to be opaque.

Anton Ertl

unread,
Mar 14, 2010, 10:47:56 AM3/14/10
to
Bruce McFarling <agi...@netscape.net> writes:
>On Mar 13, 11:50=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

>wrote:
>> Please implement it as a primitive for a Forth system of your choice
>> and show me how it is "far" simpler. =A0And for Forth systems that

>> compile to decent native code, it also won't be "far" faster, if at
>> all.
>
>But won't it be far more compact?

Not if the carnal word is inlined. Or consider the possibility of
completely unrolling the non-carnal loop given the known (and
typically low) loop count. If iForth and VFX don't do such stuff
already, I would expect them to do it soon.

Anton Ertl

unread,
Mar 14, 2010, 10:54:36 AM3/14/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>>>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>>>>Peter Knaggs <p...@bcs.org.uk> wrote:
>>>>>>>> RfD: N>R and NR>
>>>>>>>
>>>>>>>I think we discussed this already. It's still a great idea, and is
>>>>>>>well-supported by many Forths.
...

>>>AIUI this word is already in use in applications and
>>>has proved to be approriate.
>>
>> That does not make it a great idea. E.g., STATE exists in many
>> systems and is used in many applications, and it's still a bad idea.
>
>That's a good point, but the evil of STATE gets everywhere, whereas
>whatever small amount of evil N>R has, it's very limited in scope.

True. That does not make it a great idea, though.

>Mine was nicer. Certainly shorter. But neither has the simplicity of
>a version with carnal knowledge that can just MOVE from one stack to
>the other, even when they grow in opposite directions.

Please show me such a version. I doubt it will be *far* simpler.

>> I think
>> that nobody at the time claimed that this proposal was a "great idea".
>
>Eh? Surely the proponent thought so.

Maybe he did, but IIRC he did not claim it.

Anton Ertl

unread,
Mar 14, 2010, 10:59:08 AM3/14/10
to
Albert van der Horst <alb...@spenarnc.xs4all.nl> writes:
>In article <2010Mar1...@mips.complang.tuwien.ac.at>,
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>Especially SAVE-INPUT. I don't think a portable program has ever used
>>it for a useful purpose.
>
>I thought that was just me.
>Is it even used as a factor within a Forth implementation?

Not in Gforth. However, I see that Gforth's cross-compiler uses
SAVE-INPUT RESTORE-INPUT for doing things that are usually done with
>IN (that's about as useful as Gforth's implementation of these words
gets), e.g.:

save-input create restore-input throw

>(If so it is probably in combination with N>R.)

Obviously not, because Gforth has no N>R.

Andrew Haley

unread,
Mar 14, 2010, 11:18:14 AM3/14/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:

>>Mine was nicer. Certainly shorter. But neither has the simplicity of
>>a version with carnal knowledge that can just MOVE from one stack to
>>the other, even when they grow in opposite directions.
>
> Please show me such a version. I doubt it will be *far* simpler.

I don't think I said that it was. But it's certainly going to be
cleaner and probably faster and smaller than anything which requires
macros that move items one at a time.

>>> I think that nobody at the time claimed that this proposal was a
>>> "great idea".
>>
>>Eh? Surely the proponent thought so.
>
> Maybe he did, but IIRC he did not claim it.

IMO this is a simple, well-designed extension, we've already been told
by vendors they find it useful in applications, it's already
implemented by multiple systems, and as far as I can see has no
adverse impact on anything. Sounds great to me.

Andrew.

Bruce McFarling

unread,
Mar 14, 2010, 11:37:24 AM3/14/10
to
On Mar 14, 10:47 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> >But won't it be far more compact?

> Not if the carnal word is inlined.  Or consider the possibility of
> completely unrolling the non-carnal loop given the known (and
> typically low) loop count.  If iForth and VFX don't do such stuff
> already, I would expect them to do it soon.

But the carnal word wouldn't be inlined if codespace is a concern ...
indeed, I would be a bit surprised if SwiftX or Forth 6 unrolled loops
when it costs dictionary space.

Bruce McFarling

unread,
Mar 14, 2010, 11:49:10 AM3/14/10
to
On Mar 14, 7:52 am, J Thomas <jethom...@gmail.com> wrote:
> Bruce McFarling wrote:
> > J Thomas <jethom...@gmail.com> wrote:
> >> N>R ( i*n i*n-1 ... i*1 n -- ) ( R: -- n>r-sys )

> >> NR> ( -- i*n i*n-1 ... i*1 n ) ( R: n>r-sys -- )

> No, you can't use R@ to check the size unless the data is guaranteed to be on the return stack.

As Peter Knaggs has noted, that should have been

N>R ( i*x n -- ) ( R: -- j*x n )
NR> ( -- i*x n ) ( R: j*x n -- )

The n is guaranteed to be on the top of the return stack, but the rest
of the data is not guaranteed to be on the return stack at all.
"count(i)=n" is given in the text of the specification, "j" is
explicitly allowed to be arbitrary, including 0.

Since all current implementations given the data on the return stack,
but its been raised that since the data is atomic, that is not a
necessary restriction, and could be binding with small return stacks,
the suggestion has been to relax it to the data *may* be on the return
stack.

Having the "n" on top of the return stack is most likely to be useful
for precisely those settings where storage capacity of the return
stack is a concern, so its a facility rather than a constraint.

Bruce McFarling

unread,
Mar 14, 2010, 11:56:01 AM3/14/10
to
BTW, the small return stack is one scenario ... the other is where the
rack is not the actual return stack, and there is a reason to prefer
using the actual return stack.

Bernd Paysan

unread,
Mar 14, 2010, 2:32:41 PM3/14/10
to
Anton Ertl wrote:
> GET-ORDER and SAVE-INPUT are unidiomatic in having a dynamic stack
> depth with a count. My first reaction is that we should not
> standardize more words with that kind of interface.

This approach is more towards "using the stack as array". Gforth e.g.
has a more complex memory structure for input buffers, which makes
saving and restoring them a lot easier (for nested includes), and
doesn't need variable items on the stack. Example for such usage:

\ print all permutations of n numbers
: (permutate ( x1 .. xn m -- x1 .. xn )
dup 1 <= IF drop cr .s EXIT THEN
0 ?DO I' 1- roll I' 1- recurse LOOP ;
: permutate ( x1 .. xn n -- ) (permutate clearstack ;

Well, it does it's job, but it's definitely bad practice.

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

Jerry Avins

unread,
Mar 14, 2010, 2:44:18 PM3/14/10
to
Bernd Paysan wrote:
> Anton Ertl wrote:
>> GET-ORDER and SAVE-INPUT are unidiomatic in having a dynamic stack
>> depth with a count. My first reaction is that we should not
>> standardize more words with that kind of interface.

We store counted strings in memory. Why is it so gauche on the stack?

> This approach is more towards "using the stack as array". Gforth e.g.
> has a more complex memory structure for input buffers, which makes
> saving and restoring them a lot easier (for nested includes), and
> doesn't need variable items on the stack. Example for such usage:
>
> \ print all permutations of n numbers
> : (permutate ( x1 .. xn m -- x1 .. xn )
> dup 1 <= IF drop cr .s EXIT THEN
> 0 ?DO I' 1- roll I' 1- recurse LOOP ;
> : permutate ( x1 .. xn n -- ) (permutate clearstack ;
>
> Well, it does it's job, but it's definitely bad practice.

Please: permute, not permutate. (Just as administer, not administrate
and resign, not resignate.)

Jerry
--
Discovery consists of seeing what everybody has seen, and thinking what
nobody has thought. .. Albert Szent-Gyorgi
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

J Thomas

unread,
Mar 14, 2010, 2:48:52 PM3/14/10
to
Bruce McFarling wrote:
> J Thomas <jethom...@gmail.com> wrote:
>> Bruce McFarling wrote:
>> > J Thomas <jethom...@gmail.com> wrote:

>> >> N>R ( i*n i*n-1 ... i*1 n -- ) ( R: -- n>r-sys )
>> >> NR> ( -- i*n i*n-1 ... i*1 n ) ( R: n>r-sys -- )
>
>> No, you can't use R@ to check the size unless the data is guaranteed to
>> be on the return stack.
>
> As Peter Knaggs has noted, that should have been
>
> N>R ( i*x n -- ) ( R: -- j*x n )
> NR> ( -- i*x n ) ( R: j*x n -- )
>
> The n is guaranteed to be on the top of the return stack, but the rest
> of the data is not guaranteed to be on the return stack at all.
> "count(i)=n" is given in the text of the specification, "j" is
> explicitly allowed to be arbitrary, including 0.

OK, you could do it that way.

N>R ( i*x n -- ) ( R: -- n>r-sys n )
NR> ( -- i*x n ) ( R> n>r-sys n -- )

> Having the "n" on top of the return stack is most likely to be useful
> for precisely those settings where storage capacity of the return stack
> is a concern, so its a facility rather than a constraint.

It might make it a bit slower and more complex when the implementation
puts data somewhere other than return stack, but in return you get the
value of having n accessible without a new command.

Bruce McFarling

unread,
Mar 14, 2010, 3:16:32 PM3/14/10
to
On Mar 14, 2:32 pm, Bernd Paysan <bernd.pay...@gmx.de> wrote:
> Anton Ertl wrote:
> > GET-ORDER and SAVE-INPUT are unidiomatic in having a dynamic stack
> > depth with a count.  My first reaction is that we should not
> > standardize more words with that kind of interface.

> This approach is more towards "using the stack as array".

Well, not really. *"PICK"* is using the stack as a one-dimensional
array. SAVE-INPUT is using the stack as a stack. The variance with
more normal usage is precisely what Anton notes, an atomic item with a
variable size.

The alternative, in my necessarily humble, opinion would be:

GET-INPUT-STATE ( -- addr u )
* address and size of an item that can be used to restore input state.

SET-INPUT-STATE ( addr u -- )
* use the item provided by GET-INPUT-STATE to restore input state.

* Big systems have big datastacks and big return stacks, and if there
was someone using a big system for a rich enough variety of possible
input states for it to matter (eg, calling file which re-vectors KEY
keyboard to serial port where the input calls a file), if the data-
stack is used to get the load, the above can always be done with
ALLOCATE if desired.

* Small systems may have small datastacks and small return stacks, but
are also likely to have simpler permutations of input state ... if the
input state can be expressed in bit flags and parameters that fit into
a cell, it takes no more space on the stack than above, and no
additional storage space. Worst case is likely to be an input and
output file handle and some bit flags, ( 3*x 3 ) on the stack.

Bruce McFarling

unread,
Mar 14, 2010, 3:34:09 PM3/14/10
to
On Mar 14, 2:48 pm, J Thomas <jethom...@gmail.com> wrote:
> It might make it a bit slower and more complex when the implementation
> puts data somewhere other than return stack, but in return you get the
> value of having n accessible without a new command.

But could also make it simpler, since a block move count and the block
move data are more often distinct things.

Given that the existing implementations *have* n there, the original
proposal *proposed* it there, and its the only part of the data that
has a use independent of NR> ... there is precisely no efficiency loss
or capability lost *for existing implementations* in having it there.

"Might not be enough space on the return stack" is a quite clear issue
for resource constrained systems, where its quite possible that the
datastack is deeper than the return stack when they are not
implemented as facing stacks. So the objection to mandating that all
of the arbitrary number of items be on the return stack.

But "n" is not an arbitrary number of items, its one item. And for the
entirely hypothetical, "maybe its harder to do it that way", well,
maybe its not. The spare area could be a secondary soft stack at the
end of RAM, with an index byte decremented when its used, normally
used one cell at a time, and pushing it and fetching it with a FOR/
NEXT loop is the most compact way to use it.

It is loading more messages.
0 new messages