Digest #217 2023-03-03
Contributions
Author
Ruv
Change Log
- 2023-03-02 Initial version
Problem
The words SAVE-INPUT and RESTORE-INPUT almost don't bear any usefulness to programs, and they only burden implementers.
These words have the following problems:
- Too few guarantees to programs:
RESTORE-INPUTmay work or fail depending on on the input source kind (file, pipe, string, keyboard). - The returned flag of
RESTORE-INPUTis inconsistent with other words: true means fail, false means success. A better variant could be a throwable ior. - In some systems
RESTORE-INPUTworks incorrectly in some cases: it restores the position in the input buffer and returns success, but doesn't restore the content of the input buffer.
These words are almost not used in programs. I asked in comp.lang.forth and ForthHub. Only one program was mentioned: "Lambda Expressions in ANS Forth" by Gerry Jackson (sources), and in this case the problem can be also solved without these words.
What is sometimes required in programs is an ability to parse (extract) a text fragment from the input stream, and later translate (evaluate) this fragment in the current context, regardless whether the input stream was switched or not. Such an API should be designed separately. The words SAVE-INPUT and RESTORE-INPUT cannot help on that.
Solution
Declare the words SAVE-INPUT and RESTORE-INPUTas obsolescent, to destandardize (remove from the standard) them on the next iteration.
Consequences
This change doesn't affect the standard systems. The new (or updated) standard systems can be made slightly simpler by not providing an implementation and documentation for these words (if they are not used internally).
The standard programs that employ these words gain a new environmental dependency, and later they become non compliant to the new versions of the standard.
Proposal
In the section 1.4.2 Obsolescent features, after the phrase "This standard designates the following word as obsolescent:", add:
- 6.2.2182 SAVE-INPUT
- 6.2.2148 RESTORE-INPUT
In each of the glossary entries 6.2.2182 SAVE-INPUT and 6.2.2148 RESTORE-INPUT add the following note:
Note:
This word is obsolescent and is included as a concession to existing implementations.
Replies
referenceImplementation - Possible Reference Implementation
or, more simply:
: D0= OR 0= ;
referenceImplementation - Possible Reference Implementation
... oh, yes. What was I thinking?
In the general case a stack cannot be replaced by a new one (of more size), since addresses in the stack can be used under the hood.
What is possible (for each stack, or at least the data stack and return stack) are:
- to ask the system for a number of available cells in the stack (similar to
unusedfor data space); - to execute a definition with guaranteed amount of the stack space (so a new stack can be allocated before execution, and freed after; in the case of the data stack the parameters should be passed to the new stack and the results — to the old one);
- to specify the stack size for a new thread (before creating/starting);
- to specify the stack size for the Forth system before starting;
See also a StackOverflow question: Set stack size programmatically on Windows.
In GerryJackson's example, [...]
CATCHtransfers control back to the interpreter
Yes.
I think, "a point just after CATCH" should be interpreted not as a point in the source code, but as a point in run-time that is performed just after performing catch if throw was not performed (so it's the same point regardless whether throw was performed or not).
For example in the phrase "['] catch execute ." (which is a part of a definition) a point after performing catch is the point after execute in this source code.
When catch is encountered by the Forth text interpreter in interpretation state, a point just after performing catch is a point after execute inside the Forth text interpreter. And when this execute returns, the Forth text interpreter continues to parse the input source according its current state.
without restoring the parse area to its original state because that's not a reasonable thing to require.
Yes. And formally it must not restore this state, because restoring of this state is not specified.
: pick ( x_u ... x_1 x_0 u -- x_u ... x_1 x_0 x_u )
dup 0= if drop dup exit then swap >r 1- recurse r> swap
;
(the stack diagram is copied from the glossary entry)
: pick ( x_u ... x_1 x_0 u -- x_u ... x_1 x_0 x_u )
dup 0= if drop dup exit then swap >r 1- recurse r> swap
;
(the stack diagram is copied from the glossary entry)
: roll ( x_u x_u-1 ... x_0 u -- x_u-1 ... x_0 x_u )
dup 0= if drop exit then swap >r 1- recurse r> swap
;
(the stack diagram is copied from the glossary entry)