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

ANS tests; failing POSTPONETEST.FTH POSTPONE POSTPONE

720 views
Skip to first unread message

Alex McDonald

unread,
Jul 11, 2019, 4:07:56 PM7/11/19
to
This one is probably for Anton, since the code is his.

I'm was having problems running POSTPONETEST.FTH, in particular

TESTING POSTPONE POSTPONE
: POSTPONE-POSTPONE
POSTPONE POSTPONE ;

T{ : PPP1 123 ; -> }T
T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
T{ : PPP5 PPP4 ; -> }T
T{ PPP5 -> 123 }T
T{ : PPP6 345 ; IMMEDIATE -> }T
T{ : PPP7 [ POSTPONE-POSTPONE PPP6 ] ; -> }T
T{ PPP7 -> 345 }T

The compiler is miscompiling the line

T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T

and is compiling the ] instead of executing it; i.e. the STATE is wrong.
Here's my code, where STATE selects any of the interpretation (0),
compilation (-1) or postpone (-2) actions for a word.

: ]] -2 state ! ; immediate \ start of postpone state

: postpone ( -<name>- ) \ postpone next word
postpone ]]
parse-name default-recognize execute
] ; immediate \ reset state to compilation

POSTPONE-POSTPONE is being run in interpretation state. The fix is to:

: postpone ( -<name>- ) \ postpone next word
state @ \ save state
postpone ]]
parse-name default-recognize execute
state ! ; immediate \ restore state

My question; the standard specifies that there's no interpretation state
for POSTPONE. I was switching back into compilation state after the
postpone state, hence the miscompile. Am I misinterpreting the state
when POSTPONE-POSTPONE is being interpreted in PPP4?

--
Alex

A. K.

unread,
Jul 11, 2019, 8:20:05 PM7/11/19
to
just a side note:

does your compiler pass the Forth-2012 test suite?
https://github.com/gerryjackson/forth2012-test-suite/tree/master

postponetest.fth is not part of it and IMO is somewhat overinterpreting
the requirements

Alex McDonald

unread,
Jul 11, 2019, 8:38:50 PM7/11/19
to
Yes, it does pass Gerry's tests. Anton's POSTPONE tests are of interest
to me as I've spent quite some time ensuring my Forth meets the
standard, particularly in this area.

\ These tests are especially useful for showing that state-smart
\ implementations of words with special compilation semantics,
\ combined with a straight-forward implementation of POSTPONE (and
\ [COMPILE]) do not conform to the ANS Forth standard.

However, my system fails on Stephen Pelc's benchmarks in the Dhrystone
for reasons I haven't yet worked out; there's a wild pointer somewhere.

--
Alex

Ruvim

unread,
Jul 12, 2019, 12:32:03 AM7/12/19
to
1. POSTPONE shall not change STATE (it may change it internally, but
after its return STATE shall be the same as before call).
Reason: "Only the following standard words alter the value in STATE: :
(colon), ; (semicolon), ABORT, QUIT, :NONAME, [ (left-bracket), ]
(right-bracket)" — citation from the specification of STATE.


2. "Interpretation semantics for this word are undefined" actually means
that it is an ambiguous condition if "POSTPONE" is encountered by the
text interpreter in the interpretation state (see 4.1.2 Ambiguous
conditions), and nothing more.

Any standard Forth system may define the custom interpretation semantics
for POSTPONE (as well as for any other word without specified
interpretation semantics). And a program may even rely on that, but such
program probably is not a standard program.

Any standard program may execute POSTPONE indirectly in the
interpretation state. But actually it can execute its compilation
semantics only. Therefore an ambiguous condition should exist if there
is no current definition ("the definition whose compilation has been
started but not yet ended") in this case.


So, why don't to just redefine POSTPONE in the following way?
: POSTPONE POSTPONE POSTPONE ; IMMEDIATE

A standard program may do it. And after that this word may be correctly
encountered by the text interpreter in the interpretation state.

But the custom interpretation semantics of this word (if any) will be lost.


--
Ruvim

hughag...@gmail.com

unread,
Jul 12, 2019, 12:49:12 AM7/12/19
to
This is one of my disambiguifiers:
----------------------------------------------------------------------------
: postpone state @ 0= if cr ." WARNING: *** no interpretation semantics for: POSTPONE ***" cr then postpone postpone ; immediate
----------------------------------------------------------------------------

Good job, Ruvim!
You have just invented disambiguifiers!
Now Stephen Pelc will hate you too!

I moved the conversation over to this thread:
https://groups.google.com/forum/#!topic/comp.lang.forth/T-yYkpVwYew

Stephen Pelc is a liar.
He hates it when people point out that he is lying!

Anton Ertl

unread,
Jul 12, 2019, 1:42:07 AM7/12/19
to
Alex McDonald <al...@rivadpm.com> writes:
>This one is probably for Anton, since the code is his.
>
>I'm was having problems running POSTPONETEST.FTH, in particular
>
>TESTING POSTPONE POSTPONE
>: POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
>T{ : PPP1 123 ; -> }T
>T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
>T{ : PPP5 PPP4 ; -> }T
>T{ PPP5 -> 123 }T
>T{ : PPP6 345 ; IMMEDIATE -> }T
>T{ : PPP7 [ POSTPONE-POSTPONE PPP6 ] ; -> }T
>T{ PPP7 -> 345 }T
>
>The compiler is miscompiling the line
>
>T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
>
>and is compiling the ] instead of executing it; i.e. the STATE is wrong.
>Here's my code, where STATE selects any of the interpretation (0),
>compilation (-1) or postpone (-2) actions for a word.
>
>: ]] -2 state ! ; immediate \ start of postpone state
>
>: postpone ( -<name>- ) \ postpone next word
> postpone ]]
> parse-name default-recognize execute
> ] ; immediate \ reset state to compilation

There is no guarantee that POSTPONE's compilation semantics are only
performed in compile state, so resetting state to compilation is
incorrect, as shown by this test.

>POSTPONE-POSTPONE is being run in interpretation state. The fix is to:
>
>: postpone ( -<name>- ) \ postpone next word
> state @ \ save state
> postpone ]]
> parse-name default-recognize execute
> state ! ; immediate \ restore state
>
>My question; the standard specifies that there's no interpretation state
>for POSTPONE.

No it specifies that POSTPONE has no interpretation semantics. No
interpretation semantics of POSTPONE are used in this test:

: POSTPONE-POSTPONE
POSTPONE POSTPONE ;

The first POSTPONE is text-interpreted in compile state, so it's
compilation semantics are used. The second POSTPONE is processed by
POSTPONE, so its compilation semantics are compiled into
POSTPONE-POSTPONE.

T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T

Here the compilation semantics of POSTPONE (compiled into
POSTPONE-POSTPONE) is performed. So: no interpretation semantics.

BTW, it's unclear to me why you do anything with STATE at all in
POSTPONE. You know which parts of the rectype POSTPONE wants to use,
so use them directly instead of setting STATE and calling code that
decides based on STATE.

E.g., Gforth's POSTPONE is (slightly simplified):

: >postpone ( ... rectype -- )
dup >r rectype>post execute r> rectype>comp compile, ;

: postpone ( "name" -- ) \ core
\g Compiles the compilation semantics of @i{name}.
parse-name forth-recognizer recognize >postpone ; immediate

- 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 2019: http://euro.theforth.net/

Ruvim

unread,
Jul 12, 2019, 2:27:10 AM7/12/19
to
On 2019-07-12 07:31, Ruvim wrote:
> On 2019-07-11 23:07, Alex McDonald wrote:
[...]
One possible rationale to have defined interpretation semantics for all
words in a Forth system is copy-pasteability — that almost any fragment
of code from inside a definition body can be tested outside of it. And
the Standard explicitly allows this.

An excerpt from A.3.4.3.2 Interpretation semantics [1]:
Nothing in this Standard precludes an implementation from providing
interpretation semantics for these words, such as interactive
control-flow words. However, a Standard Program may not use them in
interpretation state.

In that case POSTPONE should just parse and drop the next lexeme and
does nothing more in the interpretation state.


So, when you redefines such the words you can loose an easy interactive
debugging capability (if any).



[1] https://forth-standard.org/standard/rationale#paragraph.A.3.4.3.2

--
Ruvim

Alex McDonald

unread,
Jul 12, 2019, 6:02:05 AM7/12/19
to
On 12-Jul-19 05:31, Ruvim wrote:

>
>
> So, why don't to just redefine POSTPONE in the following way?
>   : POSTPONE POSTPONE POSTPONE ; IMMEDIATE

Unfortunately there has to be a point where POSTPONE gets written,
otherwise it's turtles all the way down ;)


--
Alex

Alex McDonald

unread,
Jul 12, 2019, 6:19:06 AM7/12/19
to
That's what I meant. It was late & I was tired...

> No interpretation semantics of POSTPONE are used in this test:
>
> : POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
> The first POSTPONE is text-interpreted in compile state, so it's
> compilation semantics are used. The second POSTPONE is processed by
> POSTPONE, so its compilation semantics are compiled into
> POSTPONE-POSTPONE.
>
> T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
>
> Here the compilation semantics of POSTPONE (compiled into
> POSTPONE-POSTPONE) is performed. So: no interpretation semantics.

I see that now.

>
> BTW, it's unclear to me why you do anything with STATE at all in
> POSTPONE. You know which parts of the rectype POSTPONE wants to use,
> so use them directly instead of setting STATE and calling code that
> decides based on STATE.
>
> E.g., Gforth's POSTPONE is (slightly simplified):
>
> : >postpone ( ... rectype -- )
> dup >r rectype>post execute r> rectype>comp compile, ;
>
> : postpone ( "name" -- ) \ core
> \g Compiles the compilation semantics of @i{name}.
> parse-name forth-recognizer recognize >postpone ; immediate

I'm using the pre-v4 version of the recognizer (I prefer the explicit &
potentially varying POSTPONE action to support meta-compilation).

:noname name>interpret execute ;
:noname name>compile execute ;
:noname name>compile swap
dup ['] [[ = if
2drop ] \ stop postponing ***
else
plit compile, \ : plit postpone literal ;
then ;
dt-token value dt:name ( nt -- )

: default-recognize ( addr u -- i*x xt )
forth-recognizer recognize state @ cells- @ ;

It's a simple factor.

*** I've also just spotted the (possibly incorrect) assumption that
after ]] [[ in support of a postponed state, that the system returns to
compilation state. I'll check.


--
Alex

Alex McDonald

unread,
Jul 12, 2019, 6:41:18 AM7/12/19
to
On 12-Jul-19 11:19, Alex McDonald wrote:
> On 12-Jul-19 06:24, Anton Ertl wrote:

>
> I'm using the pre-v4 version of the recognizer (I prefer the explicit &
> potentially varying POSTPONE action to support meta-compilation).

For clarity; by pre-V4 I mean that I am using a variation on Mattias
Trute's proposal B (there were 4, lettered A B C and D; the POSTPONE
action changed between B and C, something that caused me considerable
confusion because I thought C was a refinement of B, not a rework).


--
Alex

Stephen Pelc

unread,
Jul 12, 2019, 10:58:54 AM7/12/19
to
On Fri, 12 Jul 2019 11:41:18 +0100, Alex McDonald <al...@rivadpm.com>
wrote:
I agree.

I have also now converted the CIAO and ClassVFX OOP packages to
use recognisers for the parsing to handle stuff like
(Class).foo
a.b.c.d

In both cases, simplicity is enhanced by having a custom error
handler for the postpone action. The only literal actions needed
for OOP are for field sizes and the addresses of global objects.
An interesting part of the CIAO conversion was that we needed to
have recognisers both before and after the normal word search.
Since, in our requirement domain, we need to be able to use
multiple OOP packages, we need to be able to modify the recognisers
at run time and to be able to add parsers at either end of the
recognisers.

There's still a lot to discuss in standardising recognisers.

I would be interested to hear of other OOP recognisers.

Stephen

--
Stephen Pelc, ste...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, +44 (0)78 0390 3612
web: http://www.mpeforth.com - free VFX Forth downloads

Alex McDonald

unread,
Jul 12, 2019, 11:05:52 AM7/12/19
to
On 12-Jul-19 05:49, hughag...@gmail.com wrote:

> This is one of my disambiguifiers:
> ----------------------------------------------------------------------------
> : postpone state @ 0= if cr ." WARNING: *** no interpretation semantics for: POSTPONE ***" cr then postpone postpone ; immediate
> ----------------------------------------------------------------------------
>
> Good job, Ruvim!
> You have just invented disambiguifiers!
> Now Stephen Pelc will hate you too!

Your version doesn't work and isn't ANS complaint.

The test below is a extracted version from Anton Ertl's postpone tests
at https://www.complang.tuwien.ac.at/forth/postponetest.fs

\ These tests are especially useful for showing that state-smart
\ implementations of words with special compilation semantics,
\ combined with a straight-forward implementation of POSTPONE (and
\ [COMPILE]) do not conform to the ANS Forth standard.



STC 32bit: 0.06.10 Build: 713
: postpone state @ 0= if
cr ." WARNING: *** no interpretation semantics for: POSTPONE ***" cr
then postpone postpone ; immediate
^^^^^^^^
Warning -4100 in (console): postpone is redefined
ok
: postpone-postpone postpone postpone ;
ok
: ppp1 123 ;
ok
: ppp4 [ postpone-postpone ppp1 ] ; immediate

WARNING: *** no interpretation semantics for: POSTPONE ***
ok


--
Alex

Anton Ertl

unread,
Jul 12, 2019, 12:43:34 PM7/12/19
to
Alex McDonald <al...@rivadpm.com> writes:
>On 12-Jul-19 06:24, Anton Ertl wrote:
>> BTW, it's unclear to me why you do anything with STATE at all in
>> POSTPONE. You know which parts of the rectype POSTPONE wants to use,
>> so use them directly instead of setting STATE and calling code that
>> decides based on STATE.
>>
>> E.g., Gforth's POSTPONE is (slightly simplified):
>>
>> : >postpone ( ... rectype -- )
>> dup >r rectype>post execute r> rectype>comp compile, ;
>>
>> : postpone ( "name" -- ) \ core
>> \g Compiles the compilation semantics of @i{name}.
>> parse-name forth-recognizer recognize >postpone ; immediate
>
>I'm using the pre-v4 version of the recognizer (I prefer the explicit &
>potentially varying POSTPONE action to support meta-compilation).

In that case, just define >POSTPONE accordingly. Maybe like this:

: >postpone ( ... rectype -- )
rectype>post execute ;

Alex McDonald

unread,
Jul 12, 2019, 6:54:59 PM7/12/19
to
On 12-Jul-19 17:35, Anton Ertl wrote:
> Alex McDonald <al...@rivadpm.com> writes:
>> On 12-Jul-19 06:24, Anton Ertl wrote:
>>> BTW, it's unclear to me why you do anything with STATE at all in
>>> POSTPONE. You know which parts of the rectype POSTPONE wants to use,
>>> so use them directly instead of setting STATE and calling code that
>>> decides based on STATE.
>>>
>>> E.g., Gforth's POSTPONE is (slightly simplified):
>>>
>>> : >postpone ( ... rectype -- )
>>> dup >r rectype>post execute r> rectype>comp compile, ;
>>>
>>> : postpone ( "name" -- ) \ core
>>> \g Compiles the compilation semantics of @i{name}.
>>> parse-name forth-recognizer recognize >postpone ; immediate
>>
>> I'm using the pre-v4 version of the recognizer (I prefer the explicit &
>> potentially varying POSTPONE action to support meta-compilation).
>
> In that case, just define >POSTPONE accordingly. Maybe like this:
>
> : >postpone ( ... rectype -- )
> rectype>post execute ;
>
> - anton
>

I could, but using STATE seemed natural. I'd also point out that I
posted lightly edited code; I actually use a variable _STATE_ with the
values 0, CELL and 2 CELLS for interpret, compilation and postpone
semantics; and a read-only word : STATE _STATE_ 0<> ; for those wanting
to throw state-smart words at the compiler.

