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-INPUT
may work or fail depending on on the input source kind (file, pipe, string, keyboard). - The returned flag of
RESTORE-INPUT
is inconsistent with other words: true means fail, false means success. A better variant could be a throwable ior. - In some systems
RESTORE-INPUT
works 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-INPUT
as 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
unused
for 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, [...]
CATCH
transfers 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)