Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Poll: equivalence for postpone expression

292 views
Skip to first unread message

Ruvim

unread,
Jun 19, 2021, 4:03:54 PM6/19/21
to
A poll about equivalences for the "postpone x" expression.


Definition: a phrase is a fragment of a program expressed in the Forth
source code form.

Definition: two phrases are equivalent in a given context iff each of
them in this context always produces the same effects as other. By
default, in any given context, each lexeme that is encountered by the
Forth text interpreter is recognized as either a standard word, or a
mentioned word, or a number.

NB: a proposition that contains free variables is true iff it's true for
any possible values for the free variable.



Let "foo" is a word that doesn't perform any parsing, doesn't access the
parse area, and doesn't enter into compilation or interpretation state
(i.e., any such behavior is not a part of any semantics for "foo").

Let the word "compile-foo" is defined as:
: compile-foo postpone foo ;
and it has the same scope as the word "foo".



Proposition 1.
The phrase:
[ compile-foo ]
is equivalent to the phrase:
foo
in any such context when the phrase is encountered by the Forth
text interpreter in compilation state.



Proposition 2.
The phrase:
[ postpone foo ]
is equivalent to the phrase:
foo
in any such context when the phrase is encountered by the Forth
text interpreter in compilation state.




Please evaluate each proposition, according to your understanding/view,
by the following statements:

a. The proposition shall be true in a standard system.

b. It's better if the proposition is true in a system.

c. In a standard system the proposition may be true or false,
depending on the definition "foo".

d. In a standard system the first phrase (the left part of the
equivalency) may throw an exception for any "foo".


Multiple choice is admissible.

It's enough to indicate (separately for the propositions 1 and 2) the
letters where your choice is "yes". E.g. P1: ac, P2: bcd.


--
Ruvim

P Falth

unread,
Jun 20, 2021, 3:20:48 AM6/20/21
to
This is what I get from lxf

: foo noop ; ok
: compile-foo postpone foo ; ok
: t1 [ compile-foo ] ; ok
: t2 foo ; ok
see t1
A4A2B8 4099BB 5 C80000 5 normal T1

4099BB E9E6FFFFFF jmp FOO
ok
see t2
A4A2CC 4099C0 5 C80000 5 normal T2

4099C0 E9E1FFFFFF jmp FOO
ok
: t3 [ postpone foo ] ; ok
see t3
A4A2E0 4099C5 16 C80000 5 normal T3

4099C5 895DFC mov [ebp-4h] , ebx
4099C8 BBA6994000 mov ebx , # 4099A6h
4099CD 8D6DFC lea ebp , [ebp-4h]
4099D0 E92B668700 jmp COMPILE,
ok
: t4 [ ' foo compile, ] ; ok
see t4
A4A2F4 4099D5 5 C80000 5 normal T4

4099D5 E9CCFFFFFF jmp FOO
ok


>
> Please evaluate each proposition, according to your understanding/view,
> by the following statements:
>
> a. The proposition shall be true in a standard system.
>
> b. It's better if the proposition is true in a system.
>
> c. In a standard system the proposition may be true or false,
> depending on the definition "foo".
>
> d. In a standard system the first phrase (the left part of the
> equivalency) may throw an exception for any "foo".
>
>
> Multiple choice is admissible.
>
> It's enough to indicate (separately for the propositions 1 and 2) the
> letters where your choice is "yes". E.g. P1: ac, P2: bcd.

In my opinion compiling code while not in compilation state should
not be done in a standard system. It might work in some systems
but not all.

I really do not understand why you are pursuing this type of coding.

If you want to call foo in a definition why not use foo directly.

: test foo ; will always work!

BR
Peter

> --
> Ruvim

none albert

unread,
Jun 20, 2021, 4:30:37 AM6/20/21
to
e. Avoid POSTPONE like the plague. Always find a way around it.

>
>Multiple choice is admissible.
>
>It's enough to indicate (separately for the propositions 1 and 2) the
>letters where your choice is "yes". E.g. P1: ac, P2: bcd.
>
>
>--
>Ruvim
--
"in our communism country Viet Nam, people are forced to be
alive and in the western country like US, people are free to
die from Covid 19 lol" duc ha
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Ruvim

unread,
Jun 20, 2021, 5:06:44 AM6/20/21
to
On 2021-06-20 10:20, P Falth wrote:
> On Saturday, 19 June 2021 at 22:03:54 UTC+2, Ruvim wrote:
>> A poll about equivalences for the "postpone x" expression.
[...]
What if "foo" is a dual semantics word? What if "foo" is also an
immediate? Does the system still hold this equivalence for such cases?



> : t3 [ postpone foo ] ; ok
> see t3
> A4A2E0 4099C5 16 C80000 5 normal T3
>
> 4099C5 895DFC mov [ebp-4h] , ebx
> 4099C8 BBA6994000 mov ebx , # 4099A6h
> 4099CD 8D6DFC lea ebp , [ebp-4h]
> 4099D0 E92B668700 jmp COMPILE,
> ok
> : t4 [ ' foo compile, ] ; ok
> see t4
> A4A2F4 4099D5 5 C80000 5 normal T4
>
> 4099D5 E9CCFFFFFF jmp FOO
> ok

Then, you don't support equivalence for "compile," that it is equivalent
to "postpone literal postpone execute", do you?



>>
>> Please evaluate each proposition, according to your understanding/view,
>> by the following statements:
>>
>> a. The proposition shall be true in a standard system.
>>
>> b. It's better if the proposition is true in a system.
>>
>> c. In a standard system the proposition may be true or false,
>> depending on the definition "foo".
>>
>> d. In a standard system the first phrase (the left part of the
>> equivalency) may throw an exception for any "foo".
>>
>>
>> Multiple choice is admissible.
>>
>> It's enough to indicate (separately for the propositions 1 and 2) the
>> letters where your choice is "yes". E.g. P1: ac, P2: bcd.
>
> In my opinion compiling code while not in compilation state should
> not be done in a standard system.

It seems you wanted to say "in a standard program".

Then, you support [a99-027], don't you?


> It might work in some systems but not all.

If you think the standard allows that it doesn't work regardless "foo",
then your choice is the option "d".


>
> I really do not understand why you are pursuing this type of coding.

It's not a type of coding.

It's a problem of the language consistency and equivalences of different
expressions. In what cases the language meets a user's expectations in
this regard, and it what cases it doesn't. And why the language doesn't
meet them, if any. And what are the clear rules in this regard.

[a99-027] provides a clear rule, but many people don't follow it.

Actually, any standard system can support the expected equivalences,
(while they are consistent). But they should be clear verbalized.


>
> If you want to call foo in a definition why not use foo directly.
>
> : test foo ; will always work!



[a99-027] that performing compilation semantics in the interpretation
state is ambiguous.
https://groups.google.com/forum/message/raw?msg=comp.lang.forth/RmsDuen7YkY/xDvW74uzi30J/

--
Ruvim

Ruvim

unread,
Jun 20, 2021, 5:06:46 AM6/20/21
to
On 2021-06-20 11:30, albert wrote:
[...]

> e. Avoid POSTPONE like the plague. Always find a way around it.

It's impossible in too many cases.

For example, how do you define a well known but non standard word "rdrop"?

: rdrop postpone r> postpone drop ; immediate

It's impossible do define "rdrop" without "postpone" in a standard
program. Don't suggest to use "evaluate".


--
Ruvim

Paul Rubin

unread,
Jun 20, 2021, 5:32:19 AM6/20/21
to
Ruvim <ruvim...@gmail.com> writes:
> : rdrop postpone r> postpone drop ; immediate
>
> It's impossible do define "rdrop" without "postpone" in a standard
> program. Don't suggest to use "evaluate".

Is this nonstandard?

: rdrop r> r> drop ;

Ruvim

unread,
Jun 20, 2021, 5:42:50 AM6/20/21
to
Yes, this code isn't standard.

See 3.2.3.3 Return stack
https://forth-standard.org/standard/usage#usage:returnstack

Two excerpts:

A program shall not access values on the return stack (using "R@",
"R>", "2R@", "2R>" or "NR>") that it did not place there using ">R",
"2>R" or "N>R";

All values placed on the return stack within a definition shall be
removed before the definition is terminated or before EXIT is executed.



--
Ruvim

P Falth

unread,
Jun 20, 2021, 6:48:10 AM6/20/21
to
: foo1 noop ; immediate ok
: compile-foo1 postpone foo1 ; ok
: t6 [ compile-foo1 ] ; ok
see t6
A4A408 409A3F 1 C80000 5 normal T6

409A3F C3 ret near
ok

:p foo2 ." compiling" ;p ok
:r foo2 ." interpreting" ;r ok
foo2 interpreting ok
: compile-foo2 postpone foo2 ; ok
: t7 [ compile-foo2 ] ; compiling ok
see t7
A4A3D4 409A39 1 C80000 5 normal T7

409A39 C3 ret near
ok



> > : t3 [ postpone foo ] ; ok
> > see t3
> > A4A2E0 4099C5 16 C80000 5 normal T3
> >
> > 4099C5 895DFC mov [ebp-4h] , ebx
> > 4099C8 BBA6994000 mov ebx , # 4099A6h
> > 4099CD 8D6DFC lea ebp , [ebp-4h]
> > 4099D0 E92B668700 jmp COMPILE,
> > ok
> > : t4 [ ' foo compile, ] ; ok
> > see t4
> > A4A2F4 4099D5 5 C80000 5 normal T4
> >
> > 4099D5 E9CCFFFFFF jmp FOO
> > ok
> Then, you don't support equivalence for "compile," that it is equivalent
> to "postpone literal postpone execute", do you?

: t5 [ ' foo ] literal execute ; ok
see t5
A4A308 4099DA 8 C80000 5 normal T5

4099DA B8A6994000 mov eax , # 4099A6h
4099DF FFD0 call eax
4099E1 C3 ret near
ok

Looks to do the same thing but using 3 more bytes
Yes to this I agree

Peter

> https://groups.google.com/forum/message/raw?msg=comp.lang.forth/RmsDuen7YkY/xDvW74uzi30J/
>
> --
> Ruvim

none albert

unread,
Jun 20, 2021, 7:02:47 AM6/20/21
to
In article <87mtrkr...@nightsong.com>,
: rdrop "R> DROP" EVALUATE ;
There, I did it. One could save the search order and establish
forthwordlist as the only wordlist and one would be pretty safe.

Now Ruvim threaten me with ... because it is tabu and not pc.
With what? Problems? I have done some maintenance programming
in my life and face worse problems than those that could be
caused by that.

Alternatively:
If someone forced me to use a Forth without RDROP and I had to compile
a program with RDROP , I just would go to my boss, and say "hey, your
programs are not standard" and propose to replace all occurrences in
the application with the equivalent standard sequence. He would agree.

Alternatively:
CODE RDROP
LEA, SI'| BO| [SI] 8 B,
NEXT,

Alternatively:
: RDROP 'R> , 'DROP , ; IMMEDIATE

Alternatively:
Pseudo PC.
: RDROP ['] R> COMPILE, ['] DROP COMPILE, ; IMMEDIATE

Groetjes Albert

dxforth

unread,
Jun 20, 2021, 7:55:52 AM6/20/21
to
On 20/06/2021 06:03, Ruvim wrote:
>
> Let "foo" is a word that doesn't perform any parsing, doesn't access the
> parse area, and doesn't enter into compilation or interpretation state
> (i.e., any such behavior is not a part of any semantics for "foo").
>
> Let the word "compile-foo" is defined as:
> : compile-foo postpone foo ;
> and it has the same scope as the word "foo".
>
> Proposition 1.
> The phrase:
> [ compile-foo ]
> is equivalent to the phrase:
> foo
> in any such context when the phrase is encountered by the Forth
> text interpreter in compilation state.
>
> Proposition 2.
> The phrase:
> [ postpone foo ]
> is equivalent to the phrase:
> foo
> in any such context when the phrase is encountered by the Forth
> text interpreter in compilation state.

DX-Forth 4.45 2021-06-14

Software floating-point (separate stack)

Using FORTH.SCR

: foo noop ; ok
: compile-foo postpone foo ; COMPILE is system ok

: t1 [ compile-foo ] ;
Error: "compile-foo" compilation only

: t2 [ postpone foo ] ;
Error: "foo" compilation only

If POSTPONE is based on COMPILE, it typically can compile inside [ ] ;
if based on COMPILE it typically can not. Under ANS neither POSTPONE
nor COMPILE, is guaranteed to work inside [ ] . Disambigufiers for
them aren't guaranteed to work as they only work at the user level.

AFAICS the rule is: Don't attempt to compile while inside [ ] . Is there
a compelling reason why one should be able to?

Anton Ertl

unread,
Jun 20, 2021, 8:55:50 AM6/20/21
to
dxforth <dxf...@gmail.com> writes:
>: t1 [ compile-foo ] ;
>Error: "compile-foo" compilation only
...
>AFAICS the rule is: Don't attempt to compile while inside [ ] . Is there
>a compelling reason why one should be able to?

If I want to lay down code in interpret state, it's not the Forth
system's job to tell me I can't. Just delete ?COMP from your system.
Not only will your system work better, it will also be smaller.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2021: https://euro.theforth.net/2021

Ruvim

unread,
Jun 20, 2021, 9:40:30 AM6/20/21
to
[...]
>> What if "foo" is a dual semantics word? What if "foo" is also an
>> immediate? Does the system still hold this equivalence for such cases?
>
> : foo1 noop ; immediate ok
> : compile-foo1 postpone foo1 ; ok
> : t6 [ compile-foo1 ] ; ok
> see t6
> A4A408 409A3F 1 C80000 5 normal T6
>
> 409A3F C3 ret near
> ok
>
> :p foo2 ." compiling" ;p ok
> :r foo2 ." interpreting" ;r ok
> foo2 interpreting ok
> : compile-foo2 postpone foo2 ; ok
> : t7 [ compile-foo2 ] ; compiling ok
> see t7
> A4A3D4 409A39 1 C80000 5 normal T7
>
> 409A39 C3 ret near
> ok

According to the proposition, the equivalence takes place in compilation
state, so in this case the effects are also the same for:

] foo2 [
and
] [ compile-foo2 ] [


So, P1 is held for a single-semantics immediate word, and for a
dual-semantics word that is not immediate.

I suspect, P1 in your system is not held for a dual-semantics immediate
word. I.e., if you make foo2 STATE-dependent.




>>> : t3 [ postpone foo ] ; ok
>>> see t3
>>> A4A2E0 4099C5 16 C80000 5 normal T3
>>>
>>> 4099C5 895DFC mov [ebp-4h] , ebx
>>> 4099C8 BBA6994000 mov ebx , # 4099A6h
>>> 4099CD 8D6DFC lea ebp , [ebp-4h]
>>> 4099D0 E92B668700 jmp COMPILE,
>>> ok
>>> : t4 [ ' foo compile, ] ; ok
>>> see t4
>>> A4A2F4 4099D5 5 C80000 5 normal T4
>>>
>>> 4099D5 E9CCFFFFFF jmp FOO
>>> ok
>> Then, you don't support equivalence for "compile," that it is equivalent
>> to "postpone literal postpone execute", do you?
>
> : t5 [ ' foo ] literal execute ; ok
> see t5
> A4A308 4099DA 8 C80000 5 normal T5
>
> 4099DA B8A6994000 mov eax , # 4099A6h
> 4099DF FFD0 call eax
> 4099E1 C3 ret near
> ok
>
> Looks to do the same thing but using 3 more bytes

Yes, but in this example you replace the phrase:
compile, ]
by the phrase:
] literal execute

So, you show equivalence not for "compile," but for "compile, ]"




[...]
>>> I really do not understand why you are pursuing this type of coding.
>> >> It's not a type of coding.
>>
>> It's a problem of the language consistency and equivalences of different
>> expressions. In what cases the language meets a user's expectations in
>> this regard, and it what cases it doesn't. And why the language doesn't
>> meet them, if any. And what are the clear rules in this regard.
>>
>> [a99-027] provides a clear rule, but many people don't follow it.
>>
[...]
>> [a99-027] that performing compilation semantics in the interpretation
>> state is ambiguous.
>
> Yes to this I agree

It's good to know!

It looks like more systems rely on a99-027 than it seemed.


--
Ruvim

Ruvim

unread,
Jun 20, 2021, 10:05:33 AM6/20/21
to
It's the option "d" in my list.

BTW, a more appropriate error message should mention not "foo" but
"postpone" (perhaps I already said that before :).



> If  POSTPONE  is based on  COMPILE,  it typically can compile inside [ ] ;
> if based on  COMPILE  it typically can not.  Under ANS neither  POSTPONE
> nor  COMPILE,  is guaranteed to work inside  [ ] .  Disambigufiers for
> them aren't guaranteed to work as they only work at the user level.

A standard program can access only the user level. Hence, if you
guarantee that it works on the user level, it's enough. I provided a PoC
for that.


> AFAICS the rule is: Don't attempt to compile while inside [ ] .  Is there
> a compelling reason why one should be able to?

So you as an implementer rely on a99-027, and as a user you follow the
a99-027 rule (both its parts).


--
Ruvim

dxforth

unread,
Jun 20, 2021, 10:17:55 AM6/20/21
to
On 20/06/2021 22:53, Anton Ertl wrote:
> dxforth <dxf...@gmail.com> writes:
>>: t1 [ compile-foo ] ;
>>Error: "compile-foo" compilation only
> ...
>>AFAICS the rule is: Don't attempt to compile while inside [ ] . Is there
>>a compelling reason why one should be able to?
>
> If I want to lay down code in interpret state, it's not the Forth
> system's job to tell me I can't. Just delete ?COMP from your system.
> Not only will your system work better, it will also be smaller.

I know how to save memory. What are your reasons for compiling code
in interpret state given ANS saw none?

Krishna Myneni

unread,
Jun 20, 2021, 10:33:41 AM6/20/21
to
I will select position (b) tentatively for now. These phrases in Props 1
and 2 currently do not work in kForth, but I can't see a reason for them
not to work, provided that they are part of a definition.

Alternative ways to accomplish the same thing in kForth are the following:

: foo ." xxxx " ;
ok
: t1 [ ' foo compile, ] ;
ok
t1
xxxx ok
.s
<empty>
ok
: t2 [ ' foo ] literal execute ;
ok
t2
xxxx ok


Using POSTPONE to define RDROP works, of course, as it should per the
standard.

I might go a bit further than you in suggesting that FOO is allowed to
be a definition which contains anonymous definitions (quotations or
nested :NONAME definitions), for greater applicability. That might be a
bridge too far for some Forth system implementors, but, as a Forth
programmer as well as system implementor, I don't wish to be needlessly
restricted in how to code my problem. The changes required to accomplish
this do not appear to me to be too great a burden.

Krishna

Krishna Myneni

unread,
Jun 20, 2021, 10:38:55 AM6/20/21
to
The old saying about "penny-wise but pound-foolish" comes to mind. There
are problems where coding with nested anonymous definitions can make the
application more understandable and factorable. One way to implement
such definitions is to switch to interpretation state within a
definition and then begin compiling an anonymous definition.

Krishna

P Falth

unread,
Jun 20, 2021, 11:00:43 AM6/20/21
to
: t8 foo2 ; compiling ok
see t8
A4A41C 409A40 1 C80000 5 normal T8

409A40 C3 ret near
ok

Compiling out side a started definition is not supported in lxf.
only
] foo2 [
might crash the system

> So, P1 is held for a single-semantics immediate word, and for a
> dual-semantics word that is not immediate.
>
> I suspect, P1 in your system is not held for a dual-semantics immediate
> word. I.e., if you make foo2 STATE-dependent.

This is correct.
: comp, postpone literal postpone execute ; ok
: t9 [ ' foo comp, ] ; ok
see t9
A4A448 409A4B 8 C80000 5 normal T9

409A4B B8A6994000 mov eax , # 4099A6h
409A50 FFD0 call eax
409A52 C3 ret near
ok

works also in that case

Peter

dxforth

unread,
Jun 20, 2021, 11:51:49 AM6/20/21
to
A disambigufier for COMPILE, at the user level won't fix the COMPILE,
that results in T1 succeeding when the intention was it should fail.

>
>
>> AFAICS the rule is: Don't attempt to compile while inside [ ] .  Is there
>> a compelling reason why one should be able to?
>
> So you as an implementer rely on a99-027, and as a user you follow the
> a99-027 rule (both its parts).

I barely understand it. As an implementer I know about COMPILE and
common practice. As a user I know what turns on interpreting and what
turns it off. I assumed that was enough. Perhaps ANS did too.

Ruvim

unread,
Jun 20, 2021, 12:32:00 PM6/20/21
to
On 2021-06-20 18:00, P Falth wrote:
> On Sunday, 20 June 2021 at 15:40:30 UTC+2, Ruvim wrote:
>> On 2021-06-20 13:48, P Falth wrote:
[...]

>>> :p foo2 ." compiling" ;p ok
>>> :r foo2 ." interpreting" ;r ok

BTW, in my scratch it was:

: foo2 ." interpreting" ;
c: foo2 ." compiling" ;

And in the first version the special ";c" also was used.

Concerning naming conventions. If a word starts new definition and it's
a parsing word, give it a name in the from "xxx:". But if the word
starts new definition and it isn't a parsing word, give it a name in the
form ":xxx" (like in the case of the ":noname" word).

So I chose "c:" over ":c". It also has a slightly better readability.




>>> foo2 interpreting ok
>>> : compile-foo2 postpone foo2 ; ok
>>> : t7 [ compile-foo2 ] ; compiling ok
>>> see t7
>>> A4A3D4 409A39 1 C80000 5 normal T7
>>>
>>> 409A39 C3 ret near
>>> ok
>> According to the proposition, the equivalence takes place in compilation
>> state, so in this case the effects are also the same for:
>>
>> ] foo2 [
>> and
>> ] [ compile-foo2 ] [
>
> : t8 foo2 ; compiling ok
> see t8
> A4A41C 409A40 1 C80000 5 normal T8
>
> 409A40 C3 ret near
> ok
>
> Compiling out side a started definition is not supported in lxf.
> only
> ] foo2 [
> might crash the system

Yes, in the general case. And if it crashes the system, then it should
crash it in the both cases, and then the same effects are shown in both
cases.

OTOH, in this particular case "foo2" doesn't append anything to the
current definition, so it's unclear why it might crash the system?



>> So, P1 is held for a single-semantics immediate word, and for a
>> dual-semantics word that is not immediate.
>>
>> I suspect, P1 in your system is not held for a dual-semantics immediate
>> word. I.e., if you make foo2 STATE-dependent.
>
> This is correct.

If P1 is not held for some words (from the given domain), then P1 is
false (in the given conditions) in your system.

It's OK if you rely on a99-027, but it's a problem otherwise.




[...]
>>>> Then, you don't support equivalence for "compile," that it is equivalent
>>>> to "postpone literal postpone execute", do you?
>>>
>>> : t5 [ ' foo ] literal execute ; ok
>>> see t5
>>> A4A308 4099DA 8 C80000 5 normal T5
>>>
>>> 4099DA B8A6994000 mov eax , # 4099A6h
>>> 4099DF FFD0 call eax
>>> 4099E1 C3 ret near
>>> ok
>>>
>>> Looks to do the same thing but using 3 more bytes
>> Yes, but in this example you replace the phrase:
>> compile, ]
>> by the phrase:
>> ] literal execute
>>
>> So, you show equivalence not for "compile," but for "compile, ]"
>
> : comp, postpone literal postpone execute ; ok
> : t9 [ ' foo comp, ] ; ok
> see t9
> A4A448 409A4B 8 C80000 5 normal T9
>
> 409A4B B8A6994000 mov eax , # 4099A6h
> 409A50 FFD0 call eax
> 409A52 C3 ret near
> ok
>
> works also in that case

Yes. It means that "compile," is equivalent to "comp,", that is defined
as shown. It's useful equivalency too.

But it still doesn't show that:
compile,
is equivalent to:
postpone literal postpone execute

by the definition of equivalency that I provided in the starting post :-)


--
Ruvim

dxforth

unread,
Jun 20, 2021, 12:32:37 PM6/20/21
to
I discovered one. I amended my COMPILE, to include ?COMP.
Recompiling my system it choked on the following:

:noname ... [ ... ( xt) compile, ] ;

To make that work under ANS would require:

:noname ... [ ... ( xt) ] literal execute ;

which is non-optimum.

So was ANS wrong to specify no interpretation for COMPILE, - or did
they have a reason it couldn't? Classically COMPILE, was just , so
it would have to be for reasons other than ITC/DTC.

Ruvim

unread,
Jun 20, 2021, 1:34:15 PM6/20/21
to
On 2021-06-20 17:33, Krishna Myneni wrote:
> On 6/19/21 3:03 PM, Ruvim wrote:
>> A poll about equivalences for the "postpone x" expression.
>>
[...]
I also on this side.

But some programs assume that P1 is not held in some specific cases.

For example, your definition for "∋" is not compatible with a system
that holds P1 (and its generalization).

Some excerpts from kForth-64/forth-src/modules.fs
at https://git.io/Jnos8

: module-do-ref ( ... xt 1 | xt -1 -- ...)
-1 = state @ and IF compile, ELSE execute THEN ;

: [m] ( ... "module-name" "word-name" -- ? )
member-find
?dup IF module-do-ref ELSE member-not-found THEN
; immediate

: ∋ postpone [m] ; immediate

If a system holds P2, and the equivalence for "compile,", then "∋" can
be defined as:

: ∋ [ ' [m] compile, ] ; immediate


Also, in this case it's possible to use "synonym".


A compatible way In a syst A compatibile wah

: ∋ postpone [m] ; immediate





[...]
> I might go a bit further than you in suggesting that FOO is allowed to
> be a definition which contains anonymous definitions (quotations or
> nested :NONAME definitions), for greater applicability.

It's allowed. I restricted only the semantics for "foo" to have simpler
test cases (the phrases in P1 and P2). These restrictions on "foo" can
be eliminated, by the cost of more complicated test cases.


> That might be a
> bridge too far for some Forth system implementors, but, as a Forth
> programmer as well as system implementor, I don't wish to be needlessly
> restricted in how to code my problem. The changes required to accomplish
> this do not appear to me to be too great a burden.


--
Ruvim

P Falth

unread,
Jun 20, 2021, 1:54:23 PM6/20/21
to
On Sunday, 20 June 2021 at 18:32:00 UTC+2, Ruvim wrote:
> On 2021-06-20 18:00, P Falth wrote:
> > On Sunday, 20 June 2021 at 15:40:30 UTC+2, Ruvim wrote:
> >> On 2021-06-20 13:48, P Falth wrote:
> [...]
> >>> :p foo2 ." compiling" ;p ok
> >>> :r foo2 ." interpreting" ;r ok
> BTW, in my scratch it was:
>
> : foo2 ." interpreting" ;
> c: foo2 ." compiling" ;
>
> And in the first version the special ";c" also was used.
>
> Concerning naming conventions. If a word starts new definition and it's
> a parsing word, give it a name in the from "xxx:". But if the word
> starts new definition and it isn't a parsing word, give it a name in the
> form ":xxx" (like in the case of the ":noname" word).

I know that was a mistake done 20 years ago!
having it like p: makes it also easier to search for a definition of a word in a source file.
I do not remember why I chose these words! I think p was for primitive and
r definitely for runtime. The ;p and ;r are needed.
Important for me was that the compile action was defined first and
independently from the interpretation action.
In fact it will not, for that reason. But something like ] dup [ will if no definitions
has been done since the start of the system., as the code generator is not
initialized.

> >> So, P1 is held for a single-semantics immediate word, and for a
> >> dual-semantics word that is not immediate.
> >>
> >> I suspect, P1 in your system is not held for a dual-semantics immediate
> >> word. I.e., if you make foo2 STATE-dependent.
> >
> > This is correct.
> If P1 is not held for some words (from the given domain), then P1 is
> false (in the given conditions) in your system.
>
> It's OK if you rely on a99-027, but it's a problem otherwise.
It is a problem for someone writing state smart words.
I will not do that.
In LXF64 I have postexecute that will execute a postponed immediate word
with state set to compiling.
But how could I do that?
: T9 [ ' foo postpone literal postpone execute ] ;
will produce a completely different result!

Peter

>
> --
> Ruvim

Gerry Jackson

unread,
Jun 20, 2021, 3:49:53 PM6/20/21
to
On 20/06/2021 08:20, P Falth wrote:
> In my opinion compiling code while not in compilation state should
> not be done in a standard system. It might work in some systems
> but not all.

If [ ... ] is in the middle of a colon definition I don't see any
problem with the code in interpretation mode compiling code into the
incomplete colon definition.

Executing immediate code during compilation is part of the standard and
has always been in Forth. Why is compiling code when interpreting
regarded as wrong?

As Q99-027 making it ambiguous never made it into the standard it is
irrelevant and so isn't forbidden as are the opinions of people who are
no longer involved with the standard.

--
Gerry

Krishna Myneni

unread,
Jun 20, 2021, 9:45:08 PM6/20/21
to
Ok, I see what you mean. Gforth holds to proposition 1 (P1):

-------
: foo ." xxx " ; ok
: compile-foo postpone foo ; ok
: t0 foo ; ok
: t1 [ compile-foo ] ; ok

see t0
: t0
foo ; ok
see t1
: t1
foo ; ok

include modules.fs ok
Module: modcheck ok
Begin-Module ok
Public: ok
: foo ." xxxx " ; ok
End-Module ok
Also modcheck ok
[m] modcheck foo xxxx ok
∋ modcheck foo xxxx ok
: test [ ∋ modcheck foo ] ; xxxx ok
------

However, this is in fact the intended behaviour of the module member
reference syntax. The underlying word, MODULE-DO-REF , is state-smart so
that [M] and its graphic equivalent ∋ will always execute the referenced
module member function when in interpretation state. kForth gives the
same behavior as above for the modcheck modules example.

In the use setting of data acquistion and control, it is necessary to be
able to execute module member functions directly from the interpreter.
For such applications, no use cases have come up in which a phrase such
as [ ∋ modcheck foo ] is used inside of a definition, particularly for
the purpose of compiling module member functions. However, it is
certainly possible that there may exist use cases for compilation
behavior of such phrases when used inside of a definition. In such a
case, a different word is needed.

> Some excerpts from kForth-64/forth-src/modules.fs
> at https://git.io/Jnos8
>
>   : module-do-ref ( ... xt 1 | xt -1 -- ...)
>     -1 = state @ and IF  compile, ELSE execute THEN ;
>
>   : [m] ( ... "module-name"  "word-name" -- ? )
>      member-find
>      ?dup IF  module-do-ref  ELSE  member-not-found  THEN
>   ; immediate
>
>   : ∋ postpone [m] ; immediate
>
> If a system holds P2, and the equivalence for "compile,", then "∋" can
> be defined as:
>
>   : ∋ [ ' [m] compile, ] ; immediate
>
>
> Also, in this case it's possible to use "synonym".
>

I believe we will find many cases in which we need to use a different
word to reference a module member function when compilation behavior is
explicitly needed. It is cases like these in which dual-semantics Forth
systems may possess a clear advantage for predicting what source code
will do.

Krishna

Krishna Myneni

unread,
Jun 20, 2021, 10:42:10 PM6/20/21
to
> ...

Ok, we have the word [M'] to provide compiling behavior, e.g., for the
modcheck module example,

-----
: test [m] modcheck foo ; \ ok
test xxxx ok
: test ∋ modcheck foo ; \ ... ok
test xxxx ok

: test [m'] modcheck foo execute ; \ ... ok
test xxxx ok
: test [ [m'] modcheck foo ] execute ; \ ... ok
test xxxx ok
-----

The last definition of TEST does not work in kForth, owing to the fact
that it does not obey Proposition 1. It does work in Gforth, however.

Krishna




dxforth

unread,
Jun 20, 2021, 11:10:35 PM6/20/21
to
Elizabeth's comment re nested anonymous definitions still resonates with me.
AFAIK to compile an anonymous definition requires executing :NONAME which
sets compilation state.

dxforth

unread,
Jun 20, 2021, 11:38:32 PM6/20/21
to
On 21/06/2021 05:49, Gerry Jackson wrote:
> On 20/06/2021 08:20, P Falth wrote:
>> In my opinion compiling code while not in compilation state should
>> not be done in a standard system. It might work in some systems
>> but not all.
>
> If [ ... ] is in the middle of a colon definition I don't see any
> problem with the code in interpretation mode compiling code into the
> incomplete colon definition.
>
> Executing immediate code during compilation is part of the standard and
> has always been in Forth. Why is compiling code when interpreting
> regarded as wrong?

Why is it right? Implicit in compiling code is the notion one is no
longer interpreting.

Ruvim

unread,
Jun 21, 2021, 1:30:16 AM6/21/21
to
On 2021-06-20 20:54, P Falth wrote:
> On Sunday, 20 June 2021 at 18:32:00 UTC+2, Ruvim wrote:
>> On 2021-06-20 18:00, P Falth wrote:
>>> On Sunday, 20 June 2021 at 15:40:30 UTC+2, Ruvim wrote:
[...]
>>>> So, P1 is held for a single-semantics immediate word, and for a
>>>> dual-semantics word that is not immediate.
>>>>
>>>> I suspect, P1 in your system is not held for a dual-semantics immediate
>>>> word. I.e., if you make foo2 STATE-dependent.
>>>
>>> This is correct.
>> If P1 is not held for some words (from the given domain), then P1 is
>> false (in the given conditions) in your system.
>>
>> It's OK if you rely on a99-027, but it's a problem otherwise.
> It is a problem for someone writing state smart words.

I consider non-fulfilment of P1 as an inconsistency in the Forth
language/implementation, and as any inconsistency, this inconsistency
leads to some problems, depending on particular twists. And the problems
with "state smart" words is a result of this inconsistency too.

A method to define a dual semantics word via two definitions (and even
removing the "STATE" word) doesn't solve this inconsistency, but just
buries it deeper. It's possible to show this inconsistency anyway.

a99-027 also doesn't solve the problem, but makes a workaround: it
declares that any code that can detect this inconsistency, is ambiguous.


> I will not do that.

It also just a workaround. You know a problem, and avoid it. But the
language/implementation itself still contains this inconsistency.


> In LXF64 I have postexecute that will execute a postponed immediate word
> with state set to compiling.

There is a nuance. What if a request to enter into compilation state is
a part of some compilation semantics. At the moment, such behavior may
be a part of a standard program (see the "]" word). So, I don't revert
the state in such case (see: https://git.io/JnoHY ).

Maybe it makes sense to declare that such behavior is ambiguous.
Yes, in your system. It just means that in you system this equivalency
for "compile," is not held in interpretation state, but possibly it's
held in compilation state.

That is, the phrase:

compile,

is equivalent to the phrase:

postpone literal postpone execute

in any such context where these phrases are encountered by the Forth
text interpreter in *compilation state*.

(I don't sure that your system holds this in edge cases, but this is the
idea)



To also hold this equivalency in interpretation state, you have to
define the following interpretation semantics for "postpone".

"POSTPONE" Interpretation: Skip leading space delimiters. Parse
/name/ delimited by a space. Find /name/. Perform the compilation
semantics of /name/.


But it opposes to the conception that a program is not allowed to
perform compilation semantics in interpretation state.



--
Ruvim

Gerry Jackson

unread,
Jun 21, 2021, 4:27:18 AM6/21/21
to
Perhaps I asked the wrong question. There is no absolute right and wrong
answer, just whether we should stick to purity and say do we want to
interpret while compiling. Purity is already blurred by the existence of
immediacy and built-in immediate words like IF. Immediacy is largely an
unnecessary convenience because there is an easy work around.

The question is what is the objection to compiling in interpreter mode
if it works and is harmless apart from possibly being wasteful if not in
the middle of a colon definition. The fact that it works in several, if
not all systems, seems to indicate that it requires a bit of extra code
to prevent it. I would have thought that all you KISS, 'don't like
ambiguity', 'don't like being told what to do', anti standard people
would approve :)

--
Gerry

dxforth

unread,
Jun 21, 2021, 6:20:41 AM6/21/21
to
It benefits us all to be clear what we're doing and why. As I see it:

a) For a definition, compilation mode is entered by executing : and
remains so until ; is encountered. Words within : ; are compiled
by default. The exception is immediate words which do something
immediately and compile the result as executable code. [ ] plays
no part in compilation - rather it allows something to be put on
the data stack at compile-time for a compiling word to use.
Because compiling words are typically immediate (LITERAL POSTPONE
etc) there is no need to execute them within [ ]. More importantly,
nothing is gained by doing so. ANS has marked all code compiling
words as having 'no interpretation semantics' for that reason.

b) Outside a definition there's no reason to compile code and no way
to execute it even if one did. So no need to consider further.

c) ANS has included COMPILE, among the words having no interpretation
semantics. While it could be useful to execute COMPILE, within [ ]
it is not essential e.g. VFX will optimize: [ xt ] LITERAL EXECUTE

Krishna Myneni

unread,
Jun 21, 2021, 7:42:47 AM6/21/21
to
On 6/19/21 3:03 PM, Ruvim wrote:
...
>
> Let "foo" is a word that doesn't perform any parsing, doesn't access the
> parse area, and doesn't enter into compilation or interpretation state
> (i.e., any such behavior is not a part of any semantics for "foo").
>
> Let the word "compile-foo" is defined as:
>   : compile-foo postpone foo ;
> and it has the same scope as the word "foo".
>
>
>
> Proposition 1.
>   The phrase:
>     [ compile-foo ]
>   is equivalent to the phrase:
>       foo
>   in any such context when the phrase is encountered by the Forth
>   text interpreter in compilation state.
>
>

What is your expectation for use of the phrase "[ COMPILE-FOO ]" inside
of a definition, when COMPILE-FOO is tagged as an immediate word?

: compile-foo postpone foo ; immediate

In this case the compilation semantics of COMPILE-FOO should be the same
as its runtime semantics.

Krishna


S Jack

unread,
Jun 21, 2021, 10:09:35 AM6/21/21
to
On Sunday, June 20, 2021 at 9:33:41 AM UTC-5, Krishna Myneni wrote:
> I might go a bit further than you in suggesting that FOO is allowed to
> be a definition which contains anonymous definitions (quotations or
> nested :NONAME definitions), for greater applicability. That might be a

Anonymous compile in on-going definition:

: foo ." FOO "
[ smudge csp @
' branch compile, ahead
anon ." BOO " ;
swap resolve
swap csp !
] ." BAR " literal enter ;

foo \ => FOO BAR BOO

It seems I can but I won't.

--
me

Gerry Jackson

unread,
Jun 21, 2021, 10:13:37 AM6/21/21
to
It would be silly to execute them directly because their behaviour is
undefined in interpretation mode, but they can be executed by a call to
a colon definition that uses them.

>  More importantly, nothing is gained by doing so.

Never say never, someone may find it useful.

>  ANS has marked all code compiling
>    words as having 'no interpretation semantics' for that reason.

Not just for that reason, more likely for preventing execution of
compiling words outside a colon definition.

>
> b) Outside a definition there's no reason to compile code and no way
>    to execute it even if one did.  So no need to consider further.

Quite, it would silly to do so.

>
> c) ANS has included COMPILE, among the words having no interpretation
>    semantics.  While it could be useful to execute COMPILE, within [ ]
>    it is not essential e.g. VFX will optimize:  [ xt ] LITERAL EXECUTE

In general, the fact that one system optimises something proves nothing.
--
Gerry

dxforth

unread,
Jun 21, 2021, 11:31:52 AM6/21/21
to
Their behaviour is undefined any time STATE=0. That didn't stop Ruvim
conducting a poll asking what different systems do in that instance:

https://groups.google.com/g/comp.lang.forth/c/QY-XBI8e3AE/m/Rn7EGtSuBAAJ

>
>>  More importantly, nothing is gained by doing so.
>
> Never say never, someone may find it useful.

When I'm shown something that doesn't flout ANS' rules on compiling words
then we can discuss whether it's useful.

P Falth

unread,
Jun 21, 2021, 2:34:14 PM6/21/21
to
So you want to make postpone a dual semantics words or state-smart word!

Maybe it is better to give it a new name as the behavior changed
maybe [POSTPONE] or ]POSTPONE[

But I think I see what you want to achieve, will you suggest similar behavior for
other compile only words like IF etc.

I can see an alternative instead by changing [ and ]
[ suspends compilation and sets up a temporary code space and continues compilation
] ends the temporary definition, restores the suspended definition and executes
the code just compiled

I can't say it it is usefully. But neither I think it s useful to compile in interpret state!

BR
Peter

Ruvim

unread,
Jun 22, 2021, 7:34:59 AM6/22/21
to
On 2021-06-21 04:45, Krishna Myneni wrote:
> On 6/20/21 12:34 PM, Ruvim wrote:
>> On 2021-06-20 17:33, Krishna Myneni wrote:
>>> On 6/19/21 3:03 PM, Ruvim wrote:
>>>> A poll about equivalences for the "postpone x" expression.
>>>>
>> [...]
>>>>
>>>> Let "foo" is a word that doesn't perform any parsing, doesn't access
>>>> the parse area, and doesn't enter into compilation or interpretation
>>>> state (i.e., any such behavior is not a part of any semantics for
>>>> "foo").
>>>>
>>>> Let the word "compile-foo" is defined as:
>>>>    : compile-foo postpone foo ;
>>>> and it has the same scope as the word "foo".
>>>>
>>>>
>>>>
>>>> Proposition 1.
>>>>    The phrase:
>>>>      [ compile-foo ]
>>>>    is equivalent to the phrase:
>>>>        foo
>>>>    in any such context when the phrase is encountered by the Forth
>>>>    text interpreter in compilation state.
>>>>
[...]
>>>>
>>>>   b. It's better if the proposition is true in a system.
>>>>
[...]

>>> I will select position (b) tentatively for now.
>>
>> I also on this side.
>>
>> But some programs assume that P1 is not held in some specific cases.
>>
>> For example, your definition for "∋" is not compatible with a system
>> that holds P1 (and its generalization).
>>
>
> Ok, I see what you mean.

> Gforth holds to proposition 1 (P1):

No, it doesn't.

In some cases — yes. But in general, Gforth doesn't hold P1.


--
Ruvim

Krishna Myneni

unread,
Jun 22, 2021, 8:24:06 AM6/22/21
to
Perhaps you can provide some test code for checking whether or not P1 or
P2 holds for a Forth system. Without test code, it is difficult to
understand exactly what you are aiming for.

Krishna


Ruvim

unread,
Jun 22, 2021, 9:19:41 AM6/22/21
to
On 2021-06-21 21:34, P Falth wrote:
> On Monday, 21 June 2021 at 07:30:16 UTC+2, Ruvim wrote:
>> On 2021-06-20 20:54, P Falth wrote:
[...]
>>> But how could I do that?
>>> : T9 [ ' foo postpone literal postpone execute ] ;
>>> will produce a completely different result!
>> Yes, in your system. It just means that in you system this equivalency
>> for "compile," is not held in interpretation state, but possibly it's
>> held in compilation state.
>>
>> That is, the phrase:
>>
>> compile,
>>
>> is equivalent to the phrase:
>>
>> postpone literal postpone execute
>>
>> in any such context where these phrases are encountered by the Forth
>> text interpreter in *compilation state*.
>>
>> (I don't sure that your system holds this in edge cases, but this is the
>> idea)
>>
>>
>> To also hold this equivalency in interpretation state, you have to
>> define the following interpretation semantics for "postpone".
>>
>> "POSTPONE" Interpretation: Skip leading space delimiters. Parse
>> /name/ delimited by a space. Find /name/. Perform the compilation
>> semantics of /name/.
>
> So you want to make postpone a dual semantics words or state-smart word!

I don't talk about standardization at the moment (see [1] below).

It's just a solution, how to hold the given equivalency in
interpretation state (NB: it's another one, neither P1 nor P2, but it's
connected with P2).


> Maybe it is better to give it a new name as the behavior changed
> maybe [POSTPONE] or ]POSTPONE[

A standard system is allowed to provide the given interpretation
semantics for "POSTPONE". Such "POSTPONE" can break nothing, why do we
need another name?



> But I think I see what you want to achieve, will you suggest similar behavior for
> other compile only words like IF etc.
>
> I can see an alternative instead by changing [ and ]
> [ suspends compilation and sets up a temporary code space and continues compilation
> ] ends the temporary definition, restores the suspended definition and executes
> the code just compiled

It's a nice idea!

But it's isn't compliant.
E.g., it fails on the following:

[ char | parse any text | 2drop ]

So in this case we need other names for these words.


> I can't say it it is usefully. But neither I think it s useful to compile in interpret state!

What about a Forth-assembler? It compiles in interpretation state. And
it seems, it very useful. Isn't it?

When we write something like:

[ ' x compile, ]

it can be considered as a kind of a Forth assembler, when you compile
something in interpretation state.



-----


[1] Concerning dual-semantics words.

According to the definition for the "dual-semantics word" term [2], if
you see the different effects when a non ordinary word is encountered by
the Forth text interpreter in interpretation state, and when it's
encountered in compilation state, then this word is a dual-semantics
word (by implementation).

So, if a system throws an exception when interpreting "postpone", then
"postpone" is implemented as a dual-semantics word.

It's a common case that the words for which the standard undefines
interpretation semantics are implemented as dual-semantics words.



[2] "Problem of FIND, rethinking", 2021-05-19
news:s81ftp$geg$1...@dont-email.me
http://al.howardknight.net/?ID=162255657000

A dual-semantics word is a non ordinary word, for which the
interpretation semantics are not equivalent to the compilation semantics.


--
Ruvim

Ruvim

unread,
Jun 22, 2021, 9:33:44 AM6/22/21
to
On 2021-06-21 11:27, Gerry Jackson wrote:

> Purity is already blurred by the existence of
> immediacy and built-in immediate words like IF.

The standard doesn't require to implement "IF" as an immediate word.

Perhaps you mean by "immediacy" something different.


> Immediacy is largely an
> unnecessary convenience because there is an easy work around.

What a work around do you mean?

By my understanding, immediacy (in the standard notion) is just a way to
implement non default compilation semantics and dual-semantics words.


--
Ruvim

Ruvim

unread,
Jun 22, 2021, 12:40:27 PM6/22/21
to
A test code cannot prove that these propositions are held. In some
cases, by a chance, a test code can prove that they are not held.

So for these propositions, a test code either shows that a proposition
isn't held, or shows nothing.


The test cases are following.


\ some helpers
: execute-balance ( i*x xt -- j*x n )
depth 1- >r execute depth r> -
;
: qe{ ( i*x "ccc }" -- j*x n-balance-compiling )
\ Parse the input buffer up to "}",
\ create a quotation (one-liner), execute it,
\ place on the stack the difference in the depth during compilation.
\ CS: not implemented (abort)
\ qe{ [ 10 20 ] 30 } ( -- 10 20 30 2 )
state @ abort" not implemented"
['] :noname execute-balance n>r [char] } parse
['] evaluate execute-balance 2 +
nr> drop postpone ; swap >r execute r>
; immediate


\ some "foo" words for testing

: foo1 ( -- x ) 1 ;
: foo2 ( -- x ) 2 ; immediate
: foo3 ( -- x ) state @ 0<> ; immediate



\ testing some "foo"

: compile-foo1 postpone foo1 ;
t{
qe{ foo1 }
->
qe{ [ compile-foo1 ] }
}t

: compile-foo2 postpone foo2 ;
t{
qe{ foo2 }
->
qe{ [ compile-foo2 ] }
}t

: compile-foo3 postpone foo3 ;
t{
qe{ foo3 }
->
qe{ [ compile-foo3 ] }
}t

: compile-if postpone if ;
t{
0 1 qe{ if 10 or then }
->
0 1 qe{ [ compile-if ] 10 or then }
}t



Take into account that testing is blind concerning how "foo" is defined,
what its semantics, what its behavior in the different conditions, etc.

NB: a polyfill can be loaded into any standard system so the system will
pass this test.



--
Ruvim

Gerry Jackson

unread,
Jun 22, 2021, 2:42:59 PM6/22/21
to
On 22/06/2021 14:33, Ruvim wrote:
> On 2021-06-21 11:27, Gerry Jackson wrote:
>
>> Purity is already blurred by the existence of immediacy and built-in
>> immediate words like IF.
>
> The standard doesn't require to implement "IF" as an immediate word.
>
> Perhaps you mean by "immediacy" something different.

I qualified immediacy by 'built in' but I agree it's poorly worded

>
>
>> Immediacy is largely an unnecessary convenience because there is an
>> easy work around.
>
> What a work around do you mean?

: foo ... ; immediate
: bar ... foo ... ;
can be replaced by
: foo ... ;
: bar ... [ foo ] ... ;

unless FOO is state smart which is why I wrote 'largely'. Also if FOO
does things like POSTPONEing or COMPILE,ing I assume that will work.

>
> By my understanding, immediacy (in the standard notion) is just a way to
> implement non default compilation semantics and dual-semantics words.
>
>


--
Gerry

Ruvim

unread,
Jun 22, 2021, 4:26:33 PM6/22/21
to
On 2021-06-22 21:43, Gerry Jackson wrote:
> On 22/06/2021 14:33, Ruvim wrote:
>> On 2021-06-21 11:27, Gerry Jackson wrote:
>>
>>> Purity is already blurred by the existence of immediacy and built-in
>>> immediate words like IF.
>>
>> The standard doesn't require to implement "IF" as an immediate word.
>>
>> Perhaps you mean by "immediacy" something different.
>
> I qualified immediacy by 'built in' but I agree it's poorly worded
>
>>
>>
>>> Immediacy is largely an unnecessary convenience because there is an
>>> easy work around.
>>
>> What a work around do you mean?
>
> : foo ... ; immediate
> : bar ... foo ... ;
> can be replaced by
> : foo ... ;
> : bar ... [ foo ] ... ;


Yes, it's just a convenience. But it's a useful and demanded convenience.

Without that a control flow can look as:

: bar [ if, ] baz [ then, ] qux [ ;



> unless FOO is state smart which is why I wrote 'largely'.

Instead of a dual-semantics word we have to use two ordinary words.

To compile a string literal, we can do:

[ s" test" slit, ]
or
[ s" test", ]

To compile a character 'x':

[ char x lit, ]

To compile "to x":

[ to x, ]


> Also if FOO
> does things like POSTPONEing or COMPILE,ing I assume that will work.

Yes, it's an expected behavior.

But if we don't have such a thing like non default compilation
semantics, then "postpone x" is equivalent to "['] x compile," that is
equivalent to "[ ' x lit, ] compile,"

That is,
: foo postpone x ; immediate
: bar foo ;
<=>
: foo postpone x ;
: bar [ foo ] ;
<=>
: foo [ ' x lit, ] compile, ;
: bar [ foo ] ;
<=>
: bar [ ' x compile, ] ;

>>
>> By my understanding, immediacy (in the standard notion) is just a way
>> to implement non default compilation semantics and dual-semantics words.
>>

--
Ruvim

Ruvim

unread,
Jun 24, 2021, 10:20:51 AM6/24/21
to
On 2021-06-19 23:03, Ruvim wrote:
> A poll about equivalences for the "postpone x" expression.
>
[...]
>
> Let "foo" is a word that doesn't perform any parsing, doesn't access the
> parse area, and doesn't enter into compilation or interpretation state
> (i.e., any such behavior is not a part of any semantics for "foo").
>
> Let the word "compile-foo" is defined as:
>   : compile-foo postpone foo ;
> and it has the same scope as the word "foo".
>
>
>
> Proposition 1.
>   The phrase:
>     [ compile-foo ]
>   is equivalent to the phrase:
>       foo
>   in any such context when the phrase is encountered by the Forth
>   text interpreter in compilation state.
>
>
>
> Proposition 2.
>   The phrase:
>     [ postpone foo ]
>   is equivalent to the phrase:
>       foo
>   in any such context when the phrase is encountered by the Forth
>   text interpreter in compilation state.
>


Proposition 3.
The phrase:
postpone literal postpone execute
is equivalent to the phrase:
compile,
in any context.




Rationale.

1. Creating a definition programmatically has nothing to do with
compilation state and STATE. So, it should be possible regardless of the
STATE.

2. The "code ... end-code" construct works in interpretation state.

3. Then "compile," can also work in interpretation state.

4. Then "compile-foo" (defined as it's shown above) should also work in
interpretation state, and P1 should be held.

5. Assuming that P3 (an equivalence for "compile,") is held, P2 should
be held too.




--
Ruvim

dxforth

unread,
Jun 24, 2021, 6:49:22 PM6/24/21
to
"code ... end-code" 'comma in' data as opposed to compiling a high-level
forth definition which sets 'compilation mode' and therefore STATE. It's
comparing apples and oranges.

If the proposition is compiling words should be usable inside [ ] which
AFAIK currently isn't permitted in standard programs, it would be more
convincing to argue this from a needs/benefit basis rather than equivalence
(same result obtained differently) or dubious comparisons (assembler).

Ruvim

unread,
Jun 25, 2021, 7:25:56 AM6/25/21
to
What is wrong to incrementally build a high-level forth definition in
interpretation state?


Well, what if we redefine "compile," and "postpone" in the following way:

: state-on ] ;
: state-off postpone [ ;

: execute-compiling ( ... xt -- ... )
state @ if execute exit then
state-on execute state-off
;
\ NB: the edge cases are not considered
\ for the sake of this example simplicity.

: compile, ( xt -- )
['] compile, execute-compiling
;
: postpone ( "name" -- )
postpone [: postpone postpone postpone ;]
postpone execute-compiling
; immediate


Now "compile," can be used interpretively, and a postponed code can be
started in interpretation state — from a program point of view. But from
the system's point of view (and the postponed code point of view), they
are performed in compilation state.

What a problem do you see now?



> If the proposition is compiling words should be usable inside [ ] which
> AFAIK currently isn't permitted in standard programs, it would be more
> convincing to argue this from a needs/benefit basis rather than equivalence
> (same result obtained differently) or dubious comparisons (assembler).

If we talk about consistency of a system, needs or benefits don't matter
at all.

But equivalency is a fundamental mechanism.

Why, in arithmetic, x^0 = 1 (for any x <> 0 ) ?

Since x^0 = x^(-1 + 1) = x^(-1) * x^(1) = 1/x * x = x/x = 1

It's just a consequence of equivalences that shall be held.


--
Ruvim

dxforth

unread,
Jun 25, 2021, 8:55:57 AM6/25/21
to
: ', ' ] compile, postpone [ ;

: foo [ ', >r ', * ', r> ', / ] ;

vs.

: foo >r * r> / ;
confusion <-- contravention

>
>
> --
> Ruvim
>

Ruvim

unread,
Jun 25, 2021, 9:21:48 AM6/25/21
to
On 2021-06-25 15:55, dxforth wrote:
> On 25/06/2021 21:25, Ruvim wrote:
>> On 2021-06-25 01:49, dxforth wrote:
>>> On 25/06/2021 00:20, Ruvim wrote:
[...]
>>>> Rationale.
>>>>
>>>> 1. Creating a definition programmatically has nothing to do with
>>>> compilation state and STATE. So, it should be possible regardless of
>>>> the
>>>> STATE.
>>>>
>>>> 2. The "code ... end-code" construct works in interpretation state.
>>>>
>>>> 3. Then "compile," can also work in interpretation state.
>>>>
>>>> 4. Then "compile-foo" (defined as it's shown above) should also work in
>>>> interpretation state, and P1 should be held.
>>>>
>>>> 5. Assuming that P3 (an equivalence for "compile,") is held, P2 should
>>>> be held too.
>>>>
>>>
>>> "code ... end-code" 'comma in' data as opposed to compiling a high-level
>>> forth definition which sets 'compilation mode' and therefore STATE.
>>> It's
>>> comparing apples and oranges.
>>
>> What is wrong to incrementally build a high-level forth definition in
>> interpretation state?
>
> : ',  ' ] compile, postpone [ ;
>
> : foo  [ ', >r  ', *  ', r>  ', / ] ;
>
> vs.
>
> : foo  >r * r> / ;

As I can see, nothing wrong. It just works. Yes, it has more size. But
"compilation state" was introduced to make code shorter, I think. So
compilation state doesn't abolish incremental compilation in
interpretation state in principle.


BTW colorForth also compiles in interpretation state (it doesn't have
compilation state). In this sense, it's a kind of a Forth-assembler.

Your "'," prefix could be also a part of a colorless colorForth.



[...]
>> Now "compile," can be used interpretively, and a postponed code can be
>> started in interpretation state — from a program point of view. But from
>> the system's point of view (and the postponed code point of view), they
>> are performed in compilation state.
>>
>> What a problem do you see now?



>>> If the proposition is compiling words should be usable inside [ ] which
>>> AFAIK currently isn't permitted in standard programs, it would be more
>>> convincing to argue this from a needs/benefit basis rather than
>>> equivalence
>>> (same result obtained differently) or dubious comparisons (assembler).
>>
>> If we talk about consistency of a system, needs or benefits don't matter
>> at all.
>>
>> But equivalency is a fundamental mechanism.
>>
>> Why, in arithmetic, x^0 = 1 (for any x <> 0 ) ?
>>
>> Since x^0 = x^(-1 + 1) = x^(-1) * x^(1) = 1/x * x = x/x = 1
>>
>> It's just a consequence of equivalences that shall be held.
>
> confusion <-- contravention

What do you mean?


--
Ruvim

P Falth

unread,
Jun 25, 2021, 11:58:08 AM6/25/21
to
on lxf

: ', ' ] compile, postpone [ ; ok
: foo [ ', >r ', * ', r> ', / ] ; FOO redefined ok
: foo1 >r * r> / ; FOO1 redefined ok
see foo
A4A4E8 409AB3 20 C80000 5 normal FOO

409AB3 E8062C8800 call >R
409AB8 E8FA4E8800 call *
409ABD E8212C8800 call R>
409AC2 E91A4F8800 jmp /
ok
see foo1
A4A4FC 409AC7 16 C80000 5 normal FOO1

409AC7 8B4504 mov eax , [ebp+4h]
409ACA 0FAF4500 imul eax , dword [ebp]
409ACE 99 cdq
409ACF F7FB idiv ebx
409AD1 8BD8 mov ebx , eax
409AD3 8D6D08 lea ebp , [ebp+8h]
409AD6 C3 ret near
ok
10 2 5 foo1 . 4 ok
10 2 5 foo . 1 ok

more size, less efficient and wrong result.
I have some difficulty seeing the benefit!

To get the correct result

: foo [ >r ', * r> ', / ] ; FOO redefined ok
see foo
A4A514 409AD7 37 C80000 5 normal FOO

409AD7 895C24FC mov [esp-4h] , ebx
409ADB 8B5D00 mov ebx , [ebp]
409ADE 8D6D04 lea ebp , [ebp+4h]
409AE1 8D6424FC lea esp , [esp-4h]
409AE5 E8CD4E8800 call *
409AEA 895DFC mov [ebp-4h] , ebx
409AED 8B1C24 mov ebx , [esp]
409AF0 8D6DFC lea ebp , [ebp-4h]
409AF3 8D642404 lea esp , [esp+4h]
409AF7 E9E54E8800 jmp /
ok
10 2 5 foo . 4 ok

BR
Peter

Ruvim

unread,
Jun 25, 2021, 4:33:30 PM6/25/21
to
It's obvious, this "foo" is not standard. A standard program cannot tick
">r". It's a system specific definition, namely it's compliant with only
the systems where ">r" and "r>" are implemented as ordinary words. lxf
is not such a system.


> I have some difficulty seeing the benefit!

Compiling some (or all) parts of a definition in interpretation state
can benefit for debugging or learning purposes, or for meta programming
in rare cases.

Another possible application is bootstrapping of a system, but it isn't
standard compliant, in any case.


>
> To get the correct result
>
> : foo [ >r ', * r> ', / ] ; FOO redefined ok

This code is also system specific.

However, "'," can be implemented via "find" or via "find-name", in such
a way that the "foo" by dxforth will be standard compliant:

: foo [ ', >r ', * ', r> ', / ] ;



--
Ruvim

dxforth

unread,
Jun 25, 2021, 9:18:32 PM6/25/21
to
On 25/06/2021 23:21, Ruvim wrote:
> On 2021-06-25 15:55, dxforth wrote:
>> On 25/06/2021 21:25, Ruvim wrote:
>>> ...
>>> What is wrong to incrementally build a high-level forth definition in
>>> interpretation state?
>>
>> : ',  ' ] compile, postpone [ ;
>>
>> : foo  [ ', >r  ', *  ', r>  ', / ] ;
>>
>> vs.
>>
>> : foo  >r * r> / ;
>
> As I can see, nothing wrong. It just works. Yes, it has more size. But
> "compilation state" was introduced to make code shorter, I think. So
> compilation state doesn't abolish incremental compilation in
> interpretation state in principle.

Turning off compiling bypasses the compile, in the forth interpreter
requiring one to do it manually. It's a strange principle that breaks
what the interpreter was designed to do.

dxforth

unread,
Jun 25, 2021, 10:41:25 PM6/25/21
to
On 26/06/2021 06:33, Ruvim wrote:
>>> On 2021-06-25 15:55, dxforth wrote:
>>
>> : ', ' ] compile, postpone [ ; ok
>> : foo [ ', >r ', * ', r> ', / ] ; FOO redefined ok
>> : foo1 >r * r> / ; FOO1 redefined ok
> ...
> It's obvious, this "foo" is not standard. A standard program cannot tick
> ">r". It's a system specific definition, namely it's compliant with only
> the systems where ">r" and "r>" are implemented as ordinary words. lxf
> is not such a system.

Good call. Even I didn't spot that believing what I wrote was 'standard'.
And it worked on several systems I tried. If anything it demonstrates
the pitfalls of doing stuff in interpret mode.

Ruvim

unread,
Jun 27, 2021, 4:31:11 AM6/27/21
to
It demonstrates the pitfalls of non standard code.

Your "'," word can be implemented via a full-fledged "find". Taking into
account that some dual-xt systems don't provide full-fledged "find", we
can try to use "find-name" and "name>compile" instead.

A portable definition for "'," is following.


[undefined] 2nip [if] : 2nip ( d2 d1 -- d1 ) 2swap 2drop ; [then]

: ?nf ( x|0 -- ) if exit then -13 throw ;
: ?ni ( x|0 -- ) if exit then -14 throw ;


[defined] find-name [defined] name>compile and [if]
: evaluate-word ( i*x sd-name -- j*x )
find-name dup ?nf
state @ if name>compile else name>interpret dup ?ni then execute
;
[else]
: find-sem ( sd-name -- xt flag-special true | sd-name false )
2dup dup pad c! pad 1+ swap move pad ( sd -- sd c-addr )
find dup if 2nip 1 = true exit then nip
;
: evaluate-word ( i*x sd-name -- j*x )
find-sem ?nf state @ 0= or if execute exit then compile,
;
[then]


: ', ( i*x "ccc" -- j*x ) ] parse-name evaluate-word postpone [ ;


\ test

: foo [ ', >r ', * ', r> ', / ] ;
: foo1 >r * r> / ;

t{ 3 10 6 foo -> 3 10 6 foo1 }t




--
Ruvim

P Falth

unread,
Jun 27, 2021, 6:15:34 AM6/27/21
to
I did
: ', parse-name find-name name>compile execute ;

Missing error checking and not setting the execution under compile state

But even better with recognizers ( my own version of them)

: ', parse-name recognize cell+ @ execute ;

This also support numbers and locals!

I can now write

code foo ', if ', ." true" ', else ', ." false" ', then ', ;

instead of

: foo if ." true" else ." false" then ;

Honestly I still think this is better!

BR
Peter

dxforth

unread,
Jun 27, 2021, 7:36:40 AM6/27/21
to
On 27/06/2021 18:31, Ruvim wrote:
> On 2021-06-26 05:41, dxforth wrote:
>> On 26/06/2021 06:33, Ruvim wrote:
>>>>> On 2021-06-25 15:55, dxforth wrote:
>>>>
>>>> : ',  ' ] compile, postpone [ ;  ok
>>>> : foo  [ ', >r  ', *  ', r>  ', / ] ; FOO redefined  ok
>>>> : foo1  >r * r> / ; FOO1 redefined  ok
>>> ... It's obvious, this "foo" is not standard. A standard program
>>> cannot tick
>>> ">r". It's a system specific definition, namely it's compliant with only
>>> the systems where ">r" and "r>" are implemented as ordinary words. lxf
>>> is not such a system.
>>
>> Good call.  Even I didn't spot that believing what I wrote was 'standard'.
>> And it worked on several systems I tried.  If anything it demonstrates
>> the pitfalls of doing stuff in interpret mode.
>
> It demonstrates the pitfalls of non standard code.

It demonstrates the pitfalls of writing standard code beyond the trivial.

Ruvim

unread,
Jun 27, 2021, 8:12:17 AM6/27/21
to
On 2021-06-27 13:15, P Falth wrote:
> On Sunday, 27 June 2021 at 10:31:11 UTC+2, Ruvim wrote:
>> On 2021-06-26 05:41, dxforth wrote:
[...]
What xt "name>compile" returns for immediate words?

If it's just the xt of "execute", then this "'," will work incorrectly
for dual-semantics immediate words. It can work, if the xt is for
something like "execute-compiling".



> But even better with recognizers ( my own version of them)
>
> : ', parse-name recognize cell+ @ execute ;
>
> This also support numbers and locals!
>
> I can now write
>
> code foo ', if ', ." true" ', else ', ." false" ', then ', ;

With recognizers, it's also possible to have a recognizer for "ccc," or
",ccc" so this line can look as:

code foo ,if ,." true" ,else ,." false" ,then ,;


> instead of
>
> : foo if ." true" else ." false" then ;
>
> Honestly I still think this is better!

Nobody suggests to use the former instead of the latter in all the
cases. But it doesn't mean that the former should be outlawed.


--
Ruvim

P Falth

unread,
Jun 27, 2021, 11:11:29 AM6/27/21
to
It is not the xt of execute. But it will have the problem anyway.
That is for a state smart immediate word the branch for
state = 0 will be taken.

But is this really a problem? If you compile while interpreting
(state=0) is that not what you expect to happen?
Otherwise you would have compiled while compiling!

> > But even better with recognizers ( my own version of them)
> >
> > : ', parse-name recognize cell+ @ execute ;
> >
> > This also support numbers and locals!
> >
> > I can now write
> >
> > code foo ', if ', ." true" ', else ', ." false" ', then ', ;
> With recognizers, it's also possible to have a recognizer for "ccc," or
> ",ccc" so this line can look as:
>
> code foo ,if ,." true" ,else ,." false" ,then ,;
> > instead of
> >
> > : foo if ." true" else ." false" then ;
> >
> > Honestly I still think this is better!
> Nobody suggests to use the former instead of the latter in all the
> cases. But it doesn't mean that the former should be outlawed.

But if you want this to work in a consistent way you need to specify
execution semantics for all words without it. Good luck with that!

Maybe also for the cases of interpretation inside and outside of a
started definition.

Peter

> --
> Ruvim

Ruvim

unread,
Jun 27, 2021, 12:52:09 PM6/27/21
to
It's a problem. Since in my implementation "'," performs the compilation
semantics for any actual argument. In your implementation it performs
the interpretation semantics for some actual arguments.


> If you compile while interpreting
> (state=0) is that not what you expect to happen?

BTW, what I expect is obvious from my implementation =)


The implementation of dxforth for the "'," word was just a PoC (as I can
see), and it's just a parsing alternative to "compile," that works in
interpretation state.

But in the example it was used as if it performs the compilation
semantics for any actual argument. Therefore I showed a correct
implementation for that.



> Otherwise you would have compiled while compiling!

So your point is that for some words you may use "'," to perform their
compilation semantics in interpretation state, but for other words you
may to do it only in compilation state.

This point looks inconsistently to me.





>>> But even better with recognizers ( my own version of them)
>>>
>>> : ', parse-name recognize cell+ @ execute ;
>>>
>>> This also support numbers and locals!
>>>
>>> I can now write
>>>
>>> code foo ', if ', ." true" ', else ', ." false" ', then ', ;
>> With recognizers, it's also possible to have a recognizer for "ccc," or
>> ",ccc" so this line can look as:
>>
>> code foo ,if ,." true" ,else ,." false" ,then ,;
>>> instead of
>>>
>>> : foo if ." true" else ." false" then ;
>>>
>>> Honestly I still think this is better!
>> Nobody suggests to use the former instead of the latter in all the
>> cases. But it doesn't mean that the former should be outlawed.
>
> But if you want this to work in a consistent way you need to specify
> execution semantics for all words without it. Good luck with that!

Compilation (code generation) in interpretation state can be already
implemented in such a way that it works consistently.

If you mean interpretive control flow constructs — it's a totally
different problem.


> Maybe also for the cases of interpretation inside and outside of a
> started definition.



--
Ruvim

Ruvim

unread,
Jul 7, 2021, 12:57:17 PM7/7/21
to
On 2021-06-21 14:42, Krishna Myneni wrote:
> On 6/19/21 3:03 PM, Ruvim wrote:
> ...
>>
>> Let "foo" is a word that doesn't perform any parsing, doesn't access
>> the parse area, and doesn't enter into compilation or interpretation
>> state (i.e., any such behavior is not a part of any semantics for "foo").
>>
>> Let the word "compile-foo" is defined as:
>>    : compile-foo postpone foo ;
>> and it has the same scope as the word "foo".
>>
>>
>>
>> Proposition 1.
>>    The phrase:
>>      [ compile-foo ]
>>    is equivalent to the phrase:
>>        foo
>>    in any such context when the phrase is encountered by the Forth
>>    text interpreter in compilation state.
>>
>>
>
> What is your expectation for use of the phrase "[ COMPILE-FOO ]" inside
> of a definition, when COMPILE-FOO is tagged as an immediate word?
>
> : compile-foo postpone foo ; immediate
>
> In this case the compilation semantics of COMPILE-FOO should be the same
> as its runtime semantics.


In the phrase "[ compile-foo ]" in compilation state, the interpretation
semantics for "compile-foo" are performed, since "[" enters
interpretation state. So in this context it doesn't matter whether
"compile-foo" is immediate or not, and what its compilation semantics.



Regarding the compilation semantics for an immediate word in general.

I assume, by "runtime semantics" you meant "execution semantics".

In some cases, the execution semantics (ES) of an immediate word can be
nonequivalent to its compilation semantics (CS). If you make them
equivalent, you break the equivalence in P1.

NB: Anton Ertl claimed that ES and CS should be equivalent for any
immediate word (and then P1 is false, what I consider as inconsistency).
Don't sure whether he still insist on that.



--
Ruvim

Krishna Myneni

unread,
Jul 10, 2021, 7:42:33 AM7/10/21
to
Yes.

> In some cases, the execution semantics (ES) of an immediate word can be
> nonequivalent to its compilation semantics (CS). If you make them
> equivalent, you break the equivalence in P1.
>
> NB: Anton Ertl claimed that ES and CS should be equivalent for any
> immediate word (and then P1 is false, what I consider as inconsistency).
> Don't sure whether he still insist on that.
>

If an IMMEDIATE word does not have ES = CS, how would dual-xt systems
determine the immediacy of a word? Would that not make dual-xt systems
inconsistent with the standard?

Krishna

Ruvim

unread,
Jul 12, 2021, 8:46:34 AM7/12/21
to
First of all, a system is not obligated to determine whether a word is
immediate (in the standard notion) or not. It's enough to determine
whether a word is ordinary or not [1].

Secondly, I don't see any technical problem with that. Various solutions
can be employed depending on a particular implementation. For example, a
separate flag can be introduced for that.



As I can guess, the question is about a system where two execution
tokens are associated with each name token.

One execution token (xt-int) is *used* to perform the IS for the word,
and another execution token (xt-comp) is *used* to perform the CS for
the word. If a word has default CS, then xt-comp is 0.

For an immediate word xt-int and xt-comp are the same and they both are
equal to the xt-exec that identifies the ES for the word. And it's for
any immediate words. So, to determine whether a word is immediate, the
system compares xt-int and xt-comp.

It's wrong to assume that if CS <> ES, then xt-comp should be unequal to
the xt-exec (they still can be the same in some cases). Since xt-comp
(in general case) doesn't identify CS. It's only *used* to perform CS.


Any execution token (xt) always identifies some ES, and these ES are
performed by applying "EXECUTE" to this xt. It's impossible that an
execution token doesn't identify some ES.


In the same time, some ES can be equivalent (possibly in some
conditions) to the CS for some word, or to the IS for some word [2]. In
such case, by performing these ES (possibly in those conditions) you
perform the corresponding CS or IS.


If the CS are (unconditionally) equivalent to the ES for some word
"foo", then the phrase:
[ xt-comp(foo) EXECUTE ]
is equivalent to the phrase:
[ ' foo EXECUTE ]
that is equivalent to the phrase:
foo
in compilation state, where "xt-comp(foo)" returns xt-comp for the word
"foo" in the considered system implementation.

Hence, if for some word "foo" this phrases are not equivalent, then
CS(foo) are not equivalent to the ES(foo). Obviously, it's a possible
case — the case of an immediate STATE-dependent word. And in the
considered system implementation xt-int = xt-comp in this case.




> Would that not make dual-xt systems
> inconsistent with the standard?

Not in this part. But it depends.

At the moment, if "NAME>COMPILE" returns xt-int(foo) and xt-int(EXECUTE)
for an immediate STATE-dependent word "foo", then it's incorrect, I think.

But the specification for "NAME>COMPILE" can be clarified to relax
implementations. Since at the moment it controverts it's own rationale,
when it says: "xt2 is the xt of EXECUTE (for immediate words)" [3].




[1] See also my proposal for FIND clarification
https://forth-standard.org/proposals/clarify-find-more-classic-approach?hideDiff#reply-682

[2] See also my reasoning concerning relations between xt, ES, CS, IS.
https://forth-standard.org/proposals/reword-the-term-execution-token-?hideDiff#reply-570

[3] https://forth-standard.org/standard/tools/NAMEtoCOMPILE


--
Ruvim

P Falth

unread,
Jul 12, 2021, 9:20:01 AM7/12/21
to
Not necessarily. In my system a word with default CS has xt-comp=COMPILE,

> For an immediate word xt-int and xt-comp are the same and they both are
> equal to the xt-exec that identifies the ES for the word. And it's for
> any immediate words. So, to determine whether a word is immediate, the
> system compares xt-int and xt-comp.

Yes this works in my system

> It's wrong to assume that if CS <> ES, then xt-comp should be unequal to
> the xt-exec (they still can be the same in some cases). Since xt-comp
> (in general case) doesn't identify CS. It's only *used* to perform CS.
>
>
> Any execution token (xt) always identifies some ES, and these ES are
> performed by applying "EXECUTE" to this xt. It's impossible that an
> execution token doesn't identify some ES.
>
>
> In the same time, some ES can be equivalent (possibly in some
> conditions) to the CS for some word, or to the IS for some word [2]. In
> such case, by performing these ES (possibly in those conditions) you
> perform the corresponding CS or IS.

Yes this is true for IF, ELSE etc in my system

>
> If the CS are (unconditionally) equivalent to the ES for some word
> "foo", then the phrase:
> [ xt-comp(foo) EXECUTE ]
> is equivalent to the phrase:
> [ ' foo EXECUTE ]
> that is equivalent to the phrase:
> foo
> in compilation state, where "xt-comp(foo)" returns xt-comp for the word
> "foo" in the considered system implementation.
>
> Hence, if for some word "foo" this phrases are not equivalent, then
> CS(foo) are not equivalent to the ES(foo). Obviously, it's a possible
> case — the case of an immediate STATE-dependent word. And in the
> considered system implementation xt-int = xt-comp in this case.
> > Would that not make dual-xt systems
> > inconsistent with the standard?
> Not in this part. But it depends.
>
> At the moment, if "NAME>COMPILE" returns xt-int(foo) and xt-int(EXECUTE)
> for an immediate STATE-dependent word "foo", then it's incorrect, I think.
>
> But the specification for "NAME>COMPILE" can be clarified to relax
> implementations. Since at the moment it controverts it's own rationale,
> when it says: "xt2 is the xt of EXECUTE (for immediate words)" [3].

As I read the standard there are no restrictions on what NAME>COMPILE
can return except that when applying EXECUTE to the returned x xt the CS
is performed.

In the rational, that you refer to, it is written:
"In a traditional xt+immediate-flag system, the x xt returned by NAME>COMPILE is typically xt1 xt2,"
the typically tells us that there can also be implementations where this is not true.
And it only applies to traditional xt+immediate flag systems, not dual-xt as discussed here.

BR
Peter

Ruvim

unread,
Jul 12, 2021, 12:16:34 PM7/12/21
to
On 2021-07-12 16:19, P Falth wrote:
> On Monday, 12 July 2021 at 14:46:34 UTC+2, Ruvim wrote:
>> On 2021-07-10 14:42, Krishna Myneni wrote:
>>> On 7/7/21 11:57 AM, Ruvim wrote:
>>>> On 2021-06-21 14:42, Krishna Myneni wrote:
>>>>> On 6/19/21 3:03 PM, Ruvim wrote:
>>>>> ...
>>>>>>
>>>>>> Let "foo" is a word that doesn't perform any parsing, doesn't access
>>>>>> the parse area, and doesn't enter into compilation or interpretation
>>>>>> state (i.e., any such behavior is not a part of any semantics for
>>>>>> "foo").
(1)
Yes, it is possible too. Hence you need to compare xt-comp with xt of
"COMPILE,", instead of zero.

Anyway, this variation doesn't affect my reasoning.
The problem I refer to is the same for any system implementation that
meets the mentioned conditions. Yes, "NAME>COMPILE" may return any xt at
the top. But it violates the specification *if* it returns xt of the
word and xt of "EXECUTE" for the nt of an immediate STATE-dependent
word. In the same time the rationale implies that this case meets the
specification (i.e., it's correct).


The specification says:
"Executing xt consumes x and performs the compilation semantics of
the word represented by nt".

It says nothing about any additional conditions. It means that in
compilation state the phrase:

[ "foo" find-name name>compile execute ]

should perform the CS for *any* available word "foo" that meets (1)
above. Hence, this phrase should be equivalent to the phrase:

foo

in compilation state (2).

According to the rationale, "name>compile" may return xt of the word and
xt of "EXECUTE" for an immediate word. But this equivalence is not held
*if* this immediate word is STATE-dependent.

For example, if "foo" is defined as

: foo state @ 0<> . ; immediate

and "name>compile" returns ( xt(foo) xt(execute) ) -- according to the
rationale, then the phrases above produce the different results [4].


So we have two options for "name>compile" glossary entry:

a) update the specification to relax implementations and tight
programs (specify that the returned xt should be performed in
compilation state);

b) update the rationale, remove the incorrect case, describe
implementation options for traditional xt+immediate-flag system.





[4] The Anton's position was that the compilation semantics for a word
may include such behavior that cannot be observed in compilation state.
And therefore the consequence (2) is incorrect.

Actually, the standard notion of "execution semantic" doesn't allow such
behavior for compilation semantics:

compilation semantics: The behavior of a Forth definition when its
name is encountered by the text interpreter in compilation state.

So it looks like Anton used another notion of CS. Also, this position
makes impossible some useful equivalences with "postpone" (like P1
above), since the specification for "postpone" relies on "compilation
semantics" notion.

I don't sure whether Anton still sticks on this position.


--
Ruvim
0 new messages