Digest #150 2021-05-07
Contributions
One simple and almost portable implementation of POSTPONE
is following:
: POSTPONE ( "name" -- )
BL WORD FIND DUP 0= -13 AND THROW 1 = ( xt flag-compilation )
SWAP LIT, IF ['] EXECUTE ELSE ['] COMPILE, THEN COMPILE,
; IMMEDIATE
This implementation uses the non-standard LIT,
word (that is factor of LITERAL
), and applies Tick to COMPILE,
(that is ambiguous in the general case due to undefined interpretation semantics for COMPILE,
at the moment). Also this implementation relies on the TC reply to RFI Q99-027 and doesn't meet the common expectations concerning a system behavior in this regard (a more completed implementation can be found in my gist on GitHub).
LIT,
execution: ( x -- ) append the run-time semantics "place x on the stack" to the current definition.
If LIT,
is absent, it can be replaced by the phrase 0 <# #S #> EVALUATE
in the definition above.
LITERAL
can be defined via LIT,
and vise versa:
: LITERAL ( x -- ) LIT, ; IMMEDIATE
: LIT, ( x -- ) POSTPONE LITERAL ;
To make applying Tick to COMPILE,
compliant, it's enough to redefined it:
: COMPILE, ( xt -- ) COMPILE, ;
Replies
behavior of
POSTPONE S"
is already non standard in SwiftForth
I was wrong on that.
According to the TC reply to RFI Q99-027, an ambiguous condition exists if a program performs compilation semantics in interpretation state.
So the behavior of SwiftForth in this case does not meet the common expectations, but it is still standard compliant.
Choice n value in interpretation state
Clarification and correction
We should distinguish the declared semantics (in the glossary entry for a word) and the implemented semantics (in a particular Forth system, for this word). A declaration itself does not limit the implementation ways. And FIND
returns n value not according to the declaration, but according to the implementation.
It means that some words with non default interpretation semantics can (and may) be implemented as an ordinary word, e.g. COMPILE,
or EXIT
, and then FIND
should return n value -1
for them.
So, the option B from above message should be corrected.
The possible options for n value in interpretation state for the words with non default interpretation semantics in their glossary entries, after correction:
A. If the word is implemented as an immediate word, then n is
1
, otherwise n is-1
.B. If the word is implemented as an ordinary word, then n is
-1
, otherwise n is1
.B. n is unspecified among
1
and-1
.
We consider these options for only standard words with non default interpretation semantics, since for other words we already don't have any choice, the value of n is determined: -1
for ordinary words, 1
for immediate words.
Implementation factors
Let's consider a simple cmForth-like system that doesn't explicitly maintain the immediacy flag, but rely on the different word lists only. For such a system the simplest approach is to return the same n regardless of the word kind, for example -1
. This approach is simplest since otherwise the system have to make the second search in another word list to detect whether it's an ordinary word or not. But this approach is already unacceptable, since FIND
should return n value 1
for immediate words. So this system have to perform the second search in any case. But then, in some simple implementation, this system cannot distinguish immediate word from a non-immediate word — i.e., it doesn't have information whether xt (that found in another word list) identifies the execution semantics for the name, or only performs the compilation semantics for name. It means that option A cannot be implemented in this very simple system. Then the option B is only possible fir this case.
In a more complex system, any option from the A and B is possible with equal cost. The option C means that a system is allowed to implement any from the A and B options, as well as something another, e.g. to return every time a random number among 1
and -1
(that is pretty unuseful).
If a program implements some advanced technique in a portable way (e.g., recognizer, see a comment), it needs to determine interpretation semantics and compilation semantics in the same time. With the option A this program have to perform FIND
twice for all but immediate words. With the option B this program have to perform FIND
twice for all but ordinary words. But the ordinary words comprise the majority part of words. Then the option B gains better performance.
So the option B is better for implementations in the general case.
Usefulness factors
Between the options A and B: it's far more important to distinguish ordinary words from non ordinary, than immediate words from non immediate. Also, immediacy is just a way to implement non ordinary words.
Concerning the option C: obviously, it's far less useful.
So, the option B is preferable.
Back compatibility factors
It seems, dual-xt systems already implement the option B (please, check).
Then the option B is better.
Conclusion
I suggest to stick with the option B.
Author
Ruv
Change Log
2019-10-08: Initial version
2020-08-28: Avoid ambiguous clause "xt is the execution token for name" in the case of a word with non default interpretation semantics.
2021-04-18: Allow to return the different xt for any definition. More tight meaning of n in interpretation state. Avoid "implementation-dependent definition" and make the wording simpler.
2021-05-06: Correct meaning of n in interpretation state: iff n is -1
, then xt identifies the execution semantics for name. Eliminate the"default interpretation semantics" notion from the normative part.
Problem
The descriptions of the problem and solution are the same as in the previous version
Proposal
Replace the text in the specification of FIND with the following.
FIND
( c-addr -- c-addr 0 | xt n )
Find the definition name whose name matches the counted string at c-addr. If the definition is not found, return c-addr and zero.
Otherwise, return xt and n, where xt is an execution token and n is -1
or 1
. The returned values may differ between interpretation and compilation state, and the following conditions shell be met:
- if the definition is found in interpretation state, then
- if and only if xt identifies the execution semantics for name and name is not immediate, n is
-1
, otherwise n is1
; - performing xt in interpretation state performs the interpretation semantics for name;
- if and only if xt identifies the execution semantics for name and name is not immediate, n is
- if the definition is found in compilation state, then
- if n is
1
, performing xt in compilation state performs the compilation semantics for name; - if n is
-1
, appending the execution semantics identified by xt to the current definition performs the compilation semantics for name.
- if n is
A definition may be found in compilation state but not found in interpretation state (or vise versa).
A program is allowed to apply FIND
to any string.
"Performing xt" means performing the execution semantics identified by the execution token xt.
If interpretation semantics are undefined for a definition, a Forth system is allowed to provide implementation-defined interpretation semantics for this definition (see A.3.4.3.2). In such case, when the definition is found in interpretation state, performing the returned xt in interpretation state performs the implementation-defined interpretation semantics for name.
Neither immediacy nor non-immediacy is specified for the most definitions by this standard, so a Forth system is allowed to implement any definition as an immediate word if this implementation meets the specification for this word (see A.6.1.2033, A.6.1.1550).