Proposal: Standardize the well-known RDROP

Informal

This page is dedicated to discussing this specific proposal

ContributeContributions

EricBlakeavatar of EricBlake [417] Standardize the well-known RDROPProposal2025-10-10 16:02:13

Author:

Eric Blake

Change Log:

2025-10-10 Initial proposal

Problem:

When using the return stack during stack-heavy manipulation (without locals), it is not uncommon to have conditional code that places a value on the return stack for some branches of the code, but does not need that value on the data stack after other branches. While the depth of the return stack must be restored before the end of the current definition, it is desirable to have a single word that can remove an item from the return stack without affecting the data stack, undoing only half of the effect of r>.

Several proposed example implementations have relied on use of the word rdrop, because it is well-known across a number of Forth implementations, only to need correction when it is pointed out that the standard does not yet provide a single-word solution for this desired stack effect.

Solution:

Standardizing rdrop will guarantee that library code can use this word if present for discarding a return stack cell, without worrying about it having different semantics than what most users have come to expect.

A pure-Forth implementation using other standard words is fairly trivial; therefore the new word can be optional. Note, however, that rdrop shares the characteristic of the other return stack manipulation words where it is not portable to attempt to execute the execution token obtained from ticking the word. Furthermore, a native implementation is likely to be more efficient than the immediate version given in the suggested reference implementation.

This proposal does not include 2drop; if that is desired, I'm open to amending this proposal to add it, as that would be yet another example where a native implementation is likely to be more efficient than a pure-Forth immediate wrapper.

Typical use:

... >r do r@ ... loop rdrop

Several suggested reference implementations elsewhere in the standard have used rdrop:

sm/mod

Potential future addition of non-parsing create

The potential future addition of ?: mentioned rdrop as a particularly vexing case, as the effects of immediate add a wrinkle into conditional definition.

Proposal:

Add a new glossary entry:

6.1.---- rdrop "r-drop" Core-Ext

Interpretation:
Interpretation semantics for this word are undefined.

Execution:
( R: x -- )

Remove x from the return stack.

See: 3.2.3.3 Return stack, 6.1.1260 drop, 6.1.2060 r>

Rationale: This operation may be more efficient than `r> drop`.

