This message continues in a new thread the topic:
"Custom xt compiler and compilation semantics (was: Extended VALUEs in
Forth 200x)" news://thi90o$2ofsa$
1...@dont-email.me
https://groups.google.com/g/comp.lang.forth/c/dh347IHLDtw/m/tv7Z8QsfBAAJ
Some time ago Anton defended one peculiar understanding (interpretation)
of immediate words and their semantics, namely that for any immediate
word the interpretation semantics are equivalent to the compilation
semantics, which in turn are equivalent to the execution semantics (¹).
There were many discussions in this regard [1]. I don't remember anyone
else defending this understanding, but it seems it has its share in the
community. This message is addressed to the people who share this
understanding.
[1] Just one example:
https://groups.google.com/g/comp.lang.forth/c/ildjR6oy6hg/m/caArstkVBgAJ
One consequence of the understanding (¹) is that compilation semantics
can depend on STATE. Since, if the execution semantics for an immediate
word are STATE-dependent, then the compilation semantics are either
STATE-dependent too or not equivalent to the execution semantics. If you
don't accept their inequivalence, you have to admit STATE-dependent
compilation semantics.
\ An example of immediate word for which execution semantics
\ are dependent on STATE, i.e. they produce different results
\ in interpretation state and in compilation state
: foo ( -- 132 | ) s" 123" evaluate ; immediate
' foo constant xt-foo
\ if xt-foo is executed interpretively, it places 123 on the stack
\ if xt-foo is executed compilatively, it compiles 123 as a literal
By this understanding, if I ask you to perform the compilation semantics
for an immediate word, you can do it by performing the execution
semantics of this word in interpretation state as well as in compilation
state.
But the results will vary if these execution semantics are
STATE-dependent. Should I really add that I ask for the variant of
compilation semantics that takes place namely in compilation state?
Actually, no. If I ask to perform the compilation semantics for a word,
I mean to perform that very behavior that takes place when the Forth
text interpreter encounters this word name in compilation state. No
other options.
Ditto for interpretation semantics.
Thus, the understanding (¹) produces a bunch of such excessive notions as:
- STATE-dependent compilation semantics,
- compilation semantics in compilation state,
- compilation semantics in interpretation state,
- STATE-dependent interpretation semantics,
- interpretation semantics in interpretation state,
- interpretation semantics in compilation state.
But they are not needed. They are nonsense. This whole understanding of
immediate words is very contrived and totally useless.
The only possible reason for the understanding (¹) was to justify a
particular implementation of "postpone" (i.e., to proof that the
Forth-94 standard allegedly allows such implementations):
: postpone ( "name" -- )
bl word find case
-1 of lit, ['] compile, compile, endof
1 of compile, endof
-13 throw
endcase
; immediate
(²)
This "postpone", when it's applied to an immediate word, appends to the
current definition the execution semantics of the word (by applying
"compile," to their identifier), instead of the compilation semantics
(as it's defined in 2.1 Definitions of terms).
If you want to allow this implementation, it's better to just say that
"postpone", when it's applied to an immediate word, appends its
execution semantics. There's no need to skew the notion of compilation
semantics making it STATE-dependent.
But, anyway, if you allow this implementation, you introduce some
problems. And these problems remain regardless what and how you call.
The Forth-94 TC realized these problems and, in their clarification RFI
Q99-027/A99-027, chose to restrict standard programs to avoid these
problems (NB: at the moment, it is not a normative part of any Forth
standard issued after 1984).
If you don't restrict programs, the behavior variations of the
"postpone" implementation (²) when it is applied to immediate and
nonimmediate dual-semantics words become observable for programs. Hence,
the programmer has to know how an argument of "postpone" is implemented.
And it makes "postpone" *fail* in what it was designed for.
A.6.1.2033 POSTPONE
https://forth-standard.org/standard/rationale#rat:core:POSTPONE
| POSTPONE replaces most of the functionality
| of COMPILE and [COMPILE]. COMPILE and [COMPILE]
| are used for the same purpose: postpone
| the compilation behavior of the next word
| in the parse area. COMPILE was designed to be applied
| to non-immediate words and [COMPILE] to immediate words.
|
| This burdens the programmer with needing to know
| which words in a system are immediate. Consequently,
| Forth standards have had to specify the immediacy
| or non-immediacy of all words covered by the standard.
| This unnecessarily constrains implementors.
A.6.1.1550 FIND
https://forth-standard.org/standard/rationale#rat:core:FIND
| POSTPONE allowed de-specification of immediacy
| or non-immediacy for all but a few Forth words
| whose behavior must be STATE-independent.
So, if implementation (²) for "postpone" is allowed, the programmer is
burdened again with needing to know which words are immediate.
Therefore, the implementation (²) is not acceptable without restriction
on programs. And even the understanding (¹) cannot change that. Hence,
there is no reasons to stick with this contrived understanding at all.
It's very easy to implement (or redefine) "postpone" that correctly deal
with immediate words and does not impose any restriction on programs.
See:
https://github.com/ForthHub/discussion/discussions/103#solution
On 2022-10-04 21:36Z Ruvim wrote:
> On 2022-10-03 21:52Z, Krishna Myneni wrote:
>
>> NAME>COMPILE should always return the compilation xt, which can be
>> independently set on a dual token system, or on a single token system
>> which supports "non-default compilation semantics".
>
>
>> In contrast, ticking a word on a standard system will return an
>> execution token corresponding to its interpretation semantics.
>
> It sounds incorrectly. By this wording you revoke access to the
> identifier of the execution semantics for a word.
>
> Actually, ticking a word on a standard system returns the execution
> token that identifies the execution semantics for *this* word.
>
> If the standard does not specify execution semantics for the word then
> the returned xt (if any) identifies implementation-dependent execution
> semantics for this word.
>
> Yes, usually, this execution token is used by the system to *perform*
> the interpretation semantics for the word.
>
> But, for some words, this the same execution token may be also used to
> perform the compilation semantics for the word. Namely, if the word is
> an immediate word.
>
> Since, to perform the compilation semantics for an immediate word, its
> execution token shall be executed in compilation state, to perform the
> interpretation semantics — it shall be executed in interpretation state.
>
> When you refer this execution token as one corresponding to the
> interpretation semantics of a word, you also make an impression that
> executing this token performs the interpretation semantics for the word
> regardless of STATE. But it's false in the general case.
>
> --
> Ruvim
--
Ruvim