I suppose I could have >POSTPONE but it doesn't seem that important,
since everything just works by setting _STATE_ correctly and doing a
_STATE @ + @ . Particularly ]] where the postpone state is permanent
until the super-immediate [[ .

--
Alex

hughag...@gmail.com

unread,
Jul 13, 2019, 7:27:32 AM7/13/19
to
My disambiguifiers work just fine.
I never said that they allow words without
interpretation semantics to work in interpretation mode.
I originally aborted when this stunt was tried, but
Anton Ertl pointed out that these words sometimes work
inside of [ ] brackets, so I changed the disambiguifiers
to just give a warning rather than an abort.
If the user ignores the warning, and his program fails,
that is his fault and not mine. This is not ANS-Forth.

This goofy code is not mine, but it is Anton Ertl's:
----------------------------------------------------
: postpone-postpone postpone postpone ;
ok
: ppp1 123 ;
ok
: ppp4 [ postpone-postpone ppp1 ] ; immediate
----------------------------------------------------
Why should I be blamed for Anton Ertl's incompetence?

My disambiguifiers work fine for supporting my
POST: and MACRO: words. The disambiguifiers fix FIND
so that it works correctly (the same way that it worked
in Forth-83). My POST: (used by MACRO: internally) uses
FIND to obtain the xt of every word in the definition,
so I am able to do early-binding. This works fine for
immediate and non-immediate words in the definition.
I do have to special-case those immediate words that
extract data from the input stream. These include
S" S| [CHAR] etc.. There are not many of them.

Anton Ertl doesn't have anything comparable to my
POST: and MACRO: words. He is struggling to avoid
using the disambiguifiers for political reasons
and he is failing badly for technical reasons.

I have already provided a description of the disambiguifiers:
https://groups.google.com/forum/#!topic/comp.lang.forth/T-yYkpVwYew

Alex McDonald

unread,
Jul 13, 2019, 1:16:35 PM7/13/19
to
That's not what is being tested by the code.

> I originally aborted when this stunt was tried, but
> Anton Ertl pointed out that these words sometimes work

This should always work; it is perfectly valid ANS Forth.

> inside of [ ] brackets, so I changed the disambiguifiers
> to just give a warning rather than an abort.

The warning (or abort) isn't appropriate in this case, because as Anton
explained in his reply to me
https://groups.google.com/d/msg/comp.lang.forth/vrq2f2XXy1Q/WuSF5FxrDQAJ

====

> No interpretation semantics of POSTPONE are used in this test:
>
> : POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
> The first POSTPONE is text-interpreted in compile state, so it's
> compilation semantics are used. The second POSTPONE is processed by
> POSTPONE, so its compilation semantics are compiled into
> POSTPONE-POSTPONE.
>
> T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
>
> Here the compilation semantics of POSTPONE (compiled into
> POSTPONE-POSTPONE) is performed. So: no interpretation semantics.

====


> If the user ignores the warning, and his program fails,
> that is his fault and not mine. This is not ANS-Forth.

It is ANS Forth. Your message is inappropriate.

>
> This goofy code is not mine, but it is Anton Ertl's:
> ----------------------------------------------------
> : postpone-postpone postpone postpone ;
> ok
> : ppp1 123 ;
> ok
> : ppp4 [ postpone-postpone ppp1 ] ; immediate
> ----------------------------------------------------
> Why should I be blamed for Anton Ertl's incompetence?

What incompetence? It's a test of POSTPONE. At no point does this ANS
compliant code use the undefined interpretation semantics of POSTPONE.
Your warning message is wrong.

You might be better removing the state test.

: postpone postpone postpone ; immediate


--
Alex

hughag...@gmail.com

unread,
Jul 13, 2019, 4:04:13 PM7/13/19
to
> > No interpretation semantics of POSTPONE are used in this test:
> >
> > : POSTPONE-POSTPONE
> > POSTPONE POSTPONE ;
> >
> > The first POSTPONE is text-interpreted in compile state, so it's
> > compilation semantics are used. The second POSTPONE is processed by
> > POSTPONE, so its compilation semantics are compiled into
> > POSTPONE-POSTPONE.
> >
> > T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
> >
> > Here the compilation semantics of POSTPONE (compiled into
> > POSTPONE-POSTPONE) is performed. So: no interpretation semantics.
>
> ====
>
>
> > If the user ignores the warning, and his program fails,
> > that is his fault and not mine. This is not ANS-Forth.
>
> It is ANS Forth. Your message is inappropriate.
>
> >
> > This goofy code is not mine, but it is Anton Ertl's:
> > ----------------------------------------------------
> > : postpone-postpone postpone postpone ;
> > ok
> > : ppp1 123 ;
> > ok
> > : ppp4 [ postpone-postpone ppp1 ] ; immediate
> > ----------------------------------------------------
> > Why should I be blamed for Anton Ertl's incompetence?
>
> What incompetence? It's a test of POSTPONE. At no point does this ANS
> compliant code use the undefined interpretation semantics of POSTPONE.
> Your warning message is wrong.
>
> You might be better removing the state test.
>
> : postpone postpone postpone ; immediate
>
>
> --
> Alex

Alex McDonald is so incompetent!
Executing POSTPONE in interpretive state is illegal
in ANS-Forth. Section 4.1.2 (ambiguous conditions) includes:
"interpretating (sic) a word with undefined interpretation semantics."

On Thursday, July 11, 2019 at 10:42:07 PM UTC-7, Anton Ertl wrote:
> Alex McDonald <al...@rivadpm.com> writes:
> >My question; the standard specifies that there's no interpretation state
> >for POSTPONE.
>
> No it specifies that POSTPONE has no interpretation semantics. No
> interpretation semantics of POSTPONE are used in this test:
>
> : POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
> The first POSTPONE is text-interpreted in compile state, so it's
> compilation semantics are used. The second POSTPONE is processed by
> POSTPONE, so its compilation semantics are compiled into
> POSTPONE-POSTPONE.
>
> T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
>
> Here the compilation semantics of POSTPONE (compiled into
> POSTPONE-POSTPONE) is performed. So: no interpretation semantics.

Anton Ertl is also incompetent!
This is his code:
---------------------------------------------------------
: POSTPONE-POSTPONE
POSTPONE POSTPONE ;

: PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
---------------------------------------------------------

This has exactly the same effect as:
---------------------------------------------------------
: PPP4 [ POSTPONE PPP1 ] ; IMMEDIATE
---------------------------------------------------------

The effect is that POSTPONE PPP1 is executing inside
of [ ] brackets, which is interpretive state.
Doing this is an "ambiguous condition," also known as:
"screwing everything up."

Elizabeth Rather is also incompetent!
ANS-Forth is deeply flawed in that STATE has only 2 states:
zero --- interpretive state
non-zero --- compilation state
This is so stupid! This fails to distinguish between
interpretive state inside of [ ] brackets inside of a colon word,
and interpretive state outside of a colon word.
Most of the problematic words such as IF POSTPONE etc,
actually work okay inside of [ ] brackets inside of a colon word,
but they only need to be disallowed outside of a colon word.

In Straight Forth I have STATE@ that provides 3 states:
negative --- interpretive state inside of [ ] brackets in a colon word
zero --- compilation state in a colon word
positive --- interpretive state outside of a colon word

I also do NOT say that executing words such as IF POSTPONE etc.
when STATE@ is positive is an "ambiguous condition."
This isn't ambiguous --- this is a fatal error --- the Forth
system aborts with a helpful error message.

Elizabeth Rather is obsessed with defining fatal errors
as "ambiguous conditions." This is stupid!
Fatal errors should abort with a helpful error message.
Making them ambiguous allows various ANS-Forth compliant
Forth systems to behave differently and incompatibly.
What causes an abort in one ANS-Forth system may work
in another ANS-Forth system --- so code can't be ported.

Another stupidity of Elizabeth Rather is her definition of STATE
(section 6.1.2250):
----------------------------------------------------------------
( -- a-addr )
a-addr is the address of a cell containing the compilation-state flag.
STATE is true when in compilation state, false otherwise. ...
Note: A program shall not directly alter the contents of STATE.
----------------------------------------------------------------

Why make it a variable if it can't be altered???
The note (a program shall not directly alter the contents of STATE)
isn't being enforced in any way. This is an invitation to disaster!
I only provide STATE@ that gives the value of the STATE variable,
but I don't expose the STATE variable to the user, so the user
can't directly alter it and screw everything up.

Alex McDonald

unread,
Jul 13, 2019, 8:00:01 PM7/13/19
to
On 13-Jul-19 21:04, hughag...@gmail.com wrote:
> On Saturday, July 13, 2019 at 10:16:35 AM UTC-7, Alex McDonald wrote
> Executing POSTPONE in interpretive state is illegal
> in ANS-Forth. Section 4.1.2 (ambiguous conditions) includes:
> "interpretating (sic) a word with undefined interpretation semantics."

It's not "illegal", it's undefined.

>
> On Thursday, July 11, 2019 at 10:42:07 PM UTC-7, Anton Ertl wrote:
>> Alex McDonald <al...@rivadpm.com> writes:
>>> My question; the standard specifies that there's no interpretation state
>>> for POSTPONE.
>>
>> No it specifies that POSTPONE has no interpretation semantics. No
>> interpretation semantics of POSTPONE are used in this test:
>>
>> : POSTPONE-POSTPONE
>> POSTPONE POSTPONE ;
>>
>> The first POSTPONE is text-interpreted in compile state, so it's
>> compilation semantics are used. The second POSTPONE is processed by
>> POSTPONE, so its compilation semantics are compiled into
>> POSTPONE-POSTPONE.

Did you read this bit above? It's been in this thread from the start.

>>
>> T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
>>
>> Here the compilation semantics of POSTPONE (compiled into
>> POSTPONE-POSTPONE) is performed. So: no interpretation semantics.
>
> Anton Ertl is also incompetent!
> This is his code:
> ---------------------------------------------------------
> : POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
> : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
> ---------------------------------------------------------
>
> This has exactly the same effect as:
> ---------------------------------------------------------
> : PPP4 [ POSTPONE PPP1 ] ; IMMEDIATE
> ---------------------------------------------------------
>

There's a difference. Although POSTPONE has undefined interpretation
semantics, POSTPONE-POSTPONE has well defined interpretation semantics,
which is to execute the *compilation* semantics of POSTPONE.

Your disambiguifier has the same semantics for both interpretation and
commpilation (it uses STATE), hence its problem.

> The effect is that POSTPONE PPP1 is executing inside
> of [ ] brackets, which is interpretive state.
> Doing this is an "ambiguous condition," also known as:
> "screwing everything up."

Only if you insist on comparing the different POSTPONE-POSTPONE with
POSTPONE.


> ANS-Forth is deeply flawed in that STATE has only 2 states:
> zero --- interpretive state
> non-zero --- compilation state
> This is so stupid! This fails to distinguish between
> interpretive state inside of [ ] brackets inside of a colon word,
> and interpretive state outside of a colon word.

Why is that needed?


--
Alex

Rod Pemberton

unread,
Jul 13, 2019, 8:39:12 PM7/13/19
to
> > I never said that they allow words without
> > interpretation semantics to work in interpretation mode.
>
> That's not what is being tested by the code.

If POSTPONE POSTPONE compiles the compilation semantics of POSTPONE
into POSTPONE-POSTPONE as Anton stated, what semantics does
POSTPONE-POSTPONE have? i.e., compilation or interpretation. It should
be compilation, yes?

> > No interpretation semantics of POSTPONE are used in this test:
> >
> > : POSTPONE-POSTPONE
> > POSTPONE POSTPONE ;

"No interpretation semantics ..."
Doesn't this confirm compilation only?

> > The first POSTPONE is text-interpreted in compile state, so it's
> > compilation semantics are used. The second POSTPONE is processed
> > by POSTPONE, so its compilation semantics are compiled into
> > POSTPONE-POSTPONE.
> >
> > T{ : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE -> }T
> >
> > Here the compilation semantics of POSTPONE (compiled into
> > POSTPONE-POSTPONE) is performed. So: no interpretation
> > semantics.
>

Again, "no interpretation semantics".

> > This goofy code is not mine, but it is Anton Ertl's:
> > ----------------------------------------------------
> > : postpone-postpone postpone postpone ;
> > ok
> > : ppp1 123 ;
> > ok
> > : ppp4 [ postpone-postpone ppp1 ] ; immediate
> > ----------------------------------------------------
> > Why should I be blamed for Anton Ertl's incompetence?
>
> What incompetence? It's a test of POSTPONE. At no point does this ANS
> compliant code use the undefined interpretation semantics of
> POSTPONE. Your warning message is wrong.

Uh, okay, what did I miss? Oh, that's right. I missed the whole
entire ANS semantics thingy, but I'm trying to follow this thread
anyway ... So, let's see how badly I get it wrong:

POSTPONE-POSTPONE is executed in interpretation mode between [ ] in the
definition of the word ppp4. So, the interpretation semantics for
POSTPONE-POSTPONE - which are currently undefined - should be what is
executed. So, how does POSTPONE-POSTPONE ***NOT*** attempt to
execute the interpretation semantics which are undefined? Or, in other
words, how does POSTPONE-POSTPONE switch from interpretation semantics
between [ ] to compilation semantics between [ ] ?

> At no point does this ANS compliant code use the undefined
> interpretation semantics of POSTPONE.

I don't understand that. See above.

Could someone explain please? Thank you.


Rod Pemberton
--
Once upon a time, many decades ago in a place far away, humble people
sought their freedom, and lost. "Ideas are bulletproof."

Anton Ertl

unread,
Jul 14, 2019, 3:02:18 AM7/14/19
to
Rod Pemberton <inv...@lkntrgzxc.com> writes:
>> >> : postpone-postpone postpone postpone ;
[...]
>If POSTPONE POSTPONE compiles the compilation semantics of POSTPONE
>into POSTPONE-POSTPONE as Anton stated, what semantics does
>POSTPONE-POSTPONE have? i.e., compilation or interpretation.

The interpretation semantics of POSTPONE-POSTPONE are to perform the
compilation semantics of POSTPONE.

The compilation semantics of POSTPONE-POSTPONE are to append the
compilation semantics of POSTPONE to the current definition.

I left away the stuff that : and ; contribute, because they have no
outside effect for this code.

>POSTPONE-POSTPONE is executed in interpretation mode between [ ] in the
>definition of the word ppp4. So, the interpretation semantics for
>POSTPONE-POSTPONE - which are currently undefined

Like for all user-defined words, the interpretation semantics of
POSTPONE-POSTPONE are defined; I wrote out the interpretation
semantics above.

There is one thing you need to understand about interpretation and
compilation semantics in the standard: they do not depend on STATE.
Only the text interpreter uses STATE to decide whether to perform
interpretation semantics or compilation semantics; nothing else does.

dxforth

unread,
Jul 14, 2019, 6:54:33 AM7/14/19
to
On Sunday, 14 July 2019 10:00:01 UTC+10, Alex McDonald wrote:
> On 13-Jul-19 21:04, hughag...@gmail.com wrote:
> > ...
> > : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
> > ---------------------------------------------------------
> >
> > This has exactly the same effect as:
> > ---------------------------------------------------------
> > : PPP4 [ POSTPONE PPP1 ] ; IMMEDIATE
> > ---------------------------------------------------------
> >
>
> There's a difference. Although POSTPONE has undefined interpretation
> semantics, POSTPONE-POSTPONE has well defined interpretation semantics,
> which is to execute the *compilation* semantics of POSTPONE.

That's akin to the tail wagging the dog - using ANS terminology to
claim an entitlement for POSTPONE that ANS never explicitly gave.

Alex McDonald

unread,
Jul 14, 2019, 10:52:42 AM7/14/19
to
You'll have to explain that statement; I'm not understanding what you're
saying here.

--
Alex

dxforth

unread,
Jul 14, 2019, 12:34:06 PM7/14/19
to
I'm saying ANS was in the business of including existing systems and
any interpretation that suddenly excludes them should be viewed with
suspicion.

Anton Ertl

unread,
Jul 14, 2019, 12:54:46 PM7/14/19
to
dxforth <dxf...@gmail.com> writes:
>On Monday, 15 July 2019 00:52:42 UTC+10, Alex McDonald wrote:
>> On 14-Jul-19 11:54, dxforth wrote:
>> > On Sunday, 14 July 2019 10:00:01 UTC+10, Alex McDonald wrote:
>> >> There's a difference. Although POSTPONE has undefined interpretation
>> >> semantics, POSTPONE-POSTPONE has well defined interpretation semantics,
>> >> which is to execute the *compilation* semantics of POSTPONE.
>> >
>> > That's akin to the tail wagging the dog - using ANS terminology to
>> > claim an entitlement for POSTPONE that ANS never explicitly gave.
...
>I'm saying ANS was in the business of including existing systems and
>any interpretation that suddenly excludes them should be viewed with
>suspicion.

When I run the following code on Gforth 0.7.2, SwiftForth 3.6.3, and
VFX 4.72, they all work as required by the standard.

: POSTPONE-POSTPONE
POSTPONE POSTPONE ;

: PPP1 123 ;
: PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
: PPP5 PPP4 ;
PPP5 . \ prints 123

Alex McDonald

unread,
Jul 14, 2019, 4:37:03 PM7/14/19
to
On 14-Jul-19 07:53, Anton Ertl wrote:
> There is one thing you need to understand about interpretation and
> compilation semantics in the standard: they do not depend on STATE.
> Only the text interpreter uses STATE to decide whether to perform
> interpretation semantics or compilation semantics; nothing else does.

Reading this, I have just had an "exactly!" moment. It should be
somewhere in section 3 of the standard. That may annoy those that like
their STATE to direct semantics inside a word, but so be it.

--
Alex

dxforth

unread,
Jul 14, 2019, 9:16:27 PM7/14/19
to
On Monday, 15 July 2019 02:54:46 UTC+10, Anton Ertl wrote:
> dxforth <dxf...@gmail.com> writes:
> >On Monday, 15 July 2019 00:52:42 UTC+10, Alex McDonald wrote:
> >> On 14-Jul-19 11:54, dxforth wrote:
> >> > On Sunday, 14 July 2019 10:00:01 UTC+10, Alex McDonald wrote:
> >> >> There's a difference. Although POSTPONE has undefined interpretation
> >> >> semantics, POSTPONE-POSTPONE has well defined interpretation semantics,
> >> >> which is to execute the *compilation* semantics of POSTPONE.
> >> >
> >> > That's akin to the tail wagging the dog - using ANS terminology to
> >> > claim an entitlement for POSTPONE that ANS never explicitly gave.
> ...
> >I'm saying ANS was in the business of including existing systems and
> >any interpretation that suddenly excludes them should be viewed with
> >suspicion.
>
> When I run the following code on Gforth 0.7.2, SwiftForth 3.6.3, and
> VFX 4.72, they all work as required by the standard.
>
> : POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
> : PPP1 123 ;
> : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
> : PPP5 PPP4 ;
> PPP5 . \ prints 123
>
> - anton

Your interpretation of what a several decades old standard
requires is based on the behaviour of three modern systems?

A solution for POSTPONE that didn't include threaded code
systems and classical COMPILE wasn't an option for ANS.

hughag...@gmail.com

unread,
Jul 14, 2019, 10:37:30 PM7/14/19
to
On Sunday, July 14, 2019 at 12:02:18 AM UTC-7, Anton Ertl wrote:
> Rod Pemberton <inv...@lkntrgzxc.com> writes:
> >POSTPONE-POSTPONE is executed in interpretation mode between [ ] in the
> >definition of the word ppp4. So, the interpretation semantics for
> >POSTPONE-POSTPONE - which are currently undefined
>
> Like for all user-defined words, the interpretation semantics of
> POSTPONE-POSTPONE are defined; I wrote out the interpretation
> semantics above.
>
> There is one thing you need to understand about interpretation and
> compilation semantics in the standard: they do not depend on STATE.
> Only the text interpreter uses STATE to decide whether to perform
> interpretation semantics or compilation semantics; nothing else does.

I had said previously that Anton Ertl was incompetent.
I was being too generous!

Anton Ertl is a liar.
He knows perfectly well that it is illegal in ANS-Forth to execute
words such as POSTPONE IF etc. in interpretive mode,
for which ANS-Forth says:
"Interpretation semantics for this word are undefined."
Section 4.1.2 (Ambiguous Conditions) includes:
"interpretating a word with undefined interpretation semantics."
Dodgy Anton Ertl is doing some hand-waving and bullshit-slinging
in his attempt to work around this bug in ANS-Forth.

It is a bug in ANS-Forth to say that POSTPONE IF etc. can't be
used in interpretive mode because it is often worthwhile
to execute these words inside of [ ... ] brackets inside of
colon words.
Elizabeth Rather wrote in ANS-Forth (section 4.1.2) that this
is illegal (an "ambiguous condition" in her goofy terminology)
because it should be illegal when interpreting outside of
a colon word. You can't, for example, use IF ELSE THEN out there;
you should instead use: [IF] [ELSE] [THEN] out there.
It really makes no sense to use compiling words such as
POSTPONE IF ELSE THEN etc. outside of a colon word, because
where are you compiling code if you're not in a colon word???
It does make sense to use compiling words such as
POSTPONE IF ELSE THEN etc. inside of a colon word
inside of [ ... ] brackets though.

The reason why ANS-Forth has this bug, is that Elizabeth Rather
doesn't understand meta-compiling. She didn't know that
compiling words such as POSTPONE IF etc. make sense in
[ ... ] brackets in colon word definitions.
She also didn't know that meta-compiling code in
[ ... ] brackets in colon word definitions (or immediate words)
have have data passed in at compile-time.
This ignorance explains why she didn't know that the
control-flow stack needed to be distinct from the data-stack:
(section 3.2.3.2)
----------------------------------------------------------------
The control-flow stack may, but need not, physically exist
in an implementation. If it does exist, it may be, but need not be,
implemented using the data stack. The format of the control-flow stack
is implementation defined. Since the control-flow stack may be
implemented using the data stack, items placed on the data stack
are unavailable to a program after items are placed on the
control-flow stack and remain unavailable until the control-flow stack
items are removed.
----------------------------------------------------------------

Elizabeth Rather just didn't know anything about meta-compiling!
She didn't actually know anything in 1994 about Forth whatsoever.
She still doesn't...

On Sunday, July 14, 2019 at 9:54:46 AM UTC-7, Anton Ertl wrote:
> When I run the following code on Gforth 0.7.2, SwiftForth 3.6.3, and
> VFX 4.72, they all work as required by the standard.
>
> : POSTPONE-POSTPONE
> POSTPONE POSTPONE ;
>
> : PPP1 123 ;
> : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
> : PPP5 PPP4 ;
> PPP5 . \ prints 123
>
> - anton

Anton Ertl is totally lying!
He is executing POSTPONE inside of [ ... ] brackets,
which is interpretive mode.
Unfortunately for dodgy Anton Ertl, the ANS-Forth documentation
for POSTPONE (6.1.2033) says:
"Interpretation semantics for this word are undefined."
Anton Ertl's pseudo-intellectual hand-waving doesn't change this.

Anton Ertl is a grotesque brown-noser of Elizabeth Rather.
He is afraid of pointing out that ANS-Forth has bugs because
this is the same as pointing out that Elizabeth Rather is a fake
and an incompetent. So he continues to say that Elizabeth Rather's
ANS-Forth is meaningful, but he tries to use hand-waving to cover
up the fact that ANS-Forth forbids him from executing compiling words
such as POSTPONE IF ELSE THEN etc. inside of [ ... ] brackets.

hughag...@gmail.com

unread,
Jul 14, 2019, 10:56:36 PM7/14/19
to
Is Alex McDonald's "exactly!" moment similar to
Andrew Haley's famous "aha!" moments?

I have these moments too if I eat regularly...

Anton Ertl asys that the determination of whether we are
interpreting or compiling does not depend upon STATE .
Really??? That is exactly what STATE determines!
I think Anton Ertl needs to have one of these moments too,
because he is full of shit. "Aha!" "Exactly!"

BTW: Elizabeth Rather is semi-literate at best.
She is using the word "semantics" incorrectly.
The word she should have used was: "action."
Her use of the word "semantics" was pseudo-intellectual glitz.
Sales clowns often use big words to make themselves seem smart,
but use the words incorrectly to reveal their idiocy.

Mark William Humphries

unread,
Jul 15, 2019, 1:04:19 AM7/15/19
to
One way to think about is that the state we're in (interpretation or compilation) affects which XT the outer interpreter looks for and finds, and also what the outer interpreter subsequently does with that XT.
But the interpretation/compilation state does not change which "code address" is called when we EXECUTE an XT.

dxforth

unread,
Jul 15, 2019, 1:31:58 AM7/15/19
to
On Monday, 15 July 2019 12:37:30 UTC+10, hughag...@gmail.com wrote:
> ...
> It is a bug in ANS-Forth to say that POSTPONE IF etc. can't be
> used in interpretive mode because it is often worthwhile
> to execute these words inside of [ ... ] brackets inside of
> colon words.
> ...
> The reason why ANS-Forth has this bug, is that Elizabeth Rather
> doesn't understand meta-compiling.

It might have been a bug had ANS supported meta-compiling.
It doesn't. It did leave the door open to systems that needed
POSTPONE to work inside brackets by specifying 'undefined
interpretation semantics'. Meta-compilation is not an essential
feature of forth and I see no reason why every system should be
required to support it.

Ruvim

unread,
Jul 15, 2019, 4:05:10 AM7/15/19
to
Perhaps the below explanation would be useful for somebody.


*** The excerpts from the Standard ***

execution token:
A value that identifies the execution semantics of a definition.

execution semantics:
The *behavior* of a Forth definition when it is executed.

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

Unless otherwise specified in an "Interpretation:" section of
the glossary entry, the interpretation semantics of a Forth
definition are its execution semantics.

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

Unless otherwise specified in a "Compilation:" section of
the glossary entry, the compilation semantics of a Forth definition
shall be to append its execution semantics to the execution
semantics of the current definition.

current definition:
The definition whose compilation has been started but not yet ended.

immediate word:
A Forth word whose compilation semantics are to perform its
execution semantics.


*** End of the excerpts ***



Let's repeat:

Semantics is a behavior. It can be identified by an execution token (xt).

Default interpretation semantics is execution semantics. But in some
cases it my be other.

Default compilation semantics is to append execution semantics to the
current definition. But in some cases it may be other.


Let's consider an example.

: foo ." foo for interpreting" ;
: bar ." bar for compiling" ;
: foobar state @ if bar else foo then ; immediate

So, for foobar word:
Interpretation semantics: to print "foo for interpreting"
Compilation semantics: to print "bar for compiling" (due to immediacy)
Execution semantics: to print one or another depending on the STATE.

'foobar is an xt that identifies the execution semantics for foobar.
'foo is an xt that identifies the interpretation semantics for foobar
(in the same time it is the execution token of foo)
'bar is an xt that identifies compilation semantics for foobar.
(in the same time it is the execution token of bar)


foo and bar can be used in whatever way. foo can be even performed in
the compilation state, and bar can be even performed in the
interpretation state. They can be compiled into another definitions. But
it does not change that foo is the interpretation semantics for foobar,
and bar is the compilation semantics for foobar.


So, what should "POSTPONE foobar" do? It should append compilation
semantic of foobar to the current definition, — it should append bar (or
equivalent code).

: foobar-compiling POSTPONE foobar ;

foobar-compiling \ should prints "bar for compiling"

foobar-compiling can never performs interpretation semantics of foobar
(i.e. foo), since POSTPONE appends only compilation semantics.




The same when POSTPONE is applied to POSTPONE as:

: postpone-compiling POSTPONE POSTPONE ;

: foobar-compiling [ postpone-compiling foobar ] ;

postpone-compiling cannot performs interpretation semantics of POSTPONE
since its compilations semantics only was appended.

It can be even used when there is no current definition, just as:
postpone-compiling foobar

Some Forth systems can throw exception since you try to appending
something to the current definition when it is absent. Others will just
append an orphan code fragment.




There is one problem that in many implementations POSTPONE cannot get xt
of the compilation semantics in some cases (like this state-smart
foobar). But actually this circumstance should not prevent the author
from a correct implementation of POSTPONE.


\ To execute xt in the compilation state
: EXECUTE-COMPILING ( i*x xt --j*x )
STATE @ IF EXECUTE EXIT THEN ] EXECUTE [COMPILE] [
;
: POSTPONE
BL WORD FIND DUP 0= IF -13 THROW THEN
1 = IF LIT, ['] EXECUTE-COMPILING COMPILE, EXIT THEN
LIT, ['] COMPILE, COMPILE,
; IMMEDIATE


This implementation ensures that only compilation semantics will be
performed at run-time even for state-smart words. There is one edge case
but it can be solved too.


--
Ruvim

Ruvim

unread,
Jul 15, 2019, 4:48:20 AM7/15/19
to
On 2019-07-15 11:05, Ruvim wrote:
[...]
>
> There is one problem that in many implementations POSTPONE cannot get xt
> of the compilation semantics in some cases (like this state-smart
> foobar). But actually this circumstance should not prevent the author
> from a correct implementation of POSTPONE.
>
>
> \ To execute xt in the compilation state
> : EXECUTE-COMPILING ( i*x xt --j*x )
>   STATE @ IF EXECUTE EXIT THEN  ] EXECUTE [COMPILE] [
> ;
> : POSTPONE
>   BL WORD FIND DUP 0= IF -13 THROW THEN
>   1 = IF LIT, ['] EXECUTE-COMPILING COMPILE, EXIT THEN
>   LIT, ['] COMPILE, COMPILE,
> ; IMMEDIATE


If FIND may return different result depending on STATE
(or portable implementation is required), FIND should be preformed in
the compilation mode:

: POSTPONE
BL WORD ['] FIND EXECUTE-COMPILING DUP 0= IF -13 THROW THEN

Anton Ertl

unread,
Jul 15, 2019, 5:16:26 AM7/15/19
to
Ruvim <ruvim...@gmail.com> writes:
>execution semantics:
> The *behavior* of a Forth definition when it is executed.
>
>interpretation semantics:
> The *behavior* of a Forth definition when its *name is encountered*
> by the text interpreter in interpretation state.
>
> Unless otherwise specified in an "Interpretation:" section of
> the glossary entry, the interpretation semantics of a Forth
> definition are its execution semantics.
>
>compilation semantics:
> The *behavior* of a Forth definition when its *name is encountered*
> by the text interpreter in compilation state.
>
> Unless otherwise specified in a "Compilation:" section of
> the glossary entry, the compilation semantics of a Forth definition
> shall be to append its execution semantics to the execution
> semantics of the current definition.
[...]
>Let's consider an example.
>
>: foo ." foo for interpreting" ;
>: bar ." bar for compiling" ;
>: foobar state @ if bar else foo then ; immediate
>
>So, for foobar word:
> Interpretation semantics: to print "foo for interpreting"
> Compilation semantics: to print "bar for compiling" (due to immediacy)
> Execution semantics: to print one or another depending on the STATE.

Not quite:

You got the execution semantics right.

FOOBAR has default interpretation semantics, i.e., the same
STATE-dependent semantics as the execution semantics.

FOOBAR has immediate compilation semantics, i.e., the same
STATE-dependent semantics as the execution and interpretation
semantics.

The intent of this STATE-smart word may have been to implement the
combination of interpretation and compilation semantics outlined
above, but that does not work in all cases. In particular, it does
not work as intended when you perform the interpretation semantics in
compile state or the compilation semantics in interpret state.

If you want to implement arbitrary combinations of interpretation and
compilation semantics, you need a mechanism that works at text
interpretation time, not at run-time.

Alex McDonald

unread,
Jul 15, 2019, 6:47:45 AM7/15/19
to
That would exclude

: 5or10 if 5 else 10 then ;
: its5 [ true 5or10 ] literal . ;

IF ELSE and THEN are being compiled by the text interpreter in
compilation state, hence their compilation semantics are being appended
to the definition; and when they are executed in interpretation state
they are all executing those previously compiled compilation semantics.
None of them (much like POSTPONE) has any interpretation semantics.

I shared your confusion during a late night testing session with
POSTPONE, hence my original post. But it's only taken a few minutes of
reading the standard and Anton's points for it to be clear.

Hugh's disambugifiers (and here I guess what his IF looks like)

: IF state @ 0= if
." warning IF is undefined in interpretation state"
else postpone if then ; immediate

illustrate the problem. This would fail to run the above, because (like
many state-smart words) they conflate run time and text interpretation
time. They're two different things.

On Hugh's meta-compilation point and your counter point, I'm surprised
that you would claim it's not possible to write an meta-compiler without
a POSTPONE that works inside [ ] (much like Hugh's claim that you can't
do it without a vectored LITERAL), but that it's OK because it's "not
essential". Systems like mine and Win32Forth are testament to the
capability of ANS Forths and their authors to write meta-compilers
without POSTPONEs that work as you describe.



C:\wf32\v610>wf32
STC 32bit: 0.06.10 Build: 716
: foo [ postpone dup ] ;
^^^^^^^^
Error -14 in (console): postpone is compilation only



C:\wf32\v610>wf32 .version include src/kernel/gmeta32.fs
STC 32bit: 0.06.10 Build: 716
Loading META GKERNEL Wrapper src/kernel/gmeta32.fs
Loading META version info src/version.fs
Loading META Compiler src/kernel/gmeta-compiler32.fs
Loading global structures... src/kernel/gstructs.fs

Build information
Directory: C:\wf32\v610
Compiler: src\kernel\gmeta-compiler32.fs
Source: src\kernel\gkernel32.fs
Version from: src\version.fs
Version: STC 32bit: 0.06.10 Build: 717
Build Image: gkernel32.exe Type: 3 CUI

Compiling...
Loading global structures... src/kernel/gstructs.fs
Compile complete, doing fixups
Fixup list heads...
Move vocabulary threads...
Fixup data pointers & section lengths...
Fixup forward reference compile tokens...
Fixup literal, :noname tokens, value/defer jumps...
Stack clean on exit
0 errors during meta-compile


Load point $400000
Entry point +$8914
Section Address Used Allocated
------------------------------------------
.code 00401000 32,372 4,194,304
.app 00801000 5,116 4,194,304
.sys 00C01000 32,700 4,194,304
------------------------------------------
Total 70,188

Building image gkernel32.exe
Built length 81920 bytes (80 KB)
Compilation complete, elapsed time: 00:00:00.063



--
Alex

none albert

unread,
Jul 15, 2019, 7:41:50 AM7/15/19
to
In article <qghekh$1t95$1...@gioia.aioe.org>,
Ruvim <ruvim...@gmail.com> wrote:
<SNIP>
>: POSTPONE
> BL WORD ['] FIND EXECUTE-COMPILING DUP 0= IF -13 THROW THEN
> 1 = IF LIT, ['] EXECUTE-COMPILING COMPILE, EXIT THEN
> LIT, ['] COMPILE, COMPILE,
>; IMMEDIATE

Compare to indirect threaded code:
: POSTPONE
\ NAME FOUND DUP IMMEDIATE?
BL WORD FIND 1 =
IF , ELSE 'LIT , ', , THEN
; IMMEDIATE
Where 'LIT must be replaced by ['] LIT or
' LIT but I cannot remember which is which.

Note that the immediate case is the simplest one,
the xt is just copied over to the current definition.

>--
>Ruvim
>
Groetjes Albert
--
This is the first day of the end of your life.
It may not kill you, but it does make your weaker.
If you can't beat them, too bad.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Alex McDonald

unread,
Jul 15, 2019, 7:46:48 AM7/15/19
to
Modern? As in, they're as old as the standard which is 25 years old (if
you ignore the work to update it). The original C standard is older
(actually, lots of language standards are older).

gforth predates ANS. SwiftForth and VFX weren't far behind; a couple of
years after ANS.

>
> A solution for POSTPONE that didn't include threaded code
> systems and classical COMPILE wasn't an option for ANS.
>

What do you mean? gforth is a hybrid ITC/DTC. Win32Forth is an ITC, and
it too runs the code above perfectly. (And it's "ancient"; it was
developed in 1994, the same year as the standard.)

--
Alex

Ruvim

unread,
Jul 15, 2019, 8:17:10 AM7/15/19
to
It's a delicate moment. And since the Standard is not quite clear in
this, it seems that different interpretations may have place.


You claim that the interpretation semantics for FOOBAR is
STATE-depended. But how to prove it? By definition, the interpretation
semantics of FOOBAR is a behavior that occurs when FOOBAR name is
encountered by the text interpreter *in interpretation state*.

We can't demonstrate another behavior in another state, since
in another state it will be not interpretation semantics.

But if we want to represent the behavior of FOOBAR in *in interpretation
state* as xt (execution token), the corresponding execution semantics
shall be STATE-independent. Hence, in this sense, we can say that the
interpretation semantics for FOOBAR is STATE-independent.


The same regarding compilation semantics.
The compilation semantics of FOOBAR is a behavior that occurs when
FOOBAR name is encountered by the text interpreter *in compilation
state*. And being represented by xt, it shall be STATE-independent.



> The intent of this STATE-smart word may have been to implement the
> combination of interpretation and compilation semantics outlined
> above, but that does not work in all cases. In particular, it does
> not work as intended when you perform the interpretation semantics in
> compile state


The Standard does not provide a special mechanism to perform the
interpretation semantics of a word in compile state. It provide a way to
perform the execution semantics (and occasionally the interpretation
semantics when they are the same).


Tick return an execution token that, by definition, identifies the
*execution semantics*.

6.1.2510 [']
... Place name's *execution token* xt on the stack.

6.1.0070 '
... return xt, the *execution token* for name.

The illustration:
"When interpreting, ' xyz EXECUTE is equivalent to xyz "

— means that performing execution semantics of a word in interpretation
state has the exactly same effect as performing its interpretation
semantics.



> or the compilation semantics in interpret state.

Properly implemented POSTPONE formally allows to do it.

But actually, compilation semantics cannot detect 0 value in STATE. So,
you think that you perform it in interpretation state, but it "thinks"
that it is performed in compilation state.



> If you want to implement arbitrary combinations of interpretation and
> compilation semantics, you need a mechanism that works at text
> interpretation time, not at run-time.

The immediate words work at the text interpretation time.

I have also checked the examples from your work "State-smartness — why
it is evil and how to exorcise it" and does not find a relevant example.

The most examples there are about a standard word that has not standard
execution semantics.

Regarding the word S" — the standard does not specify execution
semantics for it. So, an ambiguous condition exist if tick (' or ['])
is applied to this word. And it is the same for other words with
undefined execution semantics.


--
Ruvim

Alex McDonald

unread,
Jul 15, 2019, 9:18:51 AM7/15/19
to
And its XT is EXECUTEd.

>
> We can't demonstrate another behavior in another state, since
> in another state it will be not interpretation semantics.
>
> But if we want to represent the behavior of FOOBAR in *in interpretation
> state* as xt (execution token), the corresponding execution semantics
> shall be STATE-independent. Hence, in this sense, we can say that the
> interpretation semantics for FOOBAR is STATE-independent.

' foobar execute
: barfoo ['] foobar execute ;

Both are always the interpretation semantics of FOOBAR; neither is state
dependent. The error is in the definition of FOOBAR; because STATE
reflects the state when interpreted or compiled by the text interpreter,
but contrary to some expectations it is meaningless when FOOBAR is
executed. STATE doesn't provide this information.

>
>
> The same regarding compilation semantics.
> The compilation semantics of FOOBAR is a behavior that occurs when
> FOOBAR name is encountered by the text interpreter *in compilation
> state*. And being represented by xt, it shall be STATE-independent. >
>
>
>> The intent of this STATE-smart word may have been to implement the
>> combination of interpretation and compilation semantics outlined
>> above, but that does not work in all cases.  In particular, it does
>> not work as intended when you perform the interpretation semantics in
>> compile state
>
>
> The Standard does not provide a special mechanism to perform the
> interpretation semantics of a word in compile state. It provide a way to
> perform the execution semantics (and occasionally the interpretation
> semantics when they are the same).

Tick always returns the interpretation semantics regardless of state.

: bar ['] postpone execute ;
ok
bar dup
^^^
Error -14 in (console): bar is compilation only
: foo bar dup ;
ok
foo
^^^
Error -14 in (console): foo is compilation only

(The system points to BAR; the error comes from POSTPONE but the name
has been lost, and only BAR's name is available. Ditto FOO.)

>
>
> Tick return an execution token that, by definition, identifies the
> *execution semantics*.

I think that's a misreading. An execution token is something that can be
executed (for which the shorthand is XT). The semantics can be
interpretation or compilation. You mean interpretation semantics.

>
> 6.1.2510 [']
>   ... Place name's *execution token* xt on the stack.
>
> 6.1.0070 '
>   ... return xt, the *execution token* for name.
>
> The illustration:
>  "When interpreting, ' xyz EXECUTE is equivalent to xyz "
>
> — means that performing execution semantics of a word in interpretation
> state has the exactly same effect as performing its interpretation
> semantics.

No, it means that the execution *token* (the XT, the thing EXECUTEd),
when executed in interpretation state, executes the interpretation
semantics.

>
>
>
>> or the compilation semantics in interpret state.
>
> Properly implemented POSTPONE formally allows to do it.
>
> But actually, compilation semantics cannot detect 0 value in STATE. So,
> you think that you perform it in interpretation state, but it "thinks"
> that it is performed in compilation state.

That's true, and is the point I make above about STATE.

>
>
>
>> If you want to implement arbitrary combinations of interpretation and
>> compilation semantics, you need a mechanism that works at text
>> interpretation time, not at run-time.
>
> The immediate words work at the text interpretation time.

But they require STATE, and it is meaningless at run time.

>
> I have also checked the examples from your work "State-smartness — why
> it is evil and how to exorcise it" and does not find a relevant example.
>
> The most examples there are about a standard word that has not standard
> execution semantics.
>
> Regarding the word S" — the standard does not specify execution
> semantics for it.  So, an ambiguous condition exist if tick (' or ['])
> is applied to this word. And it is the same for other words with
> undefined execution semantics.

Interpretation semantics.

>
>
> --
> Ruvim


--
Alex

Ruvim

unread,
Jul 15, 2019, 11:05:54 AM7/15/19
to
On 2019-07-15 16:18, Alex McDonald wrote:
> On 15-Jul-19 13:17, Ruvim wrote:
>> On 2019-07-15 12:06, Anton Ertl wrote:
>>> Ruvim <ruvim...@gmail.com> writes:
>>>> execution semantics:
>>>>      The *behavior* of a Forth definition when it is executed.
>>>>
>>>> interpretation semantics:
>>>>      The *behavior* of a Forth definition when its name is
>>>> encountered by the text interpreter in interpretation state.
>>>>
>>>>      Unless otherwise specified in an "Interpretation:" section
>>>>      of the glossary entry, the interpretation semantics
>>>>      of a Forth definition are its execution semantics. >>>>
>>>> compilation semantics:
>>>>      The *behavior* of a Forth definition when its name is
>>>> encountered by the text interpreter in compilation state.
Actually, the Standard does not specify what XT is EXECUTed in this
situation. Formally it may be another associated XT (that cannot be
obtained by Tick).



>> We can't demonstrate another behavior in another state, since
>> in another state it will be not interpretation semantics.
>>
>> But if we want to represent the behavior of FOOBAR in *in
>> interpretation state* as xt (execution token), the corresponding
>> execution semantics shall be STATE-independent. Hence, in this sense,
>> we can say that the interpretation semantics for FOOBAR is
>> STATE-independent.
>
> ' foobar execute
> : barfoo ['] foobar execute ;
>
> Both are always the interpretation semantics of FOOBAR; neither is state
> dependent.

What you system outputs in the following case?

: foobar-immediate ['] foobar execute ; immediate
: test foobar-immediate ;

If it prints "foo for interpreting" than the behavior represented by xt
that tick returns in this case does not depend on STATE. And your system
is not a Standard system.

If it prints "bar for compiling" than this behavior depends on the STATE
and it is compliant to the Standard.





> The error is in the definition of FOOBAR;

What error? FOOBAR definition is a standard code.


> because STATE
> reflects the state when interpreted or compiled by the text interpreter,
> but contrary to some expectations it is meaningless when FOOBAR is
> executed. STATE doesn't provide this information.

In a Standard Forth system, when FOOBAR is executed it is executed by
the text interpreter in any case, but in some cases it is executed
indirectly. So, STATE is always meaningful.



[...]
>>> The intent of this STATE-smart word may have been to implement the
>>> combination of interpretation and compilation semantics outlined
>>> above, but that does not work in all cases.  In particular, it does
>>> not work as intended when you perform the interpretation semantics in
>>> compile state
>>
>>
>> The Standard does not provide a special mechanism to perform the
>> interpretation semantics of a word in compile state. It provide a way
>> to perform the execution semantics (and occasionally the
>> interpretation semantics when they are the same).
>
> Tick always returns the interpretation semantics regardless of state.

By the Standard Tick always return the *execution semantics*.
Not interpretation semantics. But occasionally they may coincide.

>
> : bar ['] postpone execute ;
>  ok
> bar dup
> ^^^
> Error -14 in (console): bar is compilation only

What about the following?

: test [ bar dup ] ;

In this case bar is executed in interpretation state too.




>>
>> Tick return an execution token that, by definition, identifies the
>> *execution semantics*.
>
> I think that's a misreading. An execution token is something that can be
> executed (for which the shorthand is XT). The semantics can be
> interpretation or compilation. You mean interpretation semantics.

I quoted the terms definitions from the Standard. Please, refer.

The standard distinguish the following semantics:
- execution semantics,
- interpretation semantics,
- compilation semantics,
- initiation semantics,
- run-time semantics,

See: https://forth-standard.org/standard/usage#subsection.3.4.3


>
>>
>> 6.1.2510 [']
>>    ... Place name's *execution token* xt on the stack.
>>
>> 6.1.0070 '
>>    ... return xt, the *execution token* for name.
>>
>> The illustration:
>>   "When interpreting, ' xyz EXECUTE is equivalent to xyz "
>>
>> — means that performing execution semantics of a word in
>> interpretation state has the exactly same effect as performing its
>> interpretation semantics.
>
> No, it means that the execution *token* (the XT, the thing EXECUTEd),
> when executed in interpretation state, executes the interpretation
> semantics.

You said almost the same thing in other words.
With one nuance: "equivalent" does not mean "the same instance".


--
Ruvim

JennyB

unread,
Jul 15, 2019, 12:04:50 PM7/15/19
to
On the single-xt-plus-immediate model:

FIND ' and ['] all return the same xt, which represents the execution semantics.
Depending on the flag returned by FIND , the code compiled by POSTPONE either:

Compiles a call to the execution semantics (default compilation semantics)
This may include optimising the code in any way the compiler sees fit.

or

Executes the execution semantics (= performs the compilation semantics)

Thus, either way, it appends the compilation semantics of the definition. It does the same thing that the text interpreter does when it encounters the definition during compilation.

Some systems implement definitions with distinct interpretation and compilation
semantics (such as TO and S") by providing separate xts to represent interpretation
and compilation semantics.

In this case:

' ['] and FIND (while interpreting) return the xt representing the interpretation
semantics.

FIND while compiling returns the xt representing the compilation semantics,
together with an immediate flag. Therefore POSTPONE works exactly as above;
the code compiled works the same regardless of STATE.

Neither of these two systems are going away, so for code to be portable we need to be
aware of their respective limitations.

For dual-behaviour definitions, single xt systems can't return an xt that
represents either the interpretation or compilation semantics regardless of STATE.
Therefore, if you ' or ['] such a definition, make sure the resulting xt,
or any code in which it is COMPILE,ed , can only be executed while interpreting.
Likewise, if it is POSTPONEd, make sure the resulting code can only be executed
while compiling.

Alex McDonald

unread,
Jul 15, 2019, 12:34:00 PM7/15/19
to
On 15-Jul-19 16:05, Ruvim wrote:
> On 2019-07-15 16:18, Alex McDonald wrote:
>> On 15-Jul-19 13:17, Ruvim wrote:

>>> You claim that the interpretation semantics for FOOBAR is
>>> STATE-depended. But how to prove it? By definition, the
>>> interpretation semantics of FOOBAR is a behavior that occurs when
>>> FOOBAR name is encountered by the text interpreter *in interpretation
>>> state*.
>>
>> And its XT is EXECUTEd.
>
> Actually, the Standard does not specify what XT is EXECUTed in this
> situation. Formally it may be another associated XT (that cannot be
> obtained by Tick).

What? When the text interpreter looks up <name> by using (classically)
FIND and gets back an XT to execute, it must be the same XT from tick; '
<name> execute is the equivalent of the interpretation semantics *by
definition*. You quoted this yourself;

http://forth-standard.org/standard/core/Tick: When interpreting, ' xyz
EXECUTE is equivalent to xyz.

>
>
>
>>> We can't demonstrate another behavior in another state, since
>>> in another state it will be not interpretation semantics.
>>>
>>> But if we want to represent the behavior of FOOBAR in *in
>>> interpretation state* as xt (execution token), the corresponding
>>> execution semantics shall be STATE-independent. Hence, in this sense,
>>> we can say that the interpretation semantics for FOOBAR is
>>> STATE-independent.
>>
>> ' foobar execute
>> : barfoo ['] foobar execute ;
>>
>> Both are always the interpretation semantics of FOOBAR; neither is
>> state dependent.
>
> What you system outputs in the following case?
>
> : foobar-immediate ['] foobar execute ; immediate
> : test foobar-immediate ;
>
> If it prints "foo for interpreting" than the behavior represented by xt
> that tick returns in this case does not depend on STATE. And your system
> is not a Standard system.
>
> If it prints "bar for compiling" than this behavior depends on the STATE
> and it is compliant to the Standard.

Of course it depends on the state; the code has a conditional based on
it. It outputs "bar for compiling". But that doesn't make STATE based
words magically function correctly.


: foo ." foo for interpreting" ;
: bar ." bar for compiling" ;
: foobar state @ if bar else foo then ; immediate
: barfoo postpone foobar ;
: test barfoo ;

cr foobar \ prints "foo for interpreting"
cr test \ prints "foo for interpreting"

: foo ." foo for interpreting" ;
: bar ." bar for compiling" ;
: foobar foo compiles> drop bar ; \ ***
: barfoo postpone foobar ;
: test barfoo ;

cr foobar \ prints "foo for interpreting"
cr test \ prints "bar for compiling"


The code marked *** uses a word that has an interpretation part and a
compilation part. It does not depend on the run-time or execution state;
the part selected is chosen by the text interpreter when it is compiled.


>
>
>
>
>
>> The error is in the definition of FOOBAR;
>
> What error?  FOOBAR definition is a standard code.

See above.

>
>
>> because STATE reflects the state when interpreted or compiled by the
>> text interpreter, but contrary to some expectations it is meaningless
>> when FOOBAR is executed. STATE doesn't provide this information.
>
> In a Standard Forth system, when FOOBAR is executed it is executed by
> the text interpreter in any case, but in some cases it is executed
> indirectly. So, STATE is always meaningful.

See above.

>
>
>
> [...]
>>>> The intent of this STATE-smart word may have been to implement the
>>>> combination of interpretation and compilation semantics outlined
>>>> above, but that does not work in all cases.  In particular, it does
>>>> not work as intended when you perform the interpretation semantics in
>>>> compile state
>>>
>>>
>>> The Standard does not provide a special mechanism to perform the
>>> interpretation semantics of a word in compile state. It provide a way
>>> to perform the execution semantics (and occasionally the
>>> interpretation semantics when they are the same).
>>
>> Tick always returns the interpretation semantics regardless of state.
>
> By the Standard Tick always return the *execution semantics*.
> Not interpretation semantics. But occasionally they may coincide.

This is not the case, since ' <name> execute is the equivalent of
<name>. By definition.

>
>>
>> : bar ['] postpone execute ;
>>   ok
>> bar dup
>> ^^^
>> Error -14 in (console): bar is compilation only
>
> What about the following?
>
> : test [ bar dup ] ;
>
> In this case bar is executed in interpretation state too.

Correct. It's an error, since POSTPONE has no defined execution
semantics, and ' POSTPONE EXECUTE is the equivalent of POSTPONE and
ambiguous. But this;

: bar postpone dup ;
: test [ bar ] ;

The POSTPONE has been compiled. It is the compilation semantics of
POSTPONE that BAR is executing. The state is immaterial.

>
>
>
>
>>>
>>> Tick return an execution token that, by definition, identifies the
>>> *execution semantics*.
>>
>> I think that's a misreading. An execution token is something that can
>> be executed (for which the shorthand is XT). The semantics can be
>> interpretation or compilation. You mean interpretation semantics.
>
> I quoted the terms definitions from the Standard. Please, refer.
>
> The standard distinguish the following semantics:
>   - execution semantics,
>   - interpretation semantics,
>   - compilation semantics,
>   - initiation semantics,
>   - run-time semantics,
>
> See: https://forth-standard.org/standard/usage#subsection.3.4.3

Yes, but you are misusing the broad execution semantics when you mean
the narrower interpretation.

>
>
>>
>>>
>>> 6.1.2510 [']
>>>    ... Place name's *execution token* xt on the stack.
>>>
>>> 6.1.0070 '
>>>    ... return xt, the *execution token* for name.
>>>
>>> The illustration:
>>>   "When interpreting, ' xyz EXECUTE is equivalent to xyz "
>>>
>>> — means that performing execution semantics of a word in
>>> interpretation state has the exactly same effect as performing its
>>> interpretation semantics.
>>
>> No, it means that the execution *token* (the XT, the thing EXECUTEd),
>> when executed in interpretation state, executes the interpretation
>> semantics.
>
> You said almost the same thing in other words.
> With one nuance: "equivalent" does not mean "the same instance".

In that case, you would require a very smart EXECUTE.

--
Alex

dxforth

unread,
Jul 15, 2019, 10:48:48 PM7/15/19
to
Doesn't work on DX-Forth. If your POSTPONE happens to work in interpret mode
in certain circumstances, good luck to you. However a standard program can't
count on it. POSTPONE was defined as 'no interpretation' and implementers are
entitled to assume no if's but's or maybe's.

From 20 years ago enjoy exactly the same discussion:

https://groups.google.com/d/msg/comp.lang.forth/nNTw9VjlSGU/S8TxJ9jiPpQJ

Standard Forth can't die if it's stuck in a perpetual loop. Heavy on the
personnel but its leaders don't care about that. Grist for their mill.

Mark William Humphries

unread,
Jul 15, 2019, 11:24:51 PM7/15/19
to
Interesting trip down memory lane. My approach to addressing all the issues discussed hasn't fundamentally changed since then:
https://www.reddit.com/r/Forth/comments/9izdtq/a_simple_approach_to_dual_words/

A. K.

unread,
Jul 16, 2019, 2:43:35 AM7/16/19
to
I use the same concept.

And state-smart words are so simple. He who stumbles over them has tested
his applications not thoroughly enough.

He who takes every grain of wording in the Standard document biblically
fundamentally and thus complicates the whole compiler has lost the spirit
of 'make it simple' in Forth.

Ruvim

unread,
Jul 16, 2019, 3:29:11 AM7/16/19
to
On 2019-07-15 19:33, Alex McDonald wrote:
> On 15-Jul-19 16:05, Ruvim wrote:
>> On 2019-07-15 16:18, Alex McDonald wrote:
>>> On 15-Jul-19 13:17, Ruvim wrote:
>
>>>> You claim that the interpretation semantics for FOOBAR is
>>>> STATE-depended. But how to prove it? By definition, the
>>>> interpretation semantics of FOOBAR is a behavior that occurs when
>>>> FOOBAR name is encountered by the text interpreter *in
>>>> interpretation state*.
>>>
>>> And its XT is EXECUTEd.
>>
>> Actually, the Standard does not specify what XT is EXECUTed in this
>> situation. Formally it may be another associated XT (that cannot be
>> obtained by Tick).
>
> What? When the text interpreter looks up <name> by using (classically)
> FIND and gets back an XT to execute, it must be the same XT from tick;

A standard Forth system may not use FIND internally at all.
If the XT that it performs is not the same as XT from Tick, how do you
detect this fact? You can only compare the behavior (a part of them).
And the behavior is the same.



> ' <name> execute is the equivalent of the interpretation semantics *by
> definition*. You quoted this yourself;
>
> http://forth-standard.org/standard/core/Tick: When interpreting, ' xyz
> EXECUTE is equivalent to xyz.

Yet again: "equivalent" does not mean "the same instance". Technically
it can be two different instance with equivalent behavior.




>>>> But if we want to represent the behavior of FOOBAR in *in
>>>> interpretation state* as xt (execution token), the corresponding
>>>> execution semantics shall be STATE-independent. Hence, in this
>>>> sense, we can say that the interpretation semantics for FOOBAR is
>>>> STATE-independent.
>>>
>>> ' foobar execute
>>> : barfoo ['] foobar execute ;
>>> >>> Both are always the interpretation semantics of FOOBAR; neither is
>>> state dependent.
[...]
>> : foobar-immediate ['] foobar execute ; immediate
>> : test foobar-immediate ;
[...]
> Of course it depends on the state; the code has a conditional based on
> it. It outputs "bar for compiling".

Hence, the execution semantics and the interpretation semantics are not
the same for FOOBAR. Isn't it?




> : foo ." foo for interpreting" ;
> : bar ." bar for compiling" ;
> : foobar state @ if bar else foo then ; immediate
> : barfoo postpone foobar ;
> : test barfoo ;
>
>  cr foobar \ prints "foo for interpreting"
>  cr test   \ prints "foo for interpreting"

I could say that such POSTPONE has a flaw — it works incorrectly with
the STATE-smart words. It appends execution semantics in place of
compilation semantics. This flaw should be either documented or fixed.


In the case of a classic FIND-based Forth system a correct POSTPONE can
be defined as:

: execute-compiling ( i*x xt --j*x )
state @ if execute exit then ] execute [compile] [
;
: postpone
bl word find
dup -1 = if drop lit, 'compile, compile, exit then
1 = if lit, 'execute-compiling compile, exit then
-13 throw
; immediate



> : foo ." foo for interpreting" ;
> : bar ." bar for compiling" ;
> : foobar foo compiles> drop bar ; \ ***
> : barfoo postpone foobar ;
> : test barfoo ;
>
>  cr foobar \ prints "foo for interpreting"
>  cr test   \ prints "bar for compiling"
>
>
> The code marked *** uses a word that has an interpretation part and a
> compilation part. > It does not depend on the run-time or execution state;

But it may depend on the state, for example:

: state. state @ if ." compiling" else ." interpreting" then ;
: foo ." foo for " state. ;
: bar ." bar for " state. ;
: foobar foo compiles> drop bar ;

: foobar-executing ['] foobar execute ; immediate
: foobar-compiling postpone foobar ; immediate

foobar-executing ] foobar-executing [
foobar-compiling ] foobar-compiling [

> the part selected is chosen by the text interpreter when it is compiled.

Another part is also chosen (depending on STATE) when the compiled code
is performed. And what?






>>> The error is in the definition of FOOBAR;
>>
>> What error?  FOOBAR definition is a standard code.
>
> See above.

Well, FOOBAR does not contain any error.




>>>> The Standard does not provide a special mechanism to perform the
>>>> interpretation semantics of a word in compile state. It provide a
>>>> way to perform the execution semantics (and occasionally the
>>>> interpretation semantics when they are the same).
>>>
>>> Tick always returns the interpretation semantics regardless of state.
>>
>> By the Standard Tick always return the *execution semantics*.
>> Not interpretation semantics. But occasionally they may coincide.
>
> This is not the case, since ' <name> execute is the equivalent of
> <name>. By definition.

You have missed "in interpretation state". In another state this
equivalence may be not held.

OTOH, if this equivalence is held for any word and any state — why does
the Standard need the both terms? (i.e. "execution semantics" and
"interpretation semantics"). One of them would be enough.
Don't you think so?



>>>
>>> : bar ['] postpone execute ;
[...]
> It's an error, since POSTPONE has no defined execution
> semantics, and ' POSTPONE EXECUTE is the equivalent of POSTPONE and
> ambiguous.

Ouch, yes. Your example is not relevant at all since neither execution
semantics nor even interpretation semantics are defined for POSTPONE.


--
Ruvim

Howerd

unread,
Jul 16, 2019, 3:32:39 AM7/16/19
to
On Tuesday, July 16, 2019 at 5:24:51 AM UTC+2, Mark William Humphries wrote:
> Le mardi 16 juillet 2019 10:48:48 UTC+8, dxforth a écrit :
> > On Monday, 15 July 2019 21:46:48 UTC+10, Alex McDonald wrote:
> > > On 15-Jul-19 02:16, dxforth wrote:
> > > > On Monday, 15 July 2019 02:54:46 UTC+10, Anton Ertl wrote:
Hi Mark,

Your approach seems very sensible - presumably the two bits are compared as part of the name search, with different bits masked out in different contexts.

This seems to be very similar to Chuck Moore's approach in colorForth - the
bottom 4 bits define a "colour", the editor, compiler and interpreter check for the relevant "colour" when deciding what to do.

Cheers,
Howerd

JennyB

unread,
Jul 16, 2019, 7:19:11 AM7/16/19
to
On Tuesday, 16 July 2019 08:29:11 UTC+1, Ruvim wrote:
> On 2019-07-15 19:33, Alex McDonald wrote:

> > What? When the text interpreter looks up <name> by using (classically)
> > FIND and gets back an XT to execute, it must be the same XT from tick;
>
> A standard Forth system may not use FIND internally at all.
> If the XT that it performs is not the same as XT from Tick, how do you
> detect this fact? You can only compare the behavior (a part of them).
> And the behavior is the same.

The xt returned by FIND must be the same as that returned by tick, unless
the word has both defined interpretation semantics and non-default
semantics, in which case FIND while compiling _may_ return an xt
representing the compiling semantics.

That is necessary because there are such systems, and have been since the
Standard was first thought of. They make it possible to POSTPONE and tick such words with predictable results. But, since there is no Standard way to define such words, it is possible that a system may define TO etc using STATE-smartness. Therefore, for portability, you should avoid ticking or POSTPONEing such words, or at least ensure that the result is only used while interpreting or compiling respectively.
>
>


> > : foo ." foo for interpreting" ;
> > : bar ." bar for compiling" ;
> > : foobar state @ if bar else foo then ; immediate
> > : barfoo postpone foobar ;
> > : test barfoo ;
> >
> >  cr foobar \ prints "foo for interpreting"
> >  cr test   \ prints "foo for interpreting"
>
> I could say that such POSTPONE has a flaw — it works incorrectly with
> the STATE-smart words. It appends execution semantics in place of
> compilation semantics. This flaw should be either documented or fixed.

It has worked correctly if you consider that, like every immediate definition, foobar has identical compilation and interpretation semantics. They just prduce different results depending on STATE.
>
>
> In the case of a classic FIND-based Forth system a correct POSTPONE can
> be defined as:
>
> : execute-compiling ( i*x xt --j*x )
> state @ if execute exit then ] execute [compile] [
> ;
> : postpone
> bl word find
> dup -1 = if drop lit, 'compile, compile, exit then
> 1 = if lit, 'execute-compiling compile, exit then
> -13 throw
> ; immediate
>
It's ugly, but it works - so long as you only use STATE-Smart words to
define dual semantics. But say someone writes FOOBAR as above, and someone
else comes along and thinks, 'That's just what I need to report STATE,
but I don't need it to be IMMEDIATE'.

So they write BARFOO, expecting it to report whether the definition it is in is executed while interpreting or compiling. It won't work as expected - it will always report that it is compiling.


> >>> Tick always returns the interpretation semantics regardless of state.
> >>
> >> By the Standard Tick always return the *execution semantics*.
> >> Not interpretation semantics. But occasionally they may coincide.
> >
> > This is not the case, since ' <name> execute is the equivalent of
> > <name>. By definition.
>
> You have missed "in interpretation state". In another state this
> equivalence may be not held.
>

If a definition has 'undefined interpretation semantics' that does not mean
that its xt can't be returned by returned by tick and EXECUTED while
interpreting - it just means that there is no sense in doing so, therefore it will not be done in a Standard Program. Any system that can properly
implement dual-semantics words may provide it's own interpretation semantics
for such words, either in the interests of pasteablity or simply to tell the user they are doing something stupid. Obviously, on such a system Tick should return the interpretation semantics that are available, and such an
xt should later execute those semantics regardless of STATE.

But for every word defined by a Standard Program (until we can agree on a way to define dual-semantics words), Tick will return the execution semantics. There is no way to distinguish in which State it is sensible to EXECUTE them.

> --
> Ruvim

Ruvim

unread,
Jul 16, 2019, 8:14:01 AM7/16/19
to
On 2019-07-16 14:19, JennyB wrote:
> On Tuesday, 16 July 2019 08:29:11 UTC+1, Ruvim wrote:
>> On 2019-07-15 19:33, Alex McDonald wrote:

[...]

>>> : foo ." foo for interpreting" ;
>>> : bar ." bar for compiling" ;
>>> : foobar state @ if bar else foo then ; immediate
>>> : barfoo postpone foobar ;
>>> : test barfoo ;
>>>
>>>  cr foobar \ prints "foo for interpreting"
>>>  cr test   \ prints "foo for interpreting"
>>
>> I could say that such POSTPONE has a flaw — it works incorrectly with
>> the STATE-smart words. It appends execution semantics in place of
>> compilation semantics. This flaw should be either documented or fixed.
>
> It has worked correctly if you consider that, like every immediate definition, > foobar has identical compilation and interpretation semantics. They
just > prduce different results depending on STATE.

It is wrong.

The compilation semantics for FOOBAR is a *behavior* that takes place
when FOOBAR name is encountered by the text interpreter in
interpretation state.

The interpretation semantics for FOOBAR is a *behavior* that takes place
when FOOBAR name is encountered by the text interpreter in compilation
state.

"identical compilation and interpretation semantics" means that the
behavior that takes place in STATE 0 is *identical* to the behavior that
takes place in STATE 1.

But "they just produce different results depending on STATE" means that
behavior that takes place in STATE 0 is *different* from the behavior
that takes place in STATE 1.

So, you contradict yourself.



>>
>> In the case of a classic FIND-based Forth system a correct POSTPONE can
>> be defined as:
>>
>> : execute-compiling ( i*x xt --j*x )
>> state @ if execute exit then ] execute [compile] [
>> ;
>> : postpone
>> bl word find
>> dup -1 = if drop lit, 'compile, compile, exit then
>> 1 = if lit, 'execute-compiling compile, exit then
>> -13 throw
>> ; immediate
>>
> It's ugly, but it works - so long as you only use STATE-Smart words to
> define dual semantics. But say someone writes FOOBAR as above, and someone
> else comes along and thinks, 'That's just what I need to report STATE,
> but I don't need it to be IMMEDIATE'.
>
> So they write BARFOO, expecting it to report whether the definition it is > in is executed while interpreting or compiling. It won't work as expected
> - it will always report that it is compiling.


Could you please elaborate a more concrete example?


[...]

--
Ruvim

Alex McDonald

unread,
Jul 16, 2019, 8:31:16 AM7/16/19
to
On 16-Jul-19 03:48, dxforth wrote:

>
> Doesn't work on DX-Forth. If your POSTPONE happens to work in interpret mode

My POSTPONE does not work in interpret mode. It throws a "-14
interpreting a compile-only word".

Everything works as it should (including the code below once I had fixed
a bug I reported way back at the top of this post), because beyond the
text interpreter there is no dependence on STATE, and there are no
STATE-smart words. That includes POSTPONE.

> in certain circumstances, good luck to you. However a standard program can't
> count on it. POSTPONE was defined as 'no interpretation' and implementers are
> entitled to assume no if's but's or maybe's.

This

: FOO POSTPONE POSTPONE ;
: PPP4 123 ;
: PPP5 [ FOO PPP4 ] ;

does *not* execute POSTPONE in interpret mode. There is no text
interpretation of POSTPONE beyond line 1 in the definition of FOO, and
hence no meaningful STATE for anything in or around the compiled
POSTPONE to inspect, since we no longer text interpret POSTPONE. FOO
executes the *compilation semantics* of POSTPONE.

This is what POSTPONE does when compiled by the text interpreter (when
STATE was -1);

Compilation: Skip leading space delimiters. Parse name delimited by a
space. Find name. Append the /compilation semantics/ of name to the
current definition.

So we append the /compilation semantics/ of POSTPONE to FOO. When FOO is
executed, it does the /compilation semantics/ shown above for POSTPONE.
Nowhere does it say in those semantics "Inspect the execution state, and
abort if interpreting (STATE is 0)".

The problem is state-smartness. I suspect your POSTPONE inspects STATE,
in which case

: POSTPONE POSTPONE POSTPONE ; IMMEDIATE

will fix this specific problem.


--
Alex

Alex McDonald

unread,
Jul 16, 2019, 8:47:34 AM7/16/19
to
On 16-Jul-19 13:13, Ruvim wrote:
> On 2019-07-16 14:19, JennyB wrote:
>> On Tuesday, 16 July 2019 08:29:11 UTC+1, Ruvim  wrote:
>>> On 2019-07-15 19:33, Alex McDonald wrote:
>
> [...]
>
>>>> : foo ." foo for interpreting" ;
>>>> : bar ." bar for compiling" ;
>>>> : foobar state @ if bar else foo then ; immediate
>>>> : barfoo postpone foobar ;
>>>> : test barfoo ;
>>>>
>>>>    cr foobar \ prints "foo for interpreting"
>>>>    cr test   \ prints "foo for interpreting"
>>>
>>> I could say that such POSTPONE has a flaw — it works incorrectly with
>>> the STATE-smart words. It appends execution semantics in place of
>>> compilation semantics. This flaw should be either documented or fixed.

There is no flaw here; your assumption and mistake is that FOOBAR has
two different semantics. It doesn't; it has only one, and to the text
interpreter, tick or POSTPONE both interpretation and compilation are
identical (not just "equivalent").

>>
>> It has worked correctly if you consider that, like every immediate
>> definition, > foobar has identical compilation and interpretation
>> semantics. They
> just > prduce different results depending on STATE.
>
> It is wrong.
>
> The compilation semantics for FOOBAR is a *behavior* that takes place
> when FOOBAR name is encountered by the text interpreter in
> interpretation state.

This I don't understand.

>
> The interpretation semantics for FOOBAR is a *behavior* that takes place
> when FOOBAR name is encountered by the text interpreter in compilation
> state.

Again, I don't understand. Both these seem to me to be the wrong way
round.

>
> "identical compilation and interpretation semantics" means that the
> behavior that takes place in STATE 0 is *identical* to the behavior that
> takes place in STATE 1. >
> But "they just produce different results depending on STATE" means that
> behavior that takes place in STATE 0 is *different* from the behavior
> that takes place in STATE 1.
>
> So, you contradict yourself.
>
>

I don't understand any of the above.

--
Alex

Ruvim

unread,
Jul 16, 2019, 8:53:25 AM7/16/19
to
On 2019-07-16 15:13, Ruvim wrote:
> On 2019-07-16 14:19, JennyB wrote:
>> On Tuesday, 16 July 2019 08:29:11 UTC+1, Ruvim  wrote:
>>> On 2019-07-15 19:33, Alex McDonald wrote:
>
> [...]
>
>>>> : foo ." foo for interpreting" ;
>>>> : bar ." bar for compiling" ;
>>>> : foobar state @ if bar else foo then ; immediate
>>>> : barfoo postpone foobar ;
>>>> : test barfoo ;
>>>>
>>>>    cr foobar \ prints "foo for interpreting"
>>>>    cr test   \ prints "foo for interpreting"
>>>
>>> I could say that such POSTPONE has a flaw — it works incorrectly with
>>> the STATE-smart words. It appends execution semantics in place of
>>> compilation semantics. This flaw should be either documented or fixed.
>>
>> It has worked correctly if you consider that, like every immediate
>> definition, foobar has identical compilation and interpretation
>> semantics. They just prduce different results depending on STATE.
>
> It is wrong.


> The compilation semantics for FOOBAR is a *behavior* that takes place
> when FOOBAR name is encountered by the text interpreter in
> interpretation state.
Misprint. The sentence begin should be read as
"The interpretation semantics"


> The interpretation semantics for FOOBAR is a *behavior* that takes place
> when FOOBAR name is encountered by the text interpreter in compilation
> state.
Misprint. The sentence begin should be read as
"The compilation semantics"

Alex McDonald

unread,
Jul 16, 2019, 8:53:56 AM7/16/19
to
On 16-Jul-19 08:29, Ruvim wrote:
> : state. state @ if ." compiling" else ." interpreting" then ;
> : foo ." foo for " state. ;
> : bar ." bar for " state. ;
> : foobar foo compiles> drop bar ;
>
> : foobar-executing ['] foobar execute ; immediate
> : foobar-compiling postpone foobar ; immediate
>
> foobar-executing ] foobar-executing [
> foobar-compiling ] foobar-compiling [

STC 32bit: 0.06.10 Build: 716
: state. state @ if ." compiling" else ." interpreting" then ;
ok
: foo cr ." foo for " state. ;
ok
: bar cr ." bar for " state. ;
ok
: foobar foo compiles> drop bar ;
ok

ok
: foobar-executing ['] foobar execute ; immediate
ok
: foobar-compiling postpone foobar ; immediate
ok

ok
foobar-executing ] foobar-executing [

foo for interpreting
foo for compiling ok
foobar-compiling ] foobar-compiling [

bar for interpreting
bar for compiling ok

I added a CR for clarity. Is that what you were expecting?




--
Alex

Ruvim

unread,
Jul 16, 2019, 9:06:15 AM7/16/19
to
On 2019-07-16 15:47, Alex McDonald wrote:
> On 16-Jul-19 13:13, Ruvim wrote:[...]
> Again, I don't understand. > Both these seem to me to be the wrong way round.
Yes, there was just a misprint, I have sent the errata.


>>
>> "identical compilation and interpretation semantics" means that the
>> behavior that takes place in STATE 0 is *identical* to the behavior
>> that takes place in STATE 1.
>>
>> But "they just produce different results depending on STATE" means
>> that behavior that takes place in STATE 0 is *different* from the
>> behavior that takes place in STATE 1.
>>
>> So, you contradict yourself.
>>
>
> I don't understand any of the above.

If you can't formulate a relevant question, — I can't help, sorry.



--
Ruvim

Alex McDonald

unread,
Jul 16, 2019, 10:00:34 AM7/16/19
to
On 16-Jul-19 08:29, Ruvim wrote:
> On 2019-07-15 19:33, Alex McDonald wrote:
>> On 15-Jul-19 16:05, Ruvim wrote:
>>> On 2019-07-15 16:18, Alex McDonald wrote:
>>>> On 15-Jul-19 13:17, Ruvim wrote:
>>
>>>>> You claim that the interpretation semantics for FOOBAR is
>>>>> STATE-depended. But how to prove it? By definition, the
>>>>> interpretation semantics of FOOBAR is a behavior that occurs when
>>>>> FOOBAR name is encountered by the text interpreter *in
>>>>> interpretation state*.
>>>>
>>>> And its XT is EXECUTEd.
>>>
>>> Actually, the Standard does not specify what XT is EXECUTed in this
>>> situation. Formally it may be another associated XT (that cannot be
>>> obtained by Tick).
>>
>> What? When the text interpreter looks up <name> by using (classically)
>> FIND and gets back an XT to execute, it must be the same XT from tick;
>
> A standard Forth system may not use FIND internally at all.

I can't see in the standard anything that states such a proscription, or
how you might derive that from it. The standard explicitly says;
http://forth-standard.org/standard/core/FIND

FIND
...

See:
3.4.2 Finding definition names

That section is in "3.4 The Forth text interpreter" .

Any reasonable reading would suggest that a system can use FIND
internally. Whatever "internally" means; most Forth programmers don't
recognize such a division. What would the system use if not FIND?

Or do you mean "may not" as in "some systems might not"?

That is true of my Forth; I use the equivalent gforth FIND-NAME which
returns an NT (name token) from which can be derived NAME>INTERPRET ( nt
-- xt ) the interpretation XT and NAME>COMP ( nt -- xt EXECUTE|COMPILE,
) a compilation token consisting of either (1) EXECUTE for IMMEDIATE
words or (2) COMPILE, to compile, the returned XT. The XT is the same
for all of NAME>INTERPRET NAME>COMPILE ' ['] and so on regardless of
state.



--
Alex

Alex McDonald

unread,
Jul 16, 2019, 10:17:51 AM7/16/19
to
That's neat; thanks for posting the link. I use a technique Anton & I
discussed here several years ago;
https://www.complang.tuwien.ac.at/forth/header-ideas.html

>
> I use the same concept.
>
> And state-smart words are so simple. He who stumbles over them has tested
> his applications not thoroughly enough.

There I agree. They should be avoided at all costs; STATE is an abomination.

>
> He who takes every grain of wording in the Standard document biblically
> fundamentally and thus complicates the whole compiler has lost the spirit
> of 'make it simple' in Forth.
>

Only gforth takes that approach; but that's because it is explicit in
its goals. Having such a benchmark is important for a standard, and
helps refine it.

As to spirit; the traditional "make it simple" text interpreter loop
looks simple, but underneath its placid surface is a deep and cold lake
of despond. Dual words and recognizers are a huge simplification for the
programmer, for no more than a few lines of code from the system developer.


--
Alex

Ruvim

unread,
Jul 16, 2019, 12:10:41 PM7/16/19
to
On 2019-07-16 17:00, Alex McDonald wrote:
> On 16-Jul-19 08:29, Ruvim wrote:
[...]
>> A standard Forth system may not use FIND internally at all.
>
> I can't see in the standard anything that states such a proscription, or
> how you might derive that from it. The standard explicitly says; > http://forth-standard.org/standard/core/FIND
>
> FIND
> ....
>
> See:
> 3.4.2 Finding definition names
>
> That section is in "3.4 The Forth text interpreter" .
> > Any reasonable reading would suggest that a system can use FIND
> internally. Whatever "internally" means; most Forth programmers don't
> recognize such a division. What would the system use if not FIND?
>
> Or do you mean "may not" as in "some systems might not"?


Yes, "they may not use it" is in the sense "they are allowed to not use
it", or "they are not obligated to use it".

It seems I used an unsuitable grammatical form. Thanks for pointing out.


> That is true of my Forth; I use the equivalent gforth FIND-NAME which
> returns an NT (name token) from which can be derived NAME>INTERPRET ( nt
> -- xt ) the interpretation XT and NAME>COMP ( nt -- xt EXECUTE|COMPILE,
> ) a compilation token consisting of either (1) EXECUTE for IMMEDIATE
> words or (2) COMPILE, to compile, the returned XT. The XT is the same
> for all of NAME>INTERPRET NAME>COMPILE ' ['] and so on regardless of state.


If you want an example of different XTs — a Forth system may use
additional JIT compiler and use its result internally, but does not
expose this internal XT since it is ephemeral. So, the XT returned by
Tick is different from XT that is executed when a name is encountered by
the text interpreter in interpretation state. But you cannot detect it.


--
Ruvim

Mark William Humphries

unread,
Jul 16, 2019, 11:03:56 PM7/16/19
to
Hi Howerd,

Yes, exactly. The interpreter is interested in definitions that have their interpretation bit set, and the compiler is interested in definitions that have their compilation bit set.

: interpreter ( -- ? ) ... interpretation lookup ... ;

: compiler ( -- ? ) ... compilation lookup ... ;

Typical definitions have both their interpretation and compilation bits set, but a compile-only definition for example would not have its interpretation bit set.

> This seems to be very similar to Chuck Moore's approach in colorForth - the
> bottom 4 bits define a "colour", the editor, compiler and interpreter check for the relevant "colour" when deciding what to do.

Absolutely, it's the same general idea. I'm explicitly tagging a definition's relevance to the interpreter and the compiler. Doing so leads to a clean factoring of the compiler, interpreter, and outer-interpreter, makes "special" behaviors trivial, makes STATE redundant, and simplifies some other things as well.

> Cheers,
> Howerd

Cheers,
Mark



dxforth

unread,
Jul 17, 2019, 12:30:16 AM7/17/19
to
On Tuesday, 16 July 2019 22:31:16 UTC+10, Alex McDonald wrote:
> On 16-Jul-19 03:48, dxforth wrote:
>
> >
> > Doesn't work on DX-Forth. If your POSTPONE happens to work in interpret mode
>
> My POSTPONE does not work in interpret mode. It throws a "-14
> interpreting a compile-only word".
>
> Everything works as it should (including the code below once I had fixed
> a bug I reported way back at the top of this post), because beyond the
> text interpreter there is no dependence on STATE, and there are no
> STATE-smart words. That includes POSTPONE.
>
> > in certain circumstances, good luck to you. However a standard program can't
> > count on it. POSTPONE was defined as 'no interpretation' and implementers are
> > entitled to assume no if's but's or maybe's.
>
> This
>
> : FOO POSTPONE POSTPONE ;
> : PPP4 123 ;
> : PPP5 [ FOO PPP4 ] ;
>
> does *not* execute POSTPONE in interpret mode.

That's a matter of interpretation.

> There is no text
> interpretation of POSTPONE beyond line 1 in the definition of FOO, and
> hence no meaningful STATE for anything in or around the compiled
> POSTPONE to inspect, since we no longer text interpret POSTPONE. FOO
> executes the *compilation semantics* of POSTPONE.

STATE is meaningful when POSTPONE uses COMPILE and the latter
incorporates a STATE check which it is entitled to do.

>
> This is what POSTPONE does when compiled by the text interpreter (when
> STATE was -1);
>
> Compilation: Skip leading space delimiters. Parse name delimited by a
> space. Find name. Append the /compilation semantics/ of name to the
> current definition.
>
> So we append the /compilation semantics/ of POSTPONE to FOO. When FOO is
> executed, it does the /compilation semantics/ shown above for POSTPONE.
> Nowhere does it say in those semantics "Inspect the execution state, and
> abort if interpreting (STATE is 0)".
>
> The problem is state-smartness. I suspect your POSTPONE inspects STATE,
> in which case
>
> : POSTPONE POSTPONE POSTPONE ; IMMEDIATE
>
> will fix this specific problem.

Then let Anton put it in a standard program if he wants his code to
work (for some systems anyway).

>
>
> --
> Alex

hughag...@gmail.com

unread,
Jul 17, 2019, 1:35:37 AM7/17/19
to
Pretty much everything that Alex McDonald says is wrong!

On Monday, July 15, 2019 at 3:47:45 AM UTC-7, Alex McDonald wrote:
> Hugh's disambugifiers (and here I guess what his IF looks like)
>
> : IF state @ 0= if
> ." warning IF is undefined in interpretation state"
> else postpone if then ; immediate
>
> illustrate the problem. This would fail to run the above, because (like
> many state-smart words) they conflate run time and text interpretation
> time. They're two different things.

Alex McDonald is lying. This is my disambiguifier:
---------------------------------------------------------------------
: if
state @ 0= if
cr ." WARNING: *** no interpretation semantics for: IF ***" cr
then
postpone if ;
immediate
---------------------------------------------------------------------

I have seen this happen many times previously.
An ANS-Forth cult member will post non-working code,
and claim that it is my code --- a typical troll attack.

> On Hugh's meta-compilation point and your counter point, I'm surprised
> that you would claim it's not possible to write an meta-compiler without
> a POSTPONE that works inside [ ] (much like Hugh's claim that you can't
> do it without a vectored LITERAL), but that it's OK because it's "not
> essential". Systems like mine and Win32Forth are testament to the
> capability of ANS Forths and their authors to write meta-compilers
> without POSTPONEs that work as you describe.

Forth is not really Forth without literal numbers,
so supporting literal numbers in a cross-compiler is "essential."
It is possible to work around Elizabeth Rather's incompetence
by doing this: : xxx ... [ 12345 ] literal ... ;
instead of: : xxx ... 12345 ... ;
Bizarre work-arounds such as this aren't a
"testament to the capability of ANS-Forths and their authors."
Alex McDonald is just brown-nosing Elizabeth Rather.
This is crap code --- typical for ANS-Forth.
This is the same crap code that Forth-83 required.
Note that Charles Moore left Forth Inc. in 1982, so Forth-83
is the fault of Elizabeth Rather, as was ANS-Forth in 1994.

Here is more bullshit from Alex McDonald:

On Monday, July 15, 2019 at 9:34:00 AM UTC-7, Alex McDonald wrote:
> On 15-Jul-19 16:05, Ruvim wrote:
> > On 2019-07-15 16:18, Alex McDonald wrote:
> >> On 15-Jul-19 13:17, Ruvim wrote:
>
> >>> You claim that the interpretation semantics for FOOBAR is
> >>> STATE-depended. But how to prove it? By definition, the
> >>> interpretation semantics of FOOBAR is a behavior that occurs when
> >>> FOOBAR name is encountered by the text interpreter *in interpretation
> >>> state*.
> >>
> >> And its XT is EXECUTEd.
> >
> > Actually, the Standard does not specify what XT is EXECUTed in this
> > situation. Formally it may be another associated XT (that cannot be
> > obtained by Tick).
>
> What? When the text interpreter looks up <name> by using (classically)
> FIND and gets back an XT to execute, it must be the same XT from tick; '
> <name> execute is the equivalent of the interpretation semantics *by
> definition*.

The ANS-Forth documentation for FIND (6.1.1550) says:
"For a given string, the values returned by FIND while compiling
may differ from those returned while not compiling."
Tick executes at compile-time, so it is only guaranteed to provide
the same xt as FIND provides if FIND executes at compile-time
(interpretive mode) which is the interpretation semantics
("semantics" is Elizabeth Rather's goofy term for action or behavior).
If FIND is executed at run-time, it might return a different xt.
Alex McDonald way lying when he said that FIND and tick "must"
provide the same xt.

In my experience, this weird nonsense only happens when FIND is
used on the 50 some words in ANS-Forth (such as IF etc.) that say:
"Interpretation semantics for this word are undefined."
This isn't guaranteed by the ANS-Forth document, as this weird
nonsense may theoretically happen for any word.
Assuming that this weird nonsense only happens for these problematic
words, my disambiguifiers fix the broken behavior of FIND on them.
My disambiguifiers make all of these words immediate, and allow FIND
to find them and to provide only one xt for each of them.
According to the ANS-Forth section 4.1.2 "Ambiguous Conditions"),
one particularly disturbing ambiguous condition is:
"attempting to obtain the execution token,
(e.g., with 6.1.0070 ', 6.1.1550 FIND, etc.)
of a definition with undefined interpretation semantics"
Effectively FIND and tick etc. can't be used to obtain an xt of
words such as IF etc.. My disambiguifiers fix this bug in ANS-Forth
so FIND does work on IF etc. and it works in a consistent manner.

On Tuesday, July 16, 2019 at 5:31:16 AM UTC-7, Alex McDonald wrote:
> This
>
> : FOO POSTPONE POSTPONE ;
> : PPP4 123 ;
> : PPP5 [ FOO PPP4 ] ;
>
> does *not* execute POSTPONE in interpret mode. There is no text
> interpretation of POSTPONE beyond line 1 in the definition of FOO, and
> hence no meaningful STATE for anything in or around the compiled
> POSTPONE to inspect, since we no longer text interpret POSTPONE. FOO
> executes the *compilation semantics* of POSTPONE.
>
> This is what POSTPONE does when compiled by the text interpreter (when
> STATE was -1);
>
> Compilation: Skip leading space delimiters. Parse name delimited by a
> space. Find name. Append the /compilation semantics/ of name to the
> current definition.
>
> So we append the /compilation semantics/ of POSTPONE to FOO. When FOO is
> executed, it does the /compilation semantics/ shown above for POSTPONE.
> Nowhere does it say in those semantics "Inspect the execution state, and
> abort if interpreting (STATE is 0)".
>
> The problem is state-smartness. I suspect your POSTPONE inspects STATE,
> in which case
>
> : POSTPONE POSTPONE POSTPONE ; IMMEDIATE
>
> will fix this specific problem.

LOL Getting rid of the warning message (or abort with error message)
doesn't actually fix the problem.
This reminds me of one time when I was quite young and working as a
dishwasher. We ran out of dish-washing soap! Ruh-roh!
My solution was to tape a wet paper-towel over the warning bell so
I wouldn't have to listen to that annoying beeping all day long.

Alex McDonald is a total bullshitter! He says:

On Tuesday, July 16, 2019 at 5:31:16 AM UTC-7, Alex McDonald wrote:
> This
>
> : FOO POSTPONE POSTPONE ;
> : PPP4 123 ;
> : PPP5 [ FOO PPP4 ] ;
>
> does *not* execute POSTPONE in interpret mode.

When does the POSTPONE of PPP4 happen?
It happens inside of [ ... ] brackets which is interpret mode!

Alex McDonald says:

> The problem is state-smartness. I suspect your POSTPONE inspects STATE,
> in which case
>
> : POSTPONE POSTPONE POSTPONE ; IMMEDIATE
>
> will fix this specific problem.

This is essentially a disambiguifier without a warning. I have:
------------------------------------------------------------------------
: postpone
state @ 0= if
cr ." WARNING: *** no interpretation semantics for: POSTPONE ***" cr
then
postpone postpone ;
immediate
------------------------------------------------------------------------

So, lets see what happens when the disambiguifier is used:
------------------------------------------------------------------------
: FOO POSTPONE POSTPONE ; ok
: PPP4 123 ; ok
: PPP5 [ FOO PPP4 ] ;
WARNING: *** no interpretation semantics for: POSTPONE ***
ok
------------------------------------------------------------------------

This warning occurs because the POSTPONE of PPP4 is happening
inside of the [ ... ] brackets which is interpret mode. Duh!

Notice that Alex McDonald the mystic has written FOO as:
FOO POSTPONE POSTPONE ;
and he has written POSTPONE as:
: POSTPONE POSTPONE POSTPONE ; IMMEDIATE
Notice the similarity? These are the same thing!
POSTPONE is immediate and FOO is not, but FOO is being run
inside of [ ... ] brackets so it executes at compile-time
just like an immediate word inside of a colon word.
Alex McDonald the mystic believes that piling these
definitions on top of each other magically causes POSTPONE
to not execute in interpret mode.
This is like saying: "Its turtles all the way down!"
This isn't true though. POSTPONE ends up executing in interpret mode
no matter how many levels are piled on top of each other.
Similarly, the bottom turtle doesn't have anything to stand on...

In summary --- essentially nothing that Alex McDonald says
about ANS-Forth is true. He is an idiot or a liar, or both.

I think that Anton Ertl and Alex McDonald are doing a lot of
hand-waving for the purpose of confusing everybody.
The purpose of this obfuscation is that Anton Ertl wants to
use compiling words such as POSTPONE IF ELSE THEN etc.
inside of [ ... ] brackets (which makes sense), but he also
wants to claim that this is ANS-Forth (he is lying about this).
All of this pseudo-intellectual blather may very well confuse
Forthers with less than a year of experience in Forth.
They will decide that Anton Ertl and Alex McDonald are big
Forth experts and that the whole question is above their
training level, so they will just believe the big experts.
They won't realize that Anton Ertl and Alex McDonald are liars.
I've got about 1/4 century of experience with Forth though,
so the liars aren't going to fool me quite so easily!

Ruvim

unread,
Jul 17, 2019, 7:13:48 AM7/17/19
to
Yes, it is what I expected.

But I don't sure that it is quite correctly. The behavior of
FOOBAR-COMPILING should not depend on the state (since POSTPONE
should guarantee it), but it does depend.

Perhaps, it is enough to document this detail: that your implementation
of POSTPONE does not guarantee that only compilation semantics of a word
is appended if a STATE depended code was used to define this word.


Also, it is incorrectly to say that "['] foobar" returns xt that
represents the interpretation semantics of foobar (in general case),
since interpretation semantics should not depend on the state,
but the behavior that this xt represents can depend.

For clarity: an execution token represents some interpretation semantics
if the execution semantics identified by the token is identical to this
interpretation semantics.


The examples of a standard word that has well defined execution
semantics that depends on STATE are: EVALUATE, INCLUDED.



--
Ruvim

Alex McDonald

unread,
Jul 17, 2019, 9:23:05 AM7/17/19
to
I've struggled over a number of posts to you and dxforth to point out
that the value of STATE when the compilation semantics are being
/compiled/ is important; but that the value of STATE when those
semantics are /executed/ is immaterial. This is my last effort.

FOOBAR-COMPILING prints "bar for ..." in each case; and BAR is only
reachable through the compilation semantics of FOOBAR while compiling
it. It just happens to print the value of STATE when the compilation
semantics are later executed.

>
> Perhaps, it is enough to document this detail: that your implementation
> of POSTPONE does not guarantee that only compilation semantics of a word
> is appended if a STATE depended code was used to define this word.

Since my POSTPONE has done exactly as the standard demands (added the
/compilation semantics/ i.e. BAR, to the current definition, and as the
test demonstrates that's exactly what it's doing) regardless of the
run-time value of STATE, I can't see how misdescribing it will help.

I made exactly this mistake re STATE in my implementation of POSTPONE
(see the first few posts in this thread). Perhaps reading Anton Ertl's
description carefully and having a system that I can play with at a
fundamental level helps, but it became pretty clear pretty quickly that
my understanding and therefore implementation was wrong.

If you keep insisting that there's something special about POSTPONE and
STATE, then you should have significant issues with this test.

: PIF1 POSTPONE IF ;
: PIF2 POSTPONE IF ; IMMEDIATE

: USE1 [ PIF1 ] TRUE THEN ;
: USE2 PIF2 TRUE THEN ;

When PIF1 and PIF2 were compiled, the state was compilation; hence the
compilation semantics of IF are appended to both PIF1 and PIF2.

The only difference between USE1 and USE2 is nothing. Zippo. They both
do the same thing, at the same place. Except for STATE, but PIF1 and
PIF2 don't care; /they're already compiled, and POSTPONE compiled the
compilation semantics of IF/. Nothing is referring to or using STATE in
any of the above.

In case you think my IF is "state smart" and does something hokey in
interpretation state;

if
^^
Error -14 in (console): if is compilation only

The same argument holds for POSTPONE POSTPONE.




>
>
> Also, it is incorrectly to say that "['] foobar" returns xt that
> represents the interpretation semantics of foobar (in general case),
> since interpretation semantics should not depend on the state,
> but the behavior that this xt represents can depend.
>
> For clarity: an execution token represents some interpretation semantics
> if the execution semantics identified by the token is identical to this
> interpretation semantics.

That is not clear at all; I struggle to understand what you're saying.

>
>
> The examples of a standard word that has well defined execution
> semantics that depends on STATE are: EVALUATE, INCLUDED.

EVALUATE doesn't do anything to STATE, and it doesn't care. When it's
executed it uses the text interpreter to process a string, and what
happens to STATE depends on what it interprets from that string.

I'm not sure what you mean with INCLUDED.


--
Alex

hughag...@gmail.com

unread,
Jul 17, 2019, 9:29:50 AM7/17/19
to
On Monday, July 15, 2019 at 9:34:00 AM UTC-7, Alex McDonald wrote:
> : bar postpone dup ;
> : test [ bar ] ;
>
> The POSTPONE has been compiled. It is the compilation semantics of
> POSTPONE that BAR is executing. The state is immaterial.

Alex McDonald is lying again!
It is illegal in in ANS-Forth (and "ambiguous condition" in
Elizabeth Rather's goofy terminology) to use compiling words
inside of [ ... ] brackets. BAR is a compiling word.

Lets try this:
------------------------------------------------------------------
forget bar ok
: bar postpone dup ; ok
: test [ bar ] ; ok

see bar
BAR
( 004FBAF0 8D6DFC ) LEA EBP, [EBP+-04]
( 004FBAF3 895D00 ) MOV [EBP], EBX
( 004FBAF6 BB44804000 ) MOV EBX, 00408044
( 004FBAFB E8504AF1FF ) CALL 00410550 COMPILE,
( 004FBB00 C3 ) NEXT,
( 17 bytes, 5 instructions )
ok

see test
TEST
( 004FBB20 8D6DFC ) LEA EBP, [EBP+-04]
( 004FBB23 895D00 ) MOV [EBP], EBX
( 004FBB26 C3 ) NEXT,
( 7 bytes, 3 instructions )
ok
------------------------------------------------------------------

BAR is using COMPILE, internally.
ANS-Forth documentation for COMPILE, (section 6.2.0945) says:
"Interpretation semantics for this word are undefined."

I have my disambiguifiers installed.
Why didn't my warning message come up when BAR executed inside
of [ ... ] which is illegal?
This is because POSTPONE was written before my disambiguifiers
were installed ( POSTPONE is part of VFX) so it is using the
original COMPILE, ( COMPILE, is part of VFX) rather than the
disambiguified COMPILE, that I provided.

The fact that no warning message came up does not mean that
BAR and TEST are ANS-Forth code. They aren't.
This is non-standard code that relies on compiling words working
correctly inside of [ ... ] brackets, which was explicitly
forbidden in ANS-Forth.

If Elizabeth Rather knew anything about meta-compiling, she would
have allowed compiling words to be used inside of [ ... ] brackets.
She doesn't know anything about meta-compiling though,
and so she explicitly forbade doing this.
This is a bug in ANS-Forth.

BTW: Alex McDonald is doing a great job of supporting Anton Ertl,
telling one preposterous lie after another!
Why is Anton Ertl making himself so scarce?
I would expect that Anton Ertl would want to join in, telling lies too.
Could it be that Anton Ertl has suddenly become ashamed of lying???
He now wants to leave Alex McDonald holding the bag.

Alex McDonald

unread,
Jul 17, 2019, 9:34:20 AM7/17/19
to
On 17-Jul-19 05:30, dxforth wrote:
>> This
>>
>> : FOO POSTPONE POSTPONE ;
>> : PPP4 123 ;
>> : PPP5 [ FOO PPP4 ] ;
>>
>> does*not* execute POSTPONE in interpret mode.
> That's a matter of interpretation.
>

Sloppy wording of mine. Better would be:

"does not execute the interpretation semantics of POSTPONE, regardless
of state".

--
Alex

hughag...@gmail.com

unread,
Jul 17, 2019, 9:35:30 AM7/17/19
to
On Wednesday, July 17, 2019 at 6:23:05 AM UTC-7, Alex McDonald wrote:
> If you keep insisting that there's something special about POSTPONE and
> STATE, then you should have significant issues with this test.
>
> : PIF1 POSTPONE IF ;
> : PIF2 POSTPONE IF ; IMMEDIATE
>
> : USE1 [ PIF1 ] TRUE THEN ;
> : USE2 PIF2 TRUE THEN ;
>
> When PIF1 and PIF2 were compiled, the state was compilation; hence the
> compilation semantics of IF are appended to both PIF1 and PIF2.
>
> The only difference between USE1 and USE2 is nothing. Zippo. They both
> do the same thing, at the same place. Except for STATE, but PIF1 and
> PIF2 don't care; /they're already compiled, and POSTPONE compiled the
> compilation semantics of IF/. Nothing is referring to or using STATE in
> any of the above.

Alex McDonald continues telling the same lie over and over again,
hoping that somebody will believe him!
---------------------------------------------------------------------
: PIF1 POSTPONE IF ; ok
: PIF2 POSTPONE IF ; IMMEDIATE ok
ok
: USE1 [ PIF1 ] TRUE THEN ;
WARNING: *** no interpretation semantics for: IF ***
ok
: USE2 PIF2 TRUE THEN ; ok
---------------------------------------------------------------------

USE1 is not ANS-Forth because it is executing IF inside of
[ ... ] brackets in a colon word.
Executing compiling words in interpret mode was explicitly
banned by Elizabeth Rather in her ANS-Forth.
Alex McDonald's lies don't change the fact that ANS-Forth has this bug.

Ruvim

unread,
Jul 17, 2019, 9:58:32 AM7/17/19
to
On 2019-07-17 16:22, Alex McDonald wrote:
[...]
> If you keep insisting that there's something special about POSTPONE and
> STATE, then you should have significant issues with this test.
>
> : PIF1 POSTPONE IF ;
> : PIF2 POSTPONE IF ; IMMEDIATE
>
> : USE1 [ PIF1 ] TRUE THEN ;
> : USE2 PIF2 TRUE THEN ;


There is no any issue with this test.
This test just is irrelevant to the problem I talking about.


: [T] S" 123 . " EVALUATE ; IMMEDIATE

What is the compilation semantics of [T]?

Alex McDonald

unread,
Jul 17, 2019, 9:59:53 AM7/17/19
to
State smart words which have different actions depending on whether they
are invoked in interpretation or compilation state, were largely
eliminated in Forth-83. Yet here you are, reintroducing them some 35+
years later.

Your replacement for IF (which you haven't shown in the code above) is
"state-smart", hence the erroneous warning message. It has only one
action, regardless of interpretation or compilation state.

ANS doesn't ban executing compiling words in interpret mode; it says
that some words (like IF) have no defined interpretation semantics. But
since the above code doesn't need to use the interpretation semantics,
then it's not a problem.

--
Alex

Alex McDonald

unread,
Jul 17, 2019, 10:17:46 AM7/17/19
to
To execute [T]. Using my system to find out how;

: [T] S" 123 . " EVALUATE ; IMMEDIATE
ok
"[t]" find-name name>interpret dup $. .name
$41B13A [t] ok
"[t]" find-name name>compile dup $. .name cr dup $. .name
$401039 execute
$41B13A [t] ok

For non-immediate words;

"dup" find-name name>interpret dup $. .name
$401120 dup ok
"dup" find-name name>compile dup $. .name cr dup $. .name
$402888 compile,
$401120 dup ok

The interpreter executes the result from NAME>xxx so either (all shown
in stack order) it does interpretation followed by compilation state;

' [T]
' [T] ' EXECUTE

That EXECUTE is because the word is IMMEDIATE. For non-immediate words
with default compilation semantics:

' DUP
' DUP ' COMPILE,

Straight COMPILE, since not IMMEDIATE.

I'm not sure where you're going with this; the EVALUATE looks like it
might be important?

--
Alex

Ruvim

unread,
Jul 17, 2019, 10:36:14 AM7/17/19
to
On 2019-07-17 17:17, Alex McDonald wrote:
> On 17-Jul-19 14:58, Ruvim wrote:
>> On 2019-07-17 16:22, Alex McDonald wrote:
[...]
>> There is no any issue with this test.
>> This test just is irrelevant to the problem I talking about.
>>
>>
>> : [T] S" 123 . " EVALUATE ; IMMEDIATE
>>
>> What is the compilation semantics of [T]?
>>
>
> To execute [T].

And what namely behavior takes place at that?
Or, in other words, what effects are produced?

Semantics does not talk about what xt, but about what is happening.

Alex McDonald

unread,
Jul 17, 2019, 11:13:10 AM7/17/19
to
This is a very long rabbit hole. What is it you are trying to
demonstrate please?

When processed by the text interpreter, the semantics of [T]
(compilation or interpretation) is to print 123 at the console.

(I'd point out that S" has no interpretation semantics, but that's OK,
because S" is compiled, not interpreted, in [T].)

--
Alex

Ruvim

unread,
Jul 17, 2019, 11:25:48 AM7/17/19
to
On 2019-07-17 18:13, Alex McDonald wrote:
> On 17-Jul-19 15:36, Ruvim wrote:
>> On 2019-07-17 17:17, Alex McDonald wrote:
>>> On 17-Jul-19 14:58, Ruvim wrote:
>>>>
>>>> : [T] S" 123 . " EVALUATE ; IMMEDIATE
>>>>
>>>> What is the compilation semantics of [T]?
>>>>
>>>
>>> To execute [T].
>>
>> And what namely behavior takes place at that?
>> Or, in other words, what effects are produced?
>>
>> Semantics does not talk about what xt, but about what is happening.
>>
>
> This is a very long rabbit hole. What is it you are trying to
> demonstrate please?

Terminology of the standard, meaning of some terms, and a hole with POSTPONE


> When processed by the text interpreter, the semantics of [T]
> (compilation or interpretation) is to print 123 at the console.

Not quite. Please try:

: test [T] ;

In this example "[T]" has been encountered by the text interpreter. And
what side effects have produced after that? What behavior has taken place?



>
> (I'd point out that S" has no interpretation semantics, but that's OK,
> because S" is compiled, not interpreted, in [T].)
>

There are two versions of S"
The version from CORE does not have interpretation semantics, the
version from FILE does have.

Alex McDonald

unread,
Jul 17, 2019, 11:44:37 AM7/17/19
to
On 17-Jul-19 16:25, Ruvim wrote:

>
> Not quite. Please try:
>
> : test [T] ;
>
> In this example "[T]" has been encountered by the text interpreter. And
> what side effects have produced after that? What behavior has taken place?

Oh, I see, apologies; I ran it in my head (never a good thing to do).
Yes, the 123 . gets compiled into TEST, as the state is compilation in TEST.

But please, where are you going with this? I'm getting a tad bored by
the back&fore of this very long lesson. Make your point & be done with it.


--
Alex

Ruvim

unread,
Jul 17, 2019, 12:17:29 PM7/17/19
to
On 2019-07-17 18:44, Alex McDonald wrote:
> On 17-Jul-19 16:25, Ruvim wrote:
>
>>
>> Not quite. Please try:
>>
>> : test [T] ;
>>
>> In this example "[T]" has been encountered by the text interpreter.
>> And what side effects have produced after that? What behavior has
>> taken place?
>
> Oh, I see, apologies; I ran it in my head (never a good thing to do).
> Yes, the 123 . gets compiled into TEST, as the state is compilation in
> TEST.
>


Hence, the compilation semantics of [T] is to append "123 ." (printing
123) into the current definition.
NB: compilation semantics is behavior. Not xt.


Now, let's try to append this compilation semantics to the new definition T

: T POSTPONE [T] ;


And then try to perform this compilation semantics:

: test2 [ T ] ;

So, the code "123 ." should be appended into test2.


test2 \ should print 123


Using your implementation of POSTPONE, the word test2 will print nothing.

Using my implementation of POSTPONE, the word test2 will print 123.


There are only three options:
- my implementation behaves incorrectly
- your implementation behaves incorrectly
- it is an ambiguous condition.

What do you think?


> But please, where are you going with this? I'm getting a tad bored by
> the back&fore of this very long lesson. Make your point & be done with it.

Hope, I have made my point.

Anton Ertl

unread,
Jul 17, 2019, 1:05:24 PM7/17/19
to
dxforth <dxf...@gmail.com> writes:
>On Monday, 15 July 2019 02:54:46 UTC+10, Anton Ertl wrote:
>> dxforth <dxf...@gmail.com> writes:
>> >On Monday, 15 July 2019 00:52:42 UTC+10, Alex McDonald wrote:
>> >> On 14-Jul-19 11:54, dxforth wrote:
>> >> > On Sunday, 14 July 2019 10:00:01 UTC+10, Alex McDonald wrote:
>> >> >> There's a difference. Although POSTPONE has undefined interpretation
>> >> >> semantics, POSTPONE-POSTPONE has well defined interpretation semantics,
>> >> >> which is to execute the *compilation* semantics of POSTPONE.
>> >> >
>> >> > That's akin to the tail wagging the dog - using ANS terminology to
>> >> > claim an entitlement for POSTPONE that ANS never explicitly gave.
>> ...
>> >I'm saying ANS was in the business of including existing systems and
>> >any interpretation that suddenly excludes them should be viewed with
>> >suspicion.
>>
>> When I run the following code on Gforth 0.7.2, SwiftForth 3.6.3, and
>> VFX 4.72, they all work as required by the standard.
>>
>> : POSTPONE-POSTPONE
>> POSTPONE POSTPONE ;
>>
>> : PPP1 123 ;
>> : PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
>> : PPP5 PPP4 ;
>> PPP5 . \ prints 123
>>
>> - anton
>
>Your interpretation of what a several decades old standard
>requires is based on the behaviour of three modern systems?

Well, if you look at pre-Forth-94 systems, they did not have POSTPONE,
so one cannot use these systems to interpret it.

And Forth-94 explicitly excluded systems like polyForth that had a
separate compiler loop rather than a common text interpreter for
interpretation and compilation.

>A solution for POSTPONE that didn't include threaded code
>systems and classical COMPILE wasn't an option for ANS.

COMPILE is not included in Forth-94, so not including it obviously was
an option. As for threaded code, there is nothing in the code above
that's incompatible with threaded code; the easiest way to see this is
by testing it with gforth-itc (indirect threaded code variant of
Gforth rather than the more optimized variant that the gforth and
gforth-fast engines use). The code above also works with
gforth-0.2.1, which is a pretty classic threaded code implementation.

- 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 2019: http://euro.theforth.net/

Anton Ertl

unread,
Jul 17, 2019, 1:07:56 PM7/17/19
to
Alex McDonald <al...@rivadpm.com> writes:
>gforth predates ANS.

Not really. We started it in the later stages of the Forth-94 effort,
with the intention of it becoming to ANS Forth as F83 was to Forth-83.

Anton Ertl

unread,
Jul 17, 2019, 1:31:11 PM7/17/19
to
Ruvim <ruvim...@gmail.com> writes:
>On 2019-07-15 12:06, Anton Ertl wrote:
>> Ruvim <ruvim...@gmail.com> writes:
>>> execution semantics:
>>> The *behavior* of a Forth definition when it is executed.
>>>
>>> interpretation semantics:
>>> The *behavior* of a Forth definition when its *name is encountered*
>>> by the text interpreter in interpretation state.
>>>
>>> Unless otherwise specified in an "Interpretation:" section of
>>> the glossary entry, the interpretation semantics of a Forth
>>> definition are its execution semantics.
>>>
>>> compilation semantics:
>>> The *behavior* of a Forth definition when its *name is encountered*
>>> by the text interpreter in compilation state.
>>>
>>> Unless otherwise specified in a "Compilation:" section of
>>> the glossary entry, the compilation semantics of a Forth definition
>>> shall be to append its execution semantics to the execution
>>> semantics of the current definition.
>> [...]
>>> Let's consider an example.
>>>
>>> : foo ." foo for interpreting" ;
>>> : bar ." bar for compiling" ;
>>> : foobar state @ if bar else foo then ; immediate
>>>
>>> So, for foobar word:
>>> Interpretation semantics: to print "foo for interpreting"
>>> Compilation semantics: to print "bar for compiling" (due to immediacy)
>>> Execution semantics: to print one or another depending on the STATE.
>>
>> Not quite:
>>
>> You got the execution semantics right.
>>
>> FOOBAR has default interpretation semantics, i.e., the same
>> STATE-dependent semantics as the execution semantics.
>>
>> FOOBAR has immediate compilation semantics, i.e., the same
>> STATE-dependent semantics as the execution and interpretation
>> semantics.
>
>
>It's a delicate moment. And since the Standard is not quite clear in
>this, it seems that different interpretations may have place.
>
>
>You claim that the interpretation semantics for FOOBAR is
>STATE-depended. But how to prove it?

It follows from the definition of interpretation semantics for
user-defined words:

|3.4.3.2 Interpretation semantics
|
|Unless otherwise specified in an "Interpretation:" section of the
|glossary entry, the interpretation semantics of a Forth definition are
|its execution semantics.

>By definition, the interpretation
>semantics of FOOBAR is a behavior that occurs when FOOBAR name is
>encountered by the text interpreter *in interpretation state*.

That sentence from the definition of terms does not tell you what the
interpretation semantics of a specific word are. It's useful to
understand how the interpretation semantics can be used (and may
therefore be useful in the definition of terms), but not more.

>We can't demonstrate another behavior in another state, since
>in another state it will be not interpretation semantics.

If you want a demonstration:

: [execute] execute ; immediate
: foo ." foo for interpreting" ;
: bar ." bar for compiling" ;
: foobar state @ if bar else foo then ; immediate
s" foobar" find-name name>interpret ] [execute] [

prints "bar for compiling".

In Forth-94, we can write

' foobar ] [execute] [

with the same result, but that hinges on the question of whether '
produces an xt representing interpretation of execution semantics,
which I will discuss below.

>The same regarding compilation semantics.

This is even easier to demonstrate:

: bar postpone foobar ; immediate
bar

prints "foo for interpreting".

>The Standard does not provide a special mechanism to perform the
>interpretation semantics of a word in compile state.

NAME>COMPILE EXECUTE can be performed in any state.

>Tick return an execution token that, by definition, identifies the
>*execution semantics*.
>
>6.1.2510 [']
> ... Place name's *execution token* xt on the stack.
>
>6.1.0070 '
> ... return xt, the *execution token* for name.
>
>The illustration:
> "When interpreting, ' xyz EXECUTE is equivalent to xyz "
>
>— means that performing execution semantics of a word in interpretation
>state has the exactly same effect as performing its interpretation
>semantics.

Consider

' s" execute bla"

S" has no execution semantics, but this is equivalent to

s" bla"

when interpreting. So ' s" produces an xt representing the
interpretation semantics.

>> or the compilation semantics in interpret state.
>
>Properly implemented POSTPONE formally allows to do it.
>
>But actually, compilation semantics cannot detect 0 value in STATE. So,
>you think that you perform it in interpretation state, but it "thinks"
>that it is performed in compilation state.

I demonstrated above how to do it.

>Regarding the word S" — the standard does not specify execution
>semantics for it. So, an ambiguous condition exist if tick (' or ['])
>is applied to this word. And it is the same for other words with
>undefined execution semantics.

Where can I find this ambiguous condition?

Alex McDonald

unread,
Jul 17, 2019, 1:46:47 PM7/17/19
to
On 17-Jul-19 17:17, Ruvim wrote:
> On 2019-07-17 18:44, Alex McDonald wrote:
>> On 17-Jul-19 16:25, Ruvim wrote:
>>
>>>
>>> Not quite. Please try:
>>>
>>> : test [T] ;
>>>
>>> In this example "[T]" has been encountered by the text interpreter.
>>> And what side effects have produced after that? What behavior has
>>> taken place?
>>
>> Oh, I see, apologies; I ran it in my head (never a good thing to do).
>> Yes, the 123 . gets compiled into TEST, as the state is compilation in
>> TEST.
>>
>
>
> Hence, the compilation semantics of [T] is to append "123 ." (printing
> 123) into the current definition.
> NB: compilation semantics is behavior. Not xt.
>
>
> Now, let's try to append this compilation semantics to the new definition T
>
> : T POSTPONE [T] ;
>
>
> And then try to perform this compilation semantics:
>
> : test2 [ T ] ;
>
> So, the code "123 ." should be appended into test2.

No, T executes the compilation semantics of [T], which is to EVALUATE
(text interpret) the string S" 123 . ". Because T is in interpretation
state, it prints 123 during the definition of TEST2.

>
>
> test2 \ should print 123
>
>
> Using your implementation of POSTPONE, the word test2 will print nothing.
>
> Using my implementation of POSTPONE, the word test2 will print 123.
>
>
> There are only three options:
>  - my implementation behaves incorrectly
>  - your implementation behaves incorrectly
>  - it is an ambiguous condition.
>
> What do you think?
>
>

Your implementation behaves incorrectly.

--
Alex

JennyB

unread,
Jul 17, 2019, 2:41:01 PM7/17/19
to
On Wednesday, 17 July 2019 14:58:32 UTC+1, Ruvim wrote:

> : [T] S" 123 . " EVALUATE ; IMMEDIATE
>
> What is the compilation semantics of [T]?

The same as it is for every immediate word - to perform the execution
semantics, which is the same as the interpretation semantics.
There is no way to separate them.
It just so happens that executing the xt of [T] produces different results,
depending on STATE at the time of execution.

If that's what you actually want - fine. Tick will always return an xt representing the execution semantics of the definition, and if it is Immediate POSTPONE will always COMPILE, it.

But if you insist that the interpretation semantics of [T] is to place 123
on the stack and the compilation semantics is to compile it as a literal,
and that is to happen no matter what the current definition of STATE then
there is no way that POSTPONE or tick will get you what you want. The
problem lies not in the definition of those words, but in the definition of
[T].

There is in fact no agreed syntax to do this, but several systems have their own. Mark's would be (I think)

: [T] 123 ;
: [T] 123 POSTPONE LITERAL ; immediate compile-only

or possibly:

: [T] 123 POSTPONE LITERAL ; immediate compile-only
: [T] 123 ; interpret-only

As you can see, [T] now no longer has a single xt; it has two, one representing the interpretation semantics and one representing the
compilation semantics. Tick finds the first, POSTPONE finds the
second, and FIND finds whichever is appropriate to the current STATE.

: t1 ['] [T] EXECUTE ;
: t2 POSTPONE [T] ;

: test1 t1 ; test1 places 123 on the stack
: test2 [ t2 ] ; compiles it as a literal within the defintion

If a definition has 'undefined interpretation semantics', that simply means that its execution semantics make no sense when interpreted outside the compiling of a definition. They may make sense within [ ] but there is no need put them there in normal cases; since they are immediate they have exactly the same meaning inside as out. It would make more sense to have defined t2 above as immediate.

But it is perfectly possible that a system may provide interpretation
semantics (as above) for Standard words that do not have them. A Standard
program cannot use them, of course, but they may be handy elsewhere. That
being so, Tick should return them. Thus, Tick can only return a portable
result for words that have defined interpretation semantics. If it is a
word you have defined yourself in any Standard way, Tick will return its
execution token, as I said at the start.

none albert

unread,
Jul 17, 2019, 3:36:30 PM7/17/19
to
In article <2019Jul1...@mips.complang.tuwien.ac.at>,
Of for that matter ciforth that is basically figForth 5.3
with some words like POSTPONE tucked on.

>
>- anton

Groetjes Albert
--
This is the first day of the end of your life.
It may not kill you, but it does make your weaker.
If you can't beat them, too bad.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

dxforth

unread,
Jul 18, 2019, 5:15:35 AM7/18/19
to
On Thursday, 18 July 2019 03:05:24 UTC+10, Anton Ertl wrote:
> dxforth <dxf...@gmail.com> writes:
> > ...
> >Your interpretation of what a several decades old standard
> >requires is based on the behaviour of three modern systems?
>
> Well, if you look at pre-Forth-94 systems, they did not have POSTPONE,
> so one cannot use these systems to interpret it.

Sure I can:

D.5 ANS Forth approach

"the committee has chosen to base its compatibility decisions not
upon a strict comparison with the Forth-83 Standard, but instead
upon consideration of the variety of /existing/ implementations"

>
> And Forth-94 explicitly excluded systems like polyForth that had a
> separate compiler loop rather than a common text interpreter for
> interpretation and compilation.
>
> >A solution for POSTPONE that didn't include threaded code
> >systems and classical COMPILE wasn't an option for ANS.
>
> COMPILE is not included in Forth-94, so not including it obviously was
> an option. As for threaded code, there is nothing in the code above
> that's incompatible with threaded code; the easiest way to see this is
> by testing it with gforth-itc (indirect threaded code variant of
> Gforth rather than the more optimized variant that the gforth and
> gforth-fast engines use). The code above also works with
> gforth-0.2.1, which is a pretty classic threaded code implementation.

A.6.1.2033 explains COMPILE was not practical for /native code/ systems
to implement - hence it was not included in ANS. Nowhere does ANS
exclude systems from having COMPILE or using it to implement POSTPONE.
Indeed it's likely the TC anticipated it given D.5. Win32Forth being
one such system. POSTPONE comes with certain restrictions and I wouldn't
at all be surprised if COMPILE was deciding factor in that.

Anton Ertl

unread,
Jul 18, 2019, 6:29:30 AM7/18/19
to
Alex McDonald <al...@rivadpm.com> writes:
>On 12-Jul-19 17:35, Anton Ertl wrote:
>> Alex McDonald <al...@rivadpm.com> writes:
>>> On 12-Jul-19 06:24, Anton Ertl wrote:
>>>> BTW, it's unclear to me why you do anything with STATE at all in
>>>> POSTPONE. You know which parts of the rectype POSTPONE wants to use,
>>>> so use them directly instead of setting STATE and calling code that
>>>> decides based on STATE.
>>>>
>>>> E.g., Gforth's POSTPONE is (slightly simplified):
>>>>
>>>> : >postpone ( ... rectype -- )
>>>> dup >r rectype>post execute r> rectype>comp compile, ;
>>>>
>>>> : postpone ( "name" -- ) \ core
>>>> \g Compiles the compilation semantics of @i{name}.
>>>> parse-name forth-recognizer recognize >postpone ; immediate
>>>
>>> I'm using the pre-v4 version of the recognizer (I prefer the explicit &
>>> potentially varying POSTPONE action to support meta-compilation).
>>
>> In that case, just define >POSTPONE accordingly. Maybe like this:
>>
>> : >postpone ( ... rectype -- )
>> rectype>post execute ;
>>
>> - anton
>>
>
>I could, but using STATE seemed natural.

Global state always has dangers, as shown by the start of this thread,
and if you can easily avoid it, as in this case, you should. In
particular, in the present case, the recognizer might change or read
STATE, and one of these things caused the original problem.

>: STATE _STATE_ 0<> ;

Standard STATE returns an address containing 0 or -1.

Anton Ertl

unread,
Jul 18, 2019, 6:54:28 AM7/18/19
to
Ruvim <ruvim...@gmail.com> writes:
>By the Standard Tick always return the *execution semantics*.
>Not interpretation semantics. But occasionally they may coincide.

Actually there are no words that have both execution semantics and
interpretation semantics, that do not coincide. There are some words
with undefined interpretation semantics (e.g., COMPILE,) and some
words that do not have execution semantics (e.g., S"); and some words
have neither (e.g., IF).

Thanks to 4.1.2, tick is not guaranteed to return an xt for a word
without interpretation semantics, even if it has execution semantics.
So no, the standard tick does not always return the execution
semantics.

Ruvim

unread,
Jul 18, 2019, 7:01:02 AM7/18/19
to
Well, you should agree that this specification cannot be used without
the definition of "interpretation semantics" and "execution semantics"
terms. It just specifies some relation between these appearances in some
conditions. Understanding of this specification must not contradict the
definitions of the terms.

Therefore, from my point of view the fragment "in interpretation state"
should be added at the end in [3.4.3.2] for clarity. Without that you
could think that the *default* interpretation semantics of a word is
*always* *identical* to its execution semantics (and vise versa), even
in compilation state. But this is refuted by example.



By the definitions:

The only reference way to perform the execution semantics of a word is
to apply EXECUTE to its execution token.
E.g.: ' FOOBAR EXECUTE

The only reference way to perform the interpretation semantics of a word
is to pass its name to the text interpreter in interpretation state.
E.g.: S" FOOBAR" EVALUATE or just FOOBAR

The only reference way to perform the compilation semantics of a word is
to pass its name to the text interpreter in compilation state.
E.g.: ] FOOBAR [

With "reference way" I mean that any other alternative way shall have
the same effect as the reference way. Since a reference way is a direct
consequence of the corresponding definitions.

Actually, the part above is critical. Below the consequences only.




I claim that *if* the execution semantics of a word does depend on
STATE, the effect of performing this semantics (with the same arguments
except STATE) may differ in compilation state and in interpretation
state. In the case when it differs, performing the execution semantics
in compilation state has also a different effect than performing the
interpretation semantics of this word.

E.g.:
' FOOBAR ] [EXECUTE] [
has a different effect than:
FOOBAR

So, for such words (and only for such), the interpretation semantics of
the word is different to its execution semantics.

The reason is obvious. Behavior of execution semantics covers all
possible arguments, including different STATE. But behavior of
interpretation semantics covers all possible arguments except STATE, the
STATE is fixed to 0.

If you want to say that behavior of interpretation semantics covers all
possible arguments too, including different STATE — there is no reason
to have "execution semantics" term at all. These both semantics are
always identical. Please clarify why does the standard need "execution
semantics" term?



>> By definition, the interpretation
>> semantics of FOOBAR is a behavior that occurs when FOOBAR name is
>> encountered by the text interpreter *in interpretation state*.
[...]
>> We can't demonstrate another behavior in another state, since
>> in another state it will be not interpretation semantics.
>
> If you want a demonstration:
>
> : [execute] execute ; immediate
> : foo ." foo for interpreting" ;
> : bar ." bar for compiling" ;
> : foobar state @ if bar else foo then ; immediate
> s" foobar" find-name name>interpret ] [execute] [
>
> prints "bar for compiling".
>
> In Forth-94, we can write
>
> ' foobar ] [execute] [
>
> with the same result,

This example is not relevant.

You perform the execution semantics of FOOBAR, in place of performing
the interpretation semantics of FOOBAR. See the reference ways above.

For interpretation semantics you have missed "its name is encountered by
the text interpreter" part. In the both cases FOOBAR is not encountered
by the text interpreter. In the first time it is encountered by s". In
the second — by Tick.

If you try to show how the text interpreter works — your model is wrong,
since you parse in one STATE, but perform in another STATE. The text
interpreter does not work in such way.





> but that hinges on the question of whether '
> produces an xt representing interpretation of execution semantics,
> which I will discuss below.
>
>> The same regarding compilation semantics.
>
> This is even easier to demonstrate:
>
> : bar postpone foobar ; immediate
> bar
>
> prints "foo for interpreting".

Again, you have missed "its name is encountered by the text interpreter"
part. In this time foobar is encountered by postpone.




>> Tick return an execution token that, by definition, identifies the
>> *execution semantics*.
>>
>> 6.1.2510 [']
>> ... Place name's *execution token* xt on the stack.
>>
>> 6.1.0070 '
>> ... return xt, the *execution token* for name.
>>
>> The illustration:
>> "When interpreting, ' xyz EXECUTE is equivalent to xyz "
>>
>> — means that performing execution semantics of a word in interpretation
>> state has the exactly same effect as performing its interpretation
>> semantics.
>
> Consider
>
> ' s" execute bla"
>
> S" has no execution semantics, but this is equivalent to
>
> s" bla"
>
> when interpreting. So ' s" produces an xt representing the
> interpretation semantics.

This example is not relevant due to an ambiguous condition (see below).


[...]
>> Regarding the word S" — the standard does not specify execution
>> semantics for it. So, an ambiguous condition exist if tick (' or ['])
>> is applied to this word. And it is the same for other words with
>> undefined execution semantics.
>
> Where can I find this ambiguous condition?

It is a consequence of the specifications.
You have written it above too: S" has no execution semantics.
But, by the specification, the value that Tick returns (if any) is an
identifier for execution semantics, and nothing else. The standard does
not specify what to return in the case when execution semantics is
undefined. Therefore it is an ambiguous condition: the standard Forth
systems may have different behavior in this case.


--
Ruvim

Ruvim

unread,
Jul 18, 2019, 7:22:50 AM7/18/19
to
On 2019-07-18 13:39, Anton Ertl wrote:
> Ruvim <ruvim...@gmail.com> writes:
>> By the Standard Tick always return the *execution semantics*.
>> Not interpretation semantics. But occasionally they may coincide.
>
> Actually there are no words that have both execution semantics and
> interpretation semantics, that do not coincide.

From my point of view, EVALUATE and INCLUDED are the examples of such
words.

Performing the execution semantics of EVALUATE in compilation state may
have different effect than performing its interpretation semantics.

E.g.:

: [E] EXECUTE ; IMMEDIATE

S" 123 . " ' EVALUATE ] [E] [

S" 123 . " EVALUATE

The effect is different. Therefore the execution semantics is not the
same as the interpretation semantics for this word.



> There are some words
> with undefined interpretation semantics (e.g., COMPILE,) and some
> words that do not have execution semantics (e.g., S"); and some words
> have neither (e.g., IF).
>
> Thanks to 4.1.2, tick is not guaranteed to return an xt for a word
> without interpretation semantics, even if it has execution semantics.
> So no, the standard tick does not always return the execution
> semantics.

I agree, thanks for pointing out. So, I have used more accurate wording
in my previous message.


--
Ruvim

Anton Ertl

unread,
Jul 18, 2019, 7:35:41 AM7/18/19
to
"A. K." <minf...@arcor.de> writes:
>Am Dienstag, 16. Juli 2019 05:24:51 UTC+2 schrieb Mark William Humphries:
>> My approach to addressing all the issues discussed hasn't fundamentally changed since then:
>> https://www.reddit.com/r/Forth/comments/9izdtq/a_simple_approach_to_dual_words/
>
>I use the same concept.

Good. But then you write the following, which suggests that you are
using STATE-smart words, not Mark Humphries' concept.

>And state-smart words are so simple. He who stumbles over them has tested
>his applications not thoroughly enough.

"Everything should be as simple as it can be, but not simpler" is
attributed to Albert Einstein, probably paraphrased from the following
actual quote:

|It can scarcely be denied that the supreme goal of all theory is to
|make the irreducible basic elements as simple and as few as possible
|without having to surrender the adequate representation of a single
|datum of experience.

<https://quoteinvestigator.com/2011/05/13/einstein-simple/>

STATE-smart words do not work as intended in corner cases, so they are
simpler, and they surrender the adequate representation of the corner
cases.

If you want to be simpler than proper implementations of
dual-semantics words, then drop dual-semantics words and go the ' [']
way. Then you don't need STATE-smart words.

Ruvim

unread,
Jul 18, 2019, 7:51:27 AM7/18/19
to
On 2019-07-18 13:22, Anton Ertl wrote:
> Alex McDonald <al...@rivadpm.com> writes:

>> : STATE _STATE_ 0<> ;
>
> Standard STATE returns an address containing 0 or -1.

Not quite. "The true value in STATE is non-zero, but is otherwise
implementation-defined." So, the address returned by standard STATE may
also contain 1,2, or any other value.

-- https://forth-standard.org/standard/core/STATE


--
Ruvim

Alex McDonald

unread,
Jul 18, 2019, 8:11:57 AM7/18/19
to
That's sound advice.

>
>> : STATE _STATE_ 0<> ;
>
> Standard STATE returns an address containing 0 or -1.

Yes, that was shorthand typed in and wrong. It returns a variable, not a
value.

--
Alex

Anton Ertl

unread,
Jul 18, 2019, 8:27:43 AM7/18/19
to
Ruvim <ruvim...@gmail.com> writes:
>On 2019-07-15 19:33, Alex McDonald wrote:
>> On 15-Jul-19 16:05, Ruvim wrote:
>>> On 2019-07-15 16:18, Alex McDonald wrote:
>>>> On 15-Jul-19 13:17, Ruvim wrote:
[...]
>Hence, the execution semantics and the interpretation semantics are not
>the same for FOOBAR. Isn't it?

The standard does not specify otherwise in an "Interpretation:"
section of its glossary entry, therefore its interpretation semantics
are the same as the execution semantics (3.4.3.2).

>> : foo ." foo for interpreting" ;
>> : bar ." bar for compiling" ;
>> : foobar state @ if bar else foo then ; immediate
>> : barfoo postpone foobar ;
>> : test barfoo ;
>>
>>  cr foobar \ prints "foo for interpreting"
>>  cr test   \ prints "foo for interpreting"
>
>I could say that such POSTPONE has a flaw — it works incorrectly with
>the STATE-smart words. It appends execution semantics in place of
>compilation semantics. This flaw should be either documented or fixed.

FOOBAR is an immediate word. Therefore its compilation semantics are
to perform its interpretation semantics (2.1). So if POSTPONE is
implemented correctly, POSTPONE FOOBAR must append the execution
semantics (=compilation semantics) to the current definition.

>In the case of a classic FIND-based Forth system a correct POSTPONE can
>be defined as:
>
>: execute-compiling ( i*x xt --j*x )
> state @ if execute exit then ] execute [compile] [
>;
>: postpone
> bl word find
> dup -1 = if drop lit, 'compile, compile, exit then
> 1 = if lit, 'execute-compiling compile, exit then
> -13 throw
>; immediate

Here are two examples where this POSTPONE fails:

: foo state @ . ; immediate
: foo1 postpone foo ;
foo1 \ should print 0 (the current state)

: x] ] ; immediate
: y] postpone x] ;
: bar [ 2 2 + y] literal . ;
bar \ should print 4

>OTOH, if this equivalence is held for any word and any state — why does
>the Standard need the both terms? (i.e. "execution semantics" and
>"interpretation semantics"). One of them would be enough.
>Don't you think so?

Yes, in all cases where both are defined, they are the same.

And I am unaware of any system that has an execution semantics
separate from the interpretation semantics.

If we look at where the standard terms are coming from, Forth-94 tried
to reconcile classical Forth with cmForth. The execution semantics
came from classical Forth, interpretation and compilation semantics
from cmForth. Forth-94 specified execution semantics were specified
for ordinary words, and user-defined words including :NONAME words.
It specified undefined interpretation semantics that are (or would be)
only present in the compilation wordlist in cmForth.

When it specifies compilation and interpretation semantics (even
undefined interpretation semantics), it does not specify execution
semantics, because execution semantics is just needed to define the
interpretation or compilation semantics through the default mechanism.
If they are both present, execution semantics has no function.

Alex McDonald

unread,
Jul 18, 2019, 8:45:31 AM7/18/19
to
We will make a standards wrangler out of you yet ;o

--
Alex

Anton Ertl

unread,
Jul 18, 2019, 9:52:55 AM7/18/19
to
Ruvim <ruvim...@gmail.com> writes:
>: [T] S" 123 . " EVALUATE ; IMMEDIATE
>
>What is the compilation semantics of [T]?

It is the same as the interpretation and execution semantics:
text-interpret "123".

Anton Ertl

unread,
Jul 18, 2019, 10:10:26 AM7/18/19
to
Ruvim <ruvim...@gmail.com> writes:
>On 2019-07-17 18:44, Alex McDonald wrote:
[ : [T] S" 123 . " EVALUATE ; IMMEDIATE ]
>Hence, the compilation semantics of [T] is to append "123 ." (printing
>123) into the current definition.

No, it's to text-interpret "123 .".

>Now, let's try to append this compilation semantics to the new definition T
>
>: T POSTPONE [T] ;
>
>
>And then try to perform this compilation semantics:
>
>: test2 [ T ] ;
>
>So, the code "123 ." should be appended into test2.

No. "123 ." is text-interpreted in interpretation state, so it's
performed right away rather than appended.

EVALUATE depends on a lot of global state: The search order, BASE,
STATE, etc. It should be used very carefully and sparingly.

>test2 \ should print 123
>
>
>Using your implementation of POSTPONE, the word test2 will print nothing.
>
>Using my implementation of POSTPONE, the word test2 will print 123.
>
>
>There are only three options:
> - my implementation behaves incorrectly
> - your implementation behaves incorrectly
> - it is an ambiguous condition.
>
>What do you think?

Your implementation behaves incorrectly.

I have just tested Gforth, VFX, SwiftForth, and iForth, and they all
behave the same way in this example:

: test2 [ T ] ; \ prints "123"
test2 \ prints nothing

As I wrote:

There is one thing you need to understand about interpretation and
compilation semantics in the standard: they do not depend on STATE.
Only the text interpreter uses STATE to decide whether to perform
interpretation semantics or compilation semantics; nothing else does.

Anton Ertl

unread,
Jul 18, 2019, 10:41:40 AM7/18/19
to
dxforth <dxf...@gmail.com> writes:
>On Thursday, 18 July 2019 03:05:24 UTC+10, Anton Ertl wrote:
>> dxforth <dxf...@gmail.com> writes:
>> > ...
>> >Your interpretation of what a several decades old standard
>> >requires is based on the behaviour of three modern systems?
>>
>> Well, if you look at pre-Forth-94 systems, they did not have POSTPONE,
>> so one cannot use these systems to interpret it.
>
>Sure I can:
>
> D.5 ANS Forth approach
>
> "the committee has chosen to base its compatibility decisions not
> upon a strict comparison with the Forth-83 Standard, but instead
> upon consideration of the variety of /existing/ implementations"

So they considered a number of systems, and decided that COMPILE does
not cut it, and introduced POSTPONE. Now what?

>> >A solution for POSTPONE that didn't include threaded code
>> >systems and classical COMPILE wasn't an option for ANS.
>>
>> COMPILE is not included in Forth-94, so not including it obviously was
>> an option. As for threaded code, there is nothing in the code above
>> that's incompatible with threaded code; the easiest way to see this is
>> by testing it with gforth-itc (indirect threaded code variant of
>> Gforth rather than the more optimized variant that the gforth and
>> gforth-fast engines use). The code above also works with
>> gforth-0.2.1, which is a pretty classic threaded code implementation.
>
>A.6.1.2033 explains COMPILE was not practical for /native code/ systems
>to implement - hence it was not included in ANS. Nowhere does ANS
>exclude systems from having COMPILE or using it to implement POSTPONE.

If you can produce a correct implementation of POSTPONE that employs
COMPILE, fine. But the standard and only the standard specifies what
a correct implementation of POSTPONE is. There is no other reference,
because there are no preceding implementations.

>Indeed it's likely the TC anticipated it given D.5. Win32Forth being
>one such system. POSTPONE comes with certain restrictions and I wouldn't
>at all be surprised if COMPILE was deciding factor in that.

Which restrictions do you mean?

Anyway, I just dug up POSTPONE from gforth-0.1alpha:

: (compile) ( -- ) r> dup cell+ >r @ compile, ;
: postpone ( "name" -- )
name sfind dup 0= abort" Can't compile "
0> IF compile, ELSE postpone (compile) A, THEN ;
immediate restrict

I started a recent gforth-itc, pasted this POSTPONE code into it, then
the POSTPONE-POSTPONE example, and lo and behold, it behaves just like
any other correct system; and I also tried the same experiment with
gforth-0.2.1 (the oldest that I can easily run), with the same result.

If your system does not grok the POSTPONE-POSTPONE test, it's not
because of threaded code or COMPILE.

Anton Ertl

unread,
Jul 18, 2019, 1:04:53 PM7/18/19
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>Anyway, I just dug up POSTPONE from gforth-0.1alpha:
>
>: (compile) ( -- ) r> dup cell+ >r @ compile, ;
>: postpone ( "name" -- )
> name sfind dup 0= abort" Can't compile "
> 0> IF compile, ELSE postpone (compile) A, THEN ;
> immediate restrict
>
>I started a recent gforth-itc, pasted this POSTPONE code into it, then
>the POSTPONE-POSTPONE example, and lo and behold, it behaves just like
>any other correct system; and I also tried the same experiment with
>gforth-0.2.1 (the oldest that I can easily run), with the same result.

I continued by testing on the regular gforth engine (which uses
primitive-centric threaded code rather than classic threaded code
(e.g., a colon definition is compiled as primitive CALL followed by
the body address of the colon definition). I.e., it is already
affected by the COMPILE incompatibility (see below).

And, surprisingly, it worked. I modified the code to avoid
Gforth-specific words:

: (compile) ( -- ) r> dup cell+ >r @ compile, ;
: postpone ( "name" -- )
bl word find dup 0= abort" Can't compile "
0> IF compile, ELSE postpone (compile) , THEN ;
immediate

: POSTPONE-POSTPONE
POSTPONE POSTPONE ;

: PPP1 123 ;
: PPP4 [ POSTPONE-POSTPONE PPP1 ] ; IMMEDIATE
: PPP5 PPP4 ;
PPP5 . \ prints 123

and ran it (and the POSTPONE-POSTPONE test) on VFX and SwiftForth
(native-code systems). And they worked, too. Only iForth had a
problem with this code.

Why does it work? The part where the branch with (COMPILE) is invoked
is in "POSTPONE-POSTPONE PPP1". This compiles a call to (COMPILE) (as
primitive-centric or native code), followed by a cell containing the
xt of PPP1; on Gforth:

simple-see ppp4
$7FDFBB0FC360 call
$7FDFBB0FC368 <(compile)>
$7FDFBB0FC370 PPP1
$7FDFBB0FC378 ;s

When PPP4 is then executed, (COMPILE) uses return-address manipulation
to get the xt of PPP1, step over this cell, and returns to the code
after the cell (i.e., the ";s"). This also works with native code, as
long as @ works with unaligned addresses, the return stack contains
single-cell return addresses, and the optimizer is compatible with
return-address manipulation.

The other aspect of (COMPILE) is that it uses COMPILE, to compile the
xt of PPP1, which generates the correct kind of code for the system
(primitive-centric code or native code). As a result, PPP5 looks as
follows on Gforth:

simple-see ppp5
$7FDFBB0FC3A8 call
$7FDFBB0FC3B0 <PPP1>
$7FDFBB0FC3B8 ;s

So is COMPILE (or (COMPILE)) cool for such non-traditional systems?
Not in its classical usage, because that relies on the system
compiling the xt as cell after the COMPILE, and these systems do not
do that.

: ppp6 (compile) ppp1 ; immediate

simple-see ppp6
$7FDFBB0FC458 call
$7FDFBB0FC460 <(compile)>
$7FDFBB0FC468 call
$7FDFBB0FC470 <PPP1>
$7FDFBB0FC478 ;s

Note the difference between PPP4 and PPP6. PPP4 works because
POSTPONE puts the xt after the (COMPILE) with ",".

dxforth

unread,
Jul 18, 2019, 8:41:25 PM7/18/19
to
That's unlikely. Semantics were never more than legalese which
attempted to describe how real systems worked. However semantics
are not the thing and to then use them to justify or disqualify
I consider a perversion - a putting of the cart before the horse,
law above society than a servant of it.

Ruvim

unread,
Jul 19, 2019, 4:50:48 AM7/19/19
to
== Some rationales, why these ways are the reference ways.

1. They are direct consequence of the most general definitions.

2. They work in all the possible cases. I.e. in some cases when a
reference way is allowed, the alternative ways are not allowed (or not
possible). But never inverse. When an alternative way is allowed, the
reference way is allowed too.


=== Examples

In the majority cases execution semantics can be performed by
performing the corresponding interpretation semantics. But it does not
work for anonymous definitions, is not allowed for words with defined
execution semantics and undefined interpretation semantics, and cannot
be used to perform execution semantics in compilation state.

In the majority cases interpretation semantics can be performed by
performing the corresponding execution semantics in interpretation
state. But it is not allowed for the words with undefined executions
semantics.

In the majority cases compilation semantics can be performed by
applying COMPILE, to the corresponding execution semantics. But it is
not allowed for the words with undefined executions semantics and does
not work for the words with not default compilation semantics.

In the majority cases compilation semantics can be appended to the
new definition (by applying POSTPONE to the word) and then performed by
performing the execution semantics of this new definition. But it is not
allowed for some words (that is explicitly mentioned in the
corresponding specifications), and the main thing — due to conflicting
specifications, the Standard does not guarantee that *the effect* will
be *the same* as in the reference way. When the effect may be different
— this way is not an alternative way to the reference way to perform
compilation semantics.




--
Ruvim


Ruvim

unread,
Jul 19, 2019, 5:14:16 AM7/19/19
to
== Our dispute

The issue about different effect in the last example above — is the
cause of our dispute about the proper behavior of POSTPONE and what
compilation semantics is in the edge cases.

We base our understanding on different parts of the Standard, and due to
conflicting of these parts with each other, we get conflicting
understanding. The position of Anton, Alex, and all the guys who
believes that my POSTPONE idea is incorrect, is that a particular
specification may infringe the general definitions, my position is that
particular specifications must obey to the general definitions.


But in any case, you should agree that the Standard is inconsistent in
the disputed question. So, it will be honest to admit that the
corresponding edge cases are ambiguous conditions due to the conflicting
specifications in the Standard.

It should be noted that it does not matter how other Forth systems work
in regard to our question. In another message Anton wrote: "But the
standard and only the standard specifies what a correct implementation
of POSTPONE is". And we are talking about the very normative point of
view now.


To fix the conflict in the Standard we actually have three options (from
easy to hard):

- clarify the particular specifications (by adding several words in
the several places).
- modify the general definitions.
- rewrite all the parts regarding semantics.




--
Ruvim

Coos Haak

unread,
Jul 19, 2019, 8:50:46 AM7/19/19
to
Op Thu, 18 Jul 2019 14:22:47 +0300 schreef Ruvim:

> E.g.:
>
> : [E] EXECUTE ; IMMEDIATE
>
> S" 123 . " ' EVALUATE ] [E] [
>
> S" 123 . " EVALUATE
>
> The effect is different. Therefore the execution semantics is not the
> same as the interpretation semantics for this word.
>
Let's add some comments:

: [e] >r cr ." source: " 2dup type cr ." output: " r> execute ; immediate
s" 123 . " 'evaluate [e]
source: 123 .
output: 123 ok
\ The output is visable, interpret mode.

s" 123 . " 'evaluate ] [e] [
source: 123 .
output: ok
Because ] sets compiling, the string is compiled
in the dictionary and not visable.

groet Coos

Alex McDonald

unread,
Jul 19, 2019, 9:11:05 AM7/19/19
to
On 19-Jul-19 10:14, Ruvim wrote:

>
> == Our dispute
>
> The issue about different effect in the last example above — is the
> cause of our dispute about the proper behavior of POSTPONE and what
> compilation semantics is in the edge cases.
>
> We base our understanding on different parts of the Standard, and due to
> conflicting of these parts with each other, we get conflicting
> understanding. The position of Anton, Alex, and all the guys who
> believes that my POSTPONE idea is incorrect, is that a particular
> specification may infringe the general definitions, my position is that

I have not said nor do I believe that, nor do I think you can point to
anyone else saying or believing that.


> particular specifications must obey to the general definitions.
>
>
> But in any case, you should agree that the Standard is inconsistent in
> the disputed question. So, it will be honest to admit that the
> corresponding edge cases are ambiguous conditions due to the conflicting
> specifications in the Standard.

No, I don't agree with your strawman.

>
> It should be noted that it does not matter how other Forth systems work
> in regard to our question.

That's silly. Of course it matters how real life systems work. Standards
don't run programs.

> In another message Anton wrote: "But the
> standard and only the standard specifies what a correct implementation
> of POSTPONE is". And we are talking about the very normative point of
> view now.

We have many implementations, and all of those implementations disagree
with your interpretation. Every one of them. And they quite clearly do
what the standard says they should do.

>
>
> To fix the conflict in the Standard we actually have three options (from
> easy to hard):

What conflict? I've seen nothing that indicates conflict, just a
misunderstanding on your part (and one that I initially shared part of,
see my original post).

>
>   - clarify the particular specifications (by adding several words in
> the several places).
>   - modify the general definitions.
>   - rewrite all the parts regarding semantics.
>
>

Then you must write it.


--
Alex

Alex McDonald

unread,
Jul 19, 2019, 9:18:16 AM7/19/19
to
On 19-Jul-19 14:11, Alex McDonald wrote:
> On 19-Jul-19 10:14, Ruvim wrote:

>
>> In another message Anton wrote: "But the standard and only the
>> standard specifies what a correct implementation of POSTPONE is". And
>> we are talking about the very normative point of view now.

Addendum

Perhaps purposefully, you didn't quote the next sentence.

But the standard and only the standard specifies what
a correct implementation of POSTPONE is. There is no other reference,
because there are /no preceding implementations/.

I'd also note that all subsequent implementations correctly implement
what is written, except your proposed system.

--
Alex

Ruvim

unread,
Jul 19, 2019, 10:01:30 AM7/19/19
to
On 2019-07-19 16:11, Alex McDonald wrote:
> On 19-Jul-19 10:14, Ruvim wrote:
>
>>
>> == Our dispute
>>
>> The issue about different effect in the last example above — is the
>> cause of our dispute about the proper behavior of POSTPONE and what
>> compilation semantics is in the edge cases.
>>
>> We base our understanding on different parts of the Standard, and due
>> to conflicting of these parts with each other, we get conflicting
>> understanding. The position of Anton, Alex, and all the guys who
>> believes that my POSTPONE idea is incorrect, is that a particular
>> specification may infringe the general definitions, my position is that
>
> I have not said nor do I believe that, nor do I think you can point to
> anyone else saying or believing that.

Sorry, I missed another variant. Somebody doesn't see the conflicting
parts in the Standard at all.

Regarding my POSTPONE idea, it seems your opinion is that it behaves
incorrectly. I believe it is interesting in any case and can be used to
correctly implement POSTPONE for dual-semantics STATE-smart words.


--
Ruvim

Alex McDonald

unread,
Jul 19, 2019, 10:45:36 AM7/19/19
to
On 19-Jul-19 15:01, Ruvim wrote:
> On 2019-07-19 16:11, Alex McDonald wrote:
>> On 19-Jul-19 10:14, Ruvim wrote:
>>
>>>
>>> == Our dispute
>>>
>>> The issue about different effect in the last example above — is the
>>> cause of our dispute about the proper behavior of POSTPONE and what
>>> compilation semantics is in the edge cases.
>>>
>>> We base our understanding on different parts of the Standard, and due
>>> to conflicting of these parts with each other, we get conflicting
>>> understanding. The position of Anton, Alex, and all the guys who
>>> believes that my POSTPONE idea is incorrect, is that a particular
>>> specification may infringe the general definitions, my position is that
>>
>> I have not said nor do I believe that, nor do I think you can point to
>> anyone else saying or believing that.
>
> Sorry, I missed another variant. Somebody doesn't see the conflicting
> parts in the Standard at all.

The standard has plenty of problems. IMHO the text of POSTPONE isn't one
of them, and neither is execution/interpretation/compilation semantics
(although some non-normative examples might help).

>
> Regarding my POSTPONE idea, it seems your opinion is that it behaves
> incorrectly. I believe it is interesting in any case and can be used to
> correctly implement POSTPONE for dual-semantics STATE-smart words.

Your proposal behaves incorrectly (and rather bizarrely to be frank).

No, your idea can't correctly implement POSTPONE for "dual semantics
STATE-smart" words because that's an oxymoron. Please tell me how the
programmer, the text interpreter, or any other oracle can say "This word
has dual semantics".

--
Alex
It is loading more messages.
0 new messages