(Editor's note: If the entries for >r and friends are changed to list Run-time semantics rather than Execution semantics, then this section will need to do likewise)

Amend this sentence in 3.2.3.3 Return stack:

A program shall not access or discard values on the return stack (using r@, r>, rdrop, 2r@, 2r> or nr>) that it did not place there using >r, 2>r or n>r;

Add cross-references to rdrop in 6.1.1260 drop and 6.1.2060 r>.

Reference implementation:

: rdrop ( R: x -- ) postpone r> postpone drop ; immediate

Testing:

t{ : gr3 >r r@ rdrop ; -> }t
t{ 123 gr3 -> 123 }t

(Editorial note: Other than in the subject, this proposal uses lower-case naming of all words, on the grounds that other proposals in flight deal with either making future Forth case-insensitive on standard words, or with ensuring the standard words are converted to upper-case in renderings as needed.)

EricBlakeavatar of EricBlakeNew Version: Standardize the well-known RDROP

Hide differences

Author:

Eric Blake

Change Log:

2025-10-10 typo fixes

2025-10-10 Initial proposal

Problem:

When using the return stack during stack-heavy manipulation (without locals), it is not uncommon to have conditional code that places a value on the return stack for some branches of the code, but does not need that value on the data stack after other branches. While the depth of the return stack must be restored before the end of the current definition, it is desirable to have a single word that can remove an item from the return stack without affecting the data stack, undoing only half of the effect of r>.

When using the return stack during stack-heavy manipulation (without locals), it is not uncommon to have conditional code that places a value on the return stack for some branches of the code, but does not need that value on the data stack after other branches. While the depth of the return stack must be restored before the end of the current definition, it is desirable to have a single word that can remove an item from the return stack without affecting the data stack, undoing only half of the effect of >r.

Several proposed example implementations have relied on use of the word rdrop, because it is well-known across a number of Forth implementations, only to need correction when it is pointed out that the standard does not yet provide a single-word solution for this desired stack effect.

Solution:

Standardizing rdrop will guarantee that library code can use this word if present for discarding a return stack cell, without worrying about it having different semantics than what most users have come to expect.

A pure-Forth implementation using other standard words is fairly trivial; therefore the new word can be optional. Note, however, that rdrop shares the characteristic of the other return stack manipulation words where it is not portable to attempt to execute the execution token obtained from ticking the word. Furthermore, a native implementation is likely to be more efficient than the immediate version given in the suggested reference implementation.

This proposal does not include 2drop; if that is desired, I'm open to amending this proposal to add it, as that would be yet another example where a native implementation is likely to be more efficient than a pure-Forth immediate wrapper.

This proposal does not include 2rdrop; if that is desired, I'm open to amending this proposal to add it, as that would be yet another example where a native implementation is likely to be more efficient than a pure-Forth immediate wrapper.

Typical use:

... >r do r@ ... loop rdrop

Several suggested reference implementations elsewhere in the standard have used rdrop:

sm/mod

Potential future addition of non-parsing create

The potential future addition of ?: mentioned rdrop as a particularly vexing case, as the effects of immediate add a wrinkle into conditional definition.

Proposal:

Add a new glossary entry:

6.1.---- rdrop "r-drop" Core-Ext

Interpretation:
Interpretation semantics for this word are undefined.

Execution:
( R: x -- )

Remove x from the return stack.

See: 3.2.3.3 Return stack, 6.1.1260 drop, 6.1.2060 r>

Rationale: This operation may be more efficient than `r> drop`.

(Editor's note: If the entries for >r and friends are changed to list Run-time semantics rather than Execution semantics, then this section will need to do likewise)

Amend this sentence in 3.2.3.3 Return stack:

A program shall not access or discard values on the return stack (using r@, r>, rdrop, 2r@, 2r> or nr>) that it did not place there using >r, 2>r or n>r;

Add cross-references to rdrop in 6.1.1260 drop and 6.1.2060 r>.

Add cross-references to rdrop in 6.1.0580 >r, 6.1.1260 drop, 6.1.2060 r>.

Reference implementation:

: rdrop ( R: x -- ) postpone r> postpone drop ; immediate

Testing:

t{ : gr3 >r r@ rdrop ; -> }t
t{ 123 gr3 -> 123 }t

(Editorial note: Other than in the subject, this proposal uses lower-case naming of all words, on the grounds that other proposals in flight deal with either making future Forth case-insensitive on standard words, or with ensuring the standard words are converted to upper-case in renderings as needed.)

ruvavatar of ruv

I agree with this proposal. You could also mention the word fdrop as a precedent.

The section "Typical use" should be corrected, because it demonstrate an incorrect use.

See 6.1.1240:

do Run-time: ( S: n1|n2 u1|u2 -- ; R: -- loop-sys )

Also, it says: "Anything already on the return stack becomes unavailable until the loop-control parameters are discarded".

EricBlakeavatar of EricBlake

I agree with this proposal. You could also mention the word fdrop as a precedent.

Will do on my next revision.

The section "Typical use" should be corrected, because it demonstrate an incorrect use.

Good catch. Just because i and r@ happen to be the same in my implementation (and probably several others) does not make it universally so. I will probably rewrite this into begin/repeat rather than do/loop to reduce the level of abstraction, and avoid that unfortunate return stack interaction.

EricBlakeavatar of EricBlakeNew Version: Standardize the well-known RDROP

Hide differences

Author:

Eric Blake

Change Log:

2025-10-10 mention fdrop and cs-drop, fix typical usage

2025-10-10 typo fixes

2025-10-10 Initial proposal

Problem:

When using the return stack during stack-heavy manipulation (without locals), it is not uncommon to have conditional code that places a value on the return stack for some branches of the code, but does not need that value on the data stack after other branches. While the depth of the return stack must be restored before the end of the current definition, it is desirable to have a single word that can remove an item from the return stack without affecting the data stack, undoing only half of the effect of >r.

Several proposed example implementations have relied on use of the word rdrop, because it is well-known across a number of Forth implementations, only to need correction when it is pointed out that the standard does not yet provide a single-word solution for this desired stack effect.

Additionally, the standard already has fdrop even though that can be implemented by f0= drop or similar (a more naive f>s drop risks ambiguous behavior if the value in r was out of integer range), as well as cs-drop recently added to the standard (discarding a dest from the control-flow stack was already possible with an extra then; while discarding an orig was only made possible when the cs-drop proposal enhanced cs-pick to allow duplicating an orig, and previously could only be done by abusing carnal knowledge of how an implementation expresses orig in the control-flow stack). As dropping an item from a stack tends to be a common low-level operation, it makes sense to have rdrop for doing the same with the return stack, and where the naming convention is consistent. (Aside: Whether fdrop and cs-drop affect only the data stack or distinct other stacks depends on whether the implementation merges the floating-point or control-flow stacks with the data stack; however, rdrop only affects the return stack since there is no way to merge the return stack with the data stack.)

Solution:

Standardizing rdrop will guarantee that library code can use this word if present for discarding a return stack cell, without worrying about it having different semantics than what most users have come to expect.

A pure-Forth implementation using other standard words is fairly trivial; therefore the new word can be optional. Note, however, that rdrop shares the characteristic of the other return stack manipulation words where it is not portable to attempt to execute the execution token obtained from ticking the word. Furthermore, a native implementation is likely to be more efficient than the immediate version given in the suggested reference implementation.

This proposal does not include 2rdrop; if that is desired, I'm open to amending this proposal to add it, as that would be yet another example where a native implementation is likely to be more efficient than a pure-Forth immediate wrapper.

Typical use:


... >r do r@ ... loop rdrop

... >r begin r@ ... until rdrop


Several suggested reference implementations elsewhere in the standard have used rdrop:

sm/mod

fm/mod

Potential future addition of non-parsing create

The potential future addition of ?: mentioned rdrop as a particularly vexing case, as the effects of immediate add a wrinkle into conditional definition.

Proposal:

Add a new glossary entry:


6.1.---- rdrop "r-drop" Core-Ext

6.2.---- rdrop "r-drop" Core-Ext

Interpretation: Interpretation semantics for this word are undefined.

Execution: ( R: x -- )

Remove x from the return stack.

See: 3.2.3.3 Return stack, 6.1.1260 drop, 6.1.2060 r>

Rationale: This operation may be more efficient than r> drop.

(Editor's note: If the entries for `>r` and friends are changed to list [Run-time semantics rather than Execution semantics](https://forth-standard.org/standard/core/EXIT#reply-224), then this section will need to do likewise)

Amend this sentence in 3.2.3.3 Return stack:

 A program shall not access **or discard** values on the return stack (using r@, r>, **rdrop**, 2r@, 2r> or nr>) that it did not place there using >r, 2>r or n>r; 

Add cross-references to rdrop in 6.1.0580 >r, 6.1.1260 drop, 6.1.2060 r>.

## Reference implementation:

: rdrop ( R: x -- ) postpone r> postpone drop ; immediate


## Testing:

t{ : gr3 >r r@ rdrop ; -> }t t{ 123 gr3 -> 123 }t


(Editorial note: Other than in the subject, this proposal uses lower-case naming of all words, on the grounds that other proposals in flight deal with either making future Forth case-insensitive on standard words, or with ensuring the standard words are converted to upper-case in renderings as needed.)

PeterFalthavatar of PeterFalth

I have this functionality in my Forths for a long time but with the name R>DROP. I think that is a better name. There are no other names that directly manipulate the return stack like rdup, rswap. The existing words move items to and from the return and data stack R>DROP also communicates this. I certainly did not invent R>DROP so there are also other systems using this. I have now stopped using R>DROP and put back the space! My compilers produce the same code in both cases.

Reply New Version