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

LatestXT

70 views
Skip to first unread message

Arnold Doray

unread,
Dec 8, 2011, 9:42:27 PM12/8/11
to
I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
implementation?

Thanks,
Arnold

Andrew Haley

unread,
Dec 9, 2011, 4:43:21 AM12/9/11
to
Arnold Doray <thinks...@gmail.com> wrote:
> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
> implementation?

No. Practice varies so much between Forths that it hasn't been
possible to standardize it. You'd be better off figuring how to live
without it.

Andrew.

Arnold Doray

unread,
Dec 9, 2011, 8:12:27 AM12/9/11
to
Thanks.

Anton Ertl

unread,
Dec 9, 2011, 8:26:23 AM12/9/11
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Arnold Doray <thinks...@gmail.com> wrote:
>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>> implementation?
>
>No. Practice varies so much between Forths that it hasn't been
>possible to standardize it.

This feature should be easy to insert into any standard Forth:

Add a possibly (USERized) VALUE LATESTXT, and in every place where an
xt is defined, add an "is latestxt".

So it's not that it is not standardized because there are
implementation difficulties. It's just that nobody has tried to
standardize it; maybe there is also too little common practice.

Your PREFIX? example might be a trigger to add this feature to VFX
Forth.

- 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 2011: http://www.euroforth.org/ef11/

Andrew Haley

unread,
Dec 9, 2011, 1:41:12 PM12/9/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Arnold Doray <thinks...@gmail.com> wrote:
>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>> implementation?
>>
>>No. Practice varies so much between Forths that it hasn't been
>>possible to standardize it.
>
> This feature should be easy to insert into any standard Forth:
>
> Add a possibly (USERized) VALUE LATESTXT, and in every place where an
> xt is defined, add an "is latestxt".

Not necessarily. For example, you don't know when the latest XT is
defined while compiling a colon definition; it might not be until
after ; . You don't know if there is an extra XT created by DOES> .
Is :NONAME included? I guess so. It's all these little gotchas that
make it hard.

> Your PREFIX? example might be a trigger to add this feature to VFX
> Forth.

I'm sure VFX has something equivalent already. I'm not sure how it'd
be used in PREFIX? , though.

Andrew.

Elizabeth D. Rather

unread,
Dec 9, 2011, 2:36:21 PM12/9/11
to
On 12/9/11 3:26 AM, Anton Ertl wrote:
> Andrew Haley<andr...@littlepinkcloud.invalid> writes:
>> Arnold Doray<thinks...@gmail.com> wrote:
>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>> implementation?
>>
>> No. Practice varies so much between Forths that it hasn't been
>> possible to standardize it.
>
> This feature should be easy to insert into any standard Forth:

AFAIK most if not all Forths have some method for knowing the latest
definition, it's kinda necessary. The problem is, that they all do it
differently (at different times, in different forms, etc.), which is why
it hasn't been possible to standardize it.

Although it's a system necessity, I haven't found this of much value in
application programming.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

Arnold Doray

unread,
Dec 9, 2011, 10:24:37 PM12/9/11
to
On Fri, 09 Dec 2011 13:26:23 +0000, Anton Ertl wrote:

>
> This feature should be easy to insert into any standard Forth:
>
> Add a possibly (USERized) VALUE LATESTXT, and in every place where an xt
> is defined, add an "is latestxt".
>

Thanks.

To be honest, I could live with just better standardized behaviour
for :NONAME as it is called within a word. For example,

: def :noname .S ;

GForth and BigForth behave this way:

def ." rover" ; <5> 5015480 0 0 5015480 0 ok <-- GForth
def ." rover" ; <2> 268642316 0 ok <-- BigForth

These forths leave junk on the stack making retrieving the :NONAME's xt
"unportable".

But GForth has LATESTXT which is nicer than just a clean stack since the
xt is saved. And it also works for definitions made with CREATE.

VFX and SwiftForth are much better behaved:

def ." rover" ;

DATA STACK
top
134990068 080B:C8F4
ok-1 <-- VFX.

SwiftForth is the same. Both leave a clean stack with just the :NONAME's
xt on it.

I am *guessing* that GForth and BigForth don't serialize the execution
of :NONAME and .S , so .S sees the stack as the :NONAME is in partial
execution?

In any case, some standardization of this behaviour would be welcome.

Cheers,
Arnold


BruceMcF

unread,
Dec 9, 2011, 11:12:28 PM12/9/11
to
On Dec 9, 10:24 pm, Arnold Doray <thinksqua...@gmail.com> wrote:
> On Fri, 09 Dec 2011 13:26:23 +0000, Anton Ertl wrote:
>
> > This feature should be easy to insert into any standard Forth:
>
> > Add a possibly (USERized) VALUE LATESTXT, and in every place where an xt
> > is defined, add an "is latestxt".
>
> Thanks.
>
> To be honest, I could live with just better standardized behaviour
> for :NONAME as it is called within a word. For example,
>
> : def :noname .S ;
>
> GForth and BigForth behave this way:
>
> def ." rover" ;   <5> 5015480 0 0 5015480 0  ok <-- GForth
> def ." rover" ;  <2> 268642316 0  ok <-- BigForth
>
> These forths leave junk on the stack making retrieving the :NONAME's xt
> "unportable".
>
> But GForth has LATESTXT which is nicer than just a clean stack since the
> xt is saved. And it also works for definitions made with CREATE.
>
> VFX and SwiftForth are much better behaved:
>
> def ." rover" ;
>
> DATA STACK
>      top
>       134990068 080B:C8F4
>  ok-1 <-- VFX.
>
> SwiftForth is the same. Both leave a clean stack with just the
> :NONAME's xt on it.

There's no telling what "colon-sys" from the specification actually
means ~ it could be nothing, it could be notional, as in the stack
depth is saved in a variable for checking on ";" but nothing is placed
on the data stack, it could be a marker ... so what :noname normally
leave on the stack is the xt underneath whatever ";" will be expecting
to clean up.

>
> I am *guessing* that GForth and BigForth don't serialize the execution
> of :NONAME and .S , so .S sees the stack as the :NONAME is in partial
> execution?

Far more likely that the xt is sitting underneath whatever their
colonsys happens to be under the circumstance.

Elizabeth D. Rather

unread,
Dec 9, 2011, 11:15:37 PM12/9/11
to
Remember all the discussion about colon-sys and whether colon leaves
stuff on the stack to be discarded by semi-colon? That's what you're
seeing. :noname leaves a colon-sys, as does colon. On some systems
that's nothing, on others it's stuff, and exactly what (if anything) it
is implementation-dependent.

Personally, I'm no big fan of :noname, and using it in a definition is,
to me, rarely a good idea.

Andrew Haley

unread,
Dec 10, 2011, 3:49:09 AM12/10/11
to
Arnold Doray <thinks...@gmail.com> wrote:
> On Fri, 09 Dec 2011 13:26:23 +0000, Anton Ertl wrote:
>
>>
>> This feature should be easy to insert into any standard Forth:
>>
>> Add a possibly (USERized) VALUE LATESTXT, and in every place where an xt
>> is defined, add an "is latestxt".
>
> To be honest, I could live with just better standardized behaviour
> for :NONAME as it is called within a word. For example,
>
> : def :noname .S ;
>
> GForth and BigForth behave this way:
>
> def ." rover" ; <5> 5015480 0 0 5015480 0 ok <-- GForth
> def ." rover" ; <2> 268642316 0 ok <-- BigForth
>
> These forths leave junk on the stack making retrieving the :NONAME's xt
> "unportable".

The XT might not even exist until after ; .

Andrew.

Arnold Doray

unread,
Dec 10, 2011, 5:18:38 AM12/10/11
to
Yes, I am aware that both : and :NONAME can leave "turds" on the stack
while they are parsing input. That's acceptable. But I would have thought
that the terminating ; in the input stream of :

def ." rover" ;

would have to run and clean up :NONAME's stack turds before the next word
in DEF (ie, .S) executes. But from my example, it appears that this isn't
necessarily the case.

Certainly, GForth and BigForth behave as if the .S is executed before
the :NONAME encounters the terminating ; in the input stream.

IMO, this is a separate issue from the colon-sys discussion, and is
really about :NONAME's runtime behaviour.

If :NONAME's runtime behaviour were standardized, then actions could be
taken at compile time (ie, in DEF) to save/manipulate/execute the
anonymous function created by :NONAME. But you can't do that now, or at
least have to rely on non-standard words like LATESTXT.

>
> Personally, I'm no big fan of :noname, and using it in a definition is,
> to me, rarely a good idea.
>

I first saw the use of :NONAME in a definition in the '94 spec, and
thought it was "Forth Way".

Could you share your reasons for not liking :NONAME?
How else to create words that can parse the input stream?

Thanks,
Arnold

Anton Ertl

unread,
Dec 10, 2011, 6:39:07 AM12/10/11
to
Arnold Doray <thinks...@gmail.com> writes:
>On Fri, 09 Dec 2011 18:15:37 -1000, Elizabeth D. Rather wrote:
>
>> On 12/9/11 5:24 PM, Arnold Doray wrote:
>>> : def :noname .S ;
...
>Yes, I am aware that both : and :NONAME can leave "turds" on the stack
>while they are parsing input. That's acceptable. But I would have thought
>that the terminating ; in the input stream of :
>
>def ." rover" ;
>
>would have to run and clean up :NONAME's stack turds before the next word
>in DEF (ie, .S) executes. But from my example, it appears that this isn't
>necessarily the case.
>
>Certainly, GForth and BigForth behave as if the .S is executed before
>the :NONAME encounters the terminating ; in the input stream.

Correct. :NONAME does not parse the input stream in a standard
system. It just starts a definition; then, in your code .S prints the
stack, then the text interpreter performs the compilation semantics of
'."' and ';'.

>How else to create words that can parse the input stream?

Just include parsing words in any colon definition (whether defined
with :NONAME or :). But it's usually a bad idea to create parsing
words.

Anton Ertl

unread,
Dec 10, 2011, 7:06:55 AM12/10/11
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Arnold Doray <thinks...@gmail.com> wrote:
>> These forths leave junk on the stack making retrieving the :NONAME's xt
>> "unportable".
>
>The XT might not even exist until after ; .

The standard defines :NONAME to have the stack effect
( C: -- colon-sys ) ( S: -- xt )

So the xt exists right after :NONAME in the standard. And I don't
think you can argue that it's not observable until ";" removes the
colon-sys, because we can see the whole stack with ".S". If the xt
left after the ";" is different from each of the values we saw earlier,
the system is not compliant.

Even if we ignore that, there is a practical reason for xt to exist
before the ";": RECURSE. Without an XT, how do you implement it? I
looked at a few systems (SwiftForth, VFX, Gforth), and RECURSE always
calls COMPILE, in them, so the RECURSE is defined as, essentually:

: RECURSE
... ( code equivalent to LATESTXT )
COMPILE, ; IMMEDIATE

Josh Grams

unread,
Dec 10, 2011, 7:33:59 AM12/10/11
to
Andrew Haley wrote: <K6ednaewXd6YgH7T...@supernews.com>
Er...the standard says it exists immediately. Do you have an example of
a system where it doesn't?

AFAICS the following is required to work on any standard system:

variable noname-xt
: :noname ( -- xt colon-sys )
depth 1+ >r :noname depth r> - pick noname-xt ! ;

--Josh

Anton Ertl

unread,
Dec 10, 2011, 7:24:04 AM12/10/11
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>Arnold Doray <thinks...@gmail.com> wrote:
>>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>>> implementation?
>>>
>>>No. Practice varies so much between Forths that it hasn't been
>>>possible to standardize it.
>>
>> This feature should be easy to insert into any standard Forth:
>>
>> Add a possibly (USERized) VALUE LATESTXT, and in every place where an
>> xt is defined, add an "is latestxt".
>
>Not necessarily. For example, you don't know when the latest XT is
>defined while compiling a colon definition; it might not be until
>after ; .

Is this based on a real, standard system (i.e., practice), or do you
just make this up to support your claim?

> You don't know if there is an extra XT created by DOES> .

That can be defined, just as for RECURSE; or it can be turned into an
ambiguous condition, just as it has been done for RECURSE.

>Is :NONAME included? I guess so. It's all these little gotchas that
>make it hard.

There are no special gotchas there. This is just like for any other
word one wants to standardize: You have to specify it properly.

Arnold Doray

unread,
Dec 10, 2011, 11:31:29 AM12/10/11
to
On Sat, 10 Dec 2011 11:39:07 +0000, Anton Ertl wrote:

>>Certainly, GForth and BigForth behave as if the .S is executed before
>>the :NONAME encounters the terminating ; in the input stream.
>
> Correct. :NONAME does not parse the input stream in a standard system.
> It just starts a definition; then, in your code .S prints the stack,
> then the text interpreter performs the compilation semantics of '."' and
> '

Is this reasonable?

Firstly, the spec says that :NONAME should :-

Create an execution token xt,
Enter compilation state and
Start the current definition,
producing colon-sys.
Append the initiation semantics given
below to the current definition.

If the compilation state is entered, how can the next word after
the :NONAME (ie, .S) execute?

Secondly, if the text parser doesn't kick in immediately after the :NONAME
executes, this leads to all kinds of confusion, IMHO.

For example, consider:

: mdef :noname :noname ;

It *should* be easy to determine what MDEF does -- the first :NONAME
executes, kicks off the text parser which parses the inputstream until
a ; is encountered, resulting in an XT on the stack. Ditto for the
second :NONAME. This results in two XTs on the stack.

In actual fact, each forth I tested (VFX, Swift, Gforth, BigForth) has a
different runtime behaviour for MDEF.

Cheers,
Arnold

Andrew Haley

unread,
Dec 10, 2011, 1:04:22 PM12/10/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>Arnold Doray <thinks...@gmail.com> wrote:
>>>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>>>> implementation?
>>>>
>>>>No. Practice varies so much between Forths that it hasn't been
>>>>possible to standardize it.
>>>
>>> This feature should be easy to insert into any standard Forth:
>>>
>>> Add a possibly (USERized) VALUE LATESTXT, and in every place where an
>>> xt is defined, add an "is latestxt".
>>
>>Not necessarily. For example, you don't know when the latest XT is
>>defined while compiling a colon definition; it might not be until
>>after ; .
>
> Is this based on a real, standard system (i.e., practice), or do you
> just make this up to support your claim?

I don't think it needs any support: AFAIK it's allowed by the language
of the standard, even though I don't know of any existing standard
systems that do so. On the other hand, I haven't looked. On the
gripping hand, given ten minutes or so I could create a version of :
with this property, and I think it would be standard-compliant,
although I'd have to check. Its not an unreasonable thing to do, IMO:
it avoids messing about with SMUDGE or linking and unlinking the
dictionary head.

>> You don't know if there is an extra XT created by DOES> .
>
> That can be defined, just as for RECURSE; or it can be turned into an
> ambiguous condition, just as it has been done for RECURSE.
>
>>Is :NONAME included? I guess so. It's all these little gotchas that
>>make it hard.
>
> There are no special gotchas there. This is just like for any other
> word one wants to standardize: You have to specify it properly.

Yes, but I'm not sure it's possible to specify it in that much detail
without restricting the options of an implementer. The main thrust of
standard Forth (of which I very much approve) was in the opposite
direction, that of a language specification rather than an
implementation specification. Doing that involves not just allowing
all the implementation techniques that exist but leaving enough wiggle
room for those that haven't been invented.

Andrew.

Andrew Haley

unread,
Dec 10, 2011, 1:11:04 PM12/10/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Arnold Doray <thinks...@gmail.com> wrote:
>>> These forths leave junk on the stack making retrieving the :NONAME's xt
>>> "unportable".
>>
>>The XT might not even exist until after ; .
>
> The standard defines :NONAME to have the stack effect
> ( C: -- colon-sys ) ( S: -- xt )
>
> So the xt exists right after :NONAME in the standard. And I don't
> think you can argue that it's not observable until ";" removes the
> colon-sys, because we can see the whole stack with ".S". If the xt
> left after the ";" is different from each of the values we saw earlier,
> the system is not compliant.

Ah, I think you are probably right. I did think that no standard
program could tell the difference, because there's no way to get at
the XT. But perhaps there is: some jiggling with DEPTH would do it.

> Even if we ignore that, there is a practical reason for xt to exist
> before the ";": RECURSE. Without an XT, how do you implement it? I
> looked at a few systems (SwiftForth, VFX, Gforth), and RECURSE always
> calls COMPILE, in them, so the RECURSE is defined as, essentually:
>
> : RECURSE
> ... ( code equivalent to LATESTXT )
> COMPILE, ; IMMEDIATE

True. I think it can perhaps be done with an indirection, but it's
not worth the bother.

Andrew.

Albert van der Horst

unread,
Dec 10, 2011, 1:52:16 PM12/10/11
to
In article <2011Dec...@mips.complang.tuwien.ac.at>,
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Arnold Doray <thinks...@gmail.com> wrote:
>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>> implementation?
>>
>>No. Practice varies so much between Forths that it hasn't been
>>possible to standardize it.
>
>This feature should be easy to insert into any standard Forth:
>
>Add a possibly (USERized) VALUE LATESTXT, and in every place where an
>xt is defined, add an "is latestxt".
>
>So it's not that it is not standardized because there are
>implementation difficulties. It's just that nobody has tried to
>standardize it; maybe there is also too little common practice.
>
>Your PREFIX? example might be a trigger to add this feature to VFX
>Forth.

There is another hitch. You cannot do much (portably)
with an XT. What you really want is a LATEST-DEA (dictionary
entry address) LATEST-NAME , LATEST-HEADER or some such.
Then you want standard words to manipulate fields in this
latest header.

>
>- anton
>--

--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Bernd Paysan

unread,
Dec 10, 2011, 5:03:46 PM12/10/11
to
Arnold Doray wrote:

> On Sat, 10 Dec 2011 11:39:07 +0000, Anton Ertl wrote:
>
>>>Certainly, GForth and BigForth behave as if the .S is executed before
>>>the :NONAME encounters the terminating ; in the input stream.
>>
>> Correct. :NONAME does not parse the input stream in a standard
>> system. It just starts a definition; then, in your code .S prints the
>> stack, then the text interpreter performs the compilation semantics
>> of '."' and '
>
> Is this reasonable?
>
> Firstly, the spec says that :NONAME should :-
>
> Create an execution token xt,
> Enter compilation state and
> Start the current definition,
> producing colon-sys.
> Append the initiation semantics given
> below to the current definition.
>
> If the compilation state is entered, how can the next word after
> the :NONAME (ie, .S) execute?

You don't really understand this. When you write

: test :noname .s ;

the outer interpreter does the following steps:

First it encounters ':'. It currently is in interpretation state, and :
is a normal word, so it just executes it (no special interpretation or
compilation semantics. : parses "test" and creates a definition named
test, and puts the outer interpreter into compilation state (by setting
the STATE variable and maybe doing some other things, the same actions ]
does).

Now, what : does *not* do is invoke some parsing loop. We are still in
the same outer interpreter, the same parsing loop that parses the entire
line. It's now in compilation state, and encounters :noname. It
compile,s :noname's xt, because :noname is a normal word, no special
compilation semantics. The same happens for .s. ; is different, it's
immediate, it has special compilation semantics. ; reveals the
definition test (which up to now was invisible), compiles EXIT or
similar, and switches back to interpretation state (similar to [).

When you execute test, the same thing happens: :noname inside only
switches over the interpreter to compilation state, leaving an xt and
colon-sys on the stack. colon-sys is just something implementation
dependent, you don't know what it really is. All four systems you
examined show something different, yes.

IIRC, PolyForth had it the way you expect it - : and ] just started
another parsing loop, but this eliminates some possibilities. E.g. I
can write CONSTANT without CREATE DOES> that way:

: Constant >r : r> postpone literal postpone ; ;

This is a nice capability.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

BruceMcF

unread,
Dec 10, 2011, 5:21:12 PM12/10/11
to
On Dec 10, 11:31 am, Arnold Doray <thinksqua...@gmail.com> wrote:

> Create an execution token xt,
> Enter compilation state and
> Start the current definition,
>     producing colon-sys.
>     Append the initiation semantics given
>       below to the current definition.

> If the compilation state is entered, how can the next word after
> the :NONAME (ie, .S) execute?

Because TEST is still being executed. When TEST completes, the
interpreter will be in compiler state rather than interpreter state,
because of the :noname executed by TEST.

IOW, if TEST was performed from the command line, when it returns to
the interpreter that called it, the interpreter will be in compilation
state. You have *compiled* TEST to FIRST do the above, and THEN
perform a ``.S.'' and THEN return to its caller.

Arnold Doray

unread,
Dec 10, 2011, 9:34:07 PM12/10/11
to
Yes, this is exactly what I understand happens during the compilation of
TEST.

> When you execute test, the same thing happens: :noname inside only
> switches over the interpreter to compilation state, leaving an xt and
> colon-sys on the stack. colon-sys is just something implementation
> dependent, you don't know what it really is. All four systems you
> examined show something different, yes.
>

This is the part I have trouble understanding.

When TEST executes, it executes :NONAME first, which puts the colon-sys
on the stack and switches over to *compilation* state. This is crystal
clear from the '94 Spec. Yes, I know the colon-sys is implementation
dependent. Also clear from the spec.

The issue I have is that now forth is in *compilation* state. Shouldn't
the text parser parse the input stream *immediately*, before moving on to
the next word in TEST?

As an analogy, the words [ and ] immediately switch the forth between
interpretative and compilation states. So I thought once you're in
compilation state, the text-parser should be doing its thing immediately.

Do you see?

I'm saying it is non-intuitive if the text-parser does not kick in
immediately after :NONAME executes. The system is already in compilation
state.

The forths I have tested are effectively behaving as if the text-parser
starts after the TEST executes. Why then? This seems arbitrary to me and
not at all a sensible choice.


> IIRC, PolyForth had it the way you expect it - : and ] just started
> another parsing loop, but this eliminates some possibilities. E.g. I
> can write CONSTANT without CREATE DOES> that way:
>
> : Constant >r : r> postpone literal postpone ; ;
>
> This is a nice capability.

Really? I don't think modern forths use CREATE DOES> to define constants.
Also, doesn't your example rely on return stack fiddling which I
understand is not portable?

I would prefer a sensible :NONAME. You can do a lot with it. Portably.

Cheers,
Arnold







Arnold Doray

unread,
Dec 10, 2011, 9:37:25 PM12/10/11
to
On Sat, 10 Dec 2011 14:21:12 -0800, BruceMcF wrote:

> Because TEST is still being executed. When TEST completes, the
> interpreter will be in compiler state rather than interpreter state,
> because of the :noname executed by TEST.

No, this is not what the spec says.

The spec clearly says that when :NONAME executes the system is in
compilation state. I quote:

"Create an execution token xt, *enter compilation state* and start the
current definition, producing colon-sys."

All these are done right after :NONAME executes.

Cheers,
Arnold

Elizabeth D. Rather

unread,
Dec 10, 2011, 11:01:54 PM12/10/11
to
On 12/10/11 4:34 PM, Arnold Doray wrote:
> On Sat, 10 Dec 2011 23:03:46 +0100, Bernd Paysan wrote:
>
...
No. The fact that the system is in compilation state influences what the
text interpreter will do when it runs, but doesn't immediately launch
it. The text interpreter won't become active until TEST finishes executing.

I can write a word like this:

: mycolon : here . 100 0 do i . loop cr ." Hello world" ;

...and if I then say:

mycolon foo ." Goodbye cruel world" ;

...then foo will compile perfectly normally, but a whole bunch of stuff
will happen before the actual compilation commences.

> As an analogy, the words [ and ] immediately switch the forth between
> interpretative and compilation states. So I thought once you're in
> compilation state, the text-parser should be doing its thing immediately.
>
> Do you see?

I see that you have a mistaken impression of how the text interpreter
works. It operates *either* when you explicitly invoke it with a word
that parses *or* when everything that is executing is done and control
passes to the text interpreter to process the input stream. :noname
does not invoke the text interpreter explicitly. : does, but only long
enough to get the name of the definition to be created.

> I'm saying it is non-intuitive if the text-parser does not kick in
> immediately after :NONAME executes. The system is already in compilation
> state.
>
> The forths I have tested are effectively behaving as if the text-parser
> starts after the TEST executes. Why then? This seems arbitrary to me and
> not at all a sensible choice.

That is exactly the way it works and the way it's described in, for
example, the flow-chart in my books that describes the text interpreter.

>> IIRC, PolyForth had it the way you expect it - : and ] just started
>> another parsing loop, but this eliminates some possibilities. E.g. I
>> can write CONSTANT without CREATE DOES> that way:
>>
>> : Constant>r : r> postpone literal postpone ; ;
>>
>> This is a nice capability.

It drove people nuts. Suppose you typed:

: foo ( -- ) doors 0 do

...and then thought to yourself, wait a minute, what's the value of
doors again? So you type:

doors .

...You will then be very confused because the system just says, "ok"
without executing doors and . because what has happened is that the
compiler kept right on compiling the definition foo including a
reference to doors and . and is still compiling, and will continue until
you type ; or an error occurs.

It seemed nice at the time, but caused a lot of trouble.

> Really? I don't think modern forths use CREATE DOES> to define constants.

They can, and many do:

: CONSTANT ( n -- ) CREATE , DOES> ( -- n ) @ ;

> Also, doesn't your example rely on return stack fiddling which I
> understand is not portable?

I'm not wild about that example, myself.

> I would prefer a sensible :NONAME. You can do a lot with it. Portably.

It is intended to be, and is, exactly like : without a name for the
compiled code. Why don't you tell us what you're trying to do, and maybe
we can help find a way to do it?

Andrew Haley

unread,
Dec 11, 2011, 4:35:09 AM12/11/11
to
Bernd Paysan <bernd....@gmx.de> wrote:

> IIRC, PolyForth had it the way you [Arnold Doray] expect it - : and
> ] just started another parsing loop, but this eliminates some
> possibilities. E.g. I can write CONSTANT without CREATE DOES> that
> way:
>
> : Constant >r : r> postpone literal postpone ; ;

polyFORTH could (can?) do that too, just a different way:

: CONSTANT CREATE colon USE COMPILE LITERAL COMPILE ; ;

... which I think I prefer, really.

Andrew.

Arnold Doray

unread,
Dec 11, 2011, 4:46:10 AM12/11/11
to
On Sat, 10 Dec 2011 18:01:54 -1000, Elizabeth D. Rather wrote:

>
> I see that you have a mistaken impression of how the text interpreter
> works. It operates *either* when you explicitly invoke it with a word
> that parses *or* when everything that is executing is done and control
> passes to the text interpreter to process the input stream. :noname
> does not invoke the text interpreter explicitly. : does, but only long
> enough to get the name of the definition to be created.
>

Thanks. That's a very clear explanation of when the text parser executes.

But I still think it's not the best way of doing things. It is much nicer
for :NONAME to invoke the text parser before the next word runs. Because:

A) You can do a lot more with :NONAME since the resulting xt is available
to the following word.

B) You can process multiple definitions at one go. Eg,

: mdef :noname <do-something> :noname <do-something-else> ;

This last definition doesn't even have a defined semantics in the current
way of doing things. But it is trivial to understand what it does
if :NONAME kicks off the text-parser immediately.

I'm just curious why the behaviour I've outlined above isn't used, since
it both simplifies the semantics of :NONAME and extends its usability.

Cheers,
Arnold


Andrew Haley

unread,
Dec 11, 2011, 4:55:15 AM12/11/11
to
Arnold Doray <thinks...@gmail.com> wrote:
> On Sat, 10 Dec 2011 18:01:54 -1000, Elizabeth D. Rather wrote:
>
>>
>> I see that you have a mistaken impression of how the text interpreter
>> works. It operates *either* when you explicitly invoke it with a word
>> that parses *or* when everything that is executing is done and control
>> passes to the text interpreter to process the input stream. :noname
>> does not invoke the text interpreter explicitly. : does, but only long
>> enough to get the name of the definition to be created.
>>
>
> Thanks. That's a very clear explanation of when the text parser executes.
>
> But I still think it's not the best way of doing things. It is much nicer
> for :NONAME to invoke the text parser before the next word runs. Because:
>
> A) You can do a lot more with :NONAME since the resulting xt is available
> to the following word.
>
> B) You can process multiple definitions at one go. Eg,
>
> : mdef :noname <do-something> :noname <do-something-else> ;
>
> This last definition doesn't even have a defined semantics in the current
> way of doing things.

I think you'll find it does. MDEF creates two :noname definitions.

> But it is trivial to understand what it does if :NONAME kicks off
> the text-parser immediately.
>
> I'm just curious why the behaviour I've outlined above isn't used, since
> it both simplifies the semantics of :NONAME and extends its usability.

It's partly historical baggage, and partly how things have evolved. I
think you have to bear in mind that other ways have been tried, and
after a lot of experience and experimentation the current behaviour
was adopted.

Andrew.

Anton Ertl

unread,
Dec 11, 2011, 5:21:57 AM12/11/11
to
Arnold Doray <thinks...@gmail.com> writes:
>On Sat, 10 Dec 2011 23:03:46 +0100, Bernd Paysan wrote:
>When TEST executes, it executes :NONAME first, which puts the colon-sys
>on the stack and switches over to *compilation* state. This is crystal
>clear from the '94 Spec. Yes, I know the colon-sys is implementation
>dependent. Also clear from the spec.
>
>The issue I have is that now forth is in *compilation* state. Shouldn't
>the text parser parse the input stream *immediately*, before moving on to
>the next word in TEST?

No. Compilation state is just a state of a variable. It just
modifies the behaviour of words that read the variable, in particular
the text interpreter. But the word that's currently running is TEST,
and this word does not change what it does depending on STATE. So it
continues, performing .S and then the run-time semantics of ";". The
latter returns execution to the text interpreter, which then performs
the compilation semantics of the words in the input stream.

>As an analogy, the words [ and ] immediately switch the forth between
>interpretative and compilation states.

They also just change the state, and they change it when they are
executed (in particular, ] is not immediate, and [ can be POSTPONEd or
ticked). The effect of this state change also only affects words that
read the state, in particular the text interpreter.

Anton Ertl

unread,
Dec 11, 2011, 5:43:52 AM12/11/11
to
"Elizabeth D. Rather" <era...@forth.com> writes:
>It drove people nuts. Suppose you typed:
>
>: foo ( -- ) doors 0 do
>
>...and then thought to yourself, wait a minute, what's the value of
>doors again? So you type:
>
>doors .
>
>...You will then be very confused because the system just says, "ok"
>without executing doors and . because what has happened is that the
>compiler kept right on compiling the definition foo including a
>reference to doors and . and is still compiling, and will continue until
>you type ; or an error occurs.
>
>It seemed nice at the time, but caused a lot of trouble.

I don't see the difference between the Forth-94 behaviour and the
PolyForth behaviour here.

Anton Ertl

unread,
Dec 11, 2011, 5:47:50 AM12/11/11
to
Not

: CONSTANT CREATE colon USE [COMPILE] LITERAL [COMPILE] ; ;

?

The COMPILE I know does not parse and is not very appropriate for most
immediate words. But then I don't know PolyForth.

Anton Ertl

unread,
Dec 11, 2011, 5:50:42 AM12/11/11
to
Albert van der Horst <alb...@spenarnc.xs4all.nl> writes:
>There is another hitch. You cannot do much (portably)
>with an XT.

You can EXECUTE it and you can COMPILE, it.

> What you really want is a LATEST-DEA (dictionary
>entry address) LATEST-NAME , LATEST-HEADER or some such.

Yes, that's traditionally called LATEST, and Gforth has it, too.
However, the DEA/nt/NFA is not a standard concept, so you can do
nothing with that in standard programs. And there is very little
chance of it being standardized (not for technical reasons).

In any case, neither of these words is a replacement for the other,
because

1) There are words with an xt that do not necessarily have a
DEA/nt/NFA (unnamed words), so LATEST cannot be used to build
LATESTXT.

2) On some systems (including Gforth) there is no reliable way to get
from the xt to the DEA/nt/NFA, so LATESTXT cannot be used to build
LATEST.

Anton Ertl

unread,
Dec 11, 2011, 6:02:38 AM12/11/11
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>>Arnold Doray <thinks...@gmail.com> wrote:
>>>>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>>>>> implementation?
>>>>>
>>>>>No. Practice varies so much between Forths that it hasn't been
>>>>>possible to standardize it.
>>>>
>>>> This feature should be easy to insert into any standard Forth:
>>>>
>>>> Add a possibly (USERized) VALUE LATESTXT, and in every place where an
>>>> xt is defined, add an "is latestxt".
>>>
>>>Not necessarily. For example, you don't know when the latest XT is
>>>defined while compiling a colon definition; it might not be until
>>>after ; .
>>
>> Is this based on a real, standard system (i.e., practice), or do you
>> just make this up to support your claim?
>
>I don't think it needs any support: AFAIK it's allowed by the language
>of the standard, even though I don't know of any existing standard
>systems that do so.

So it's not that practice varies; you just claimed that it does,
without any support.

>Yes, but I'm not sure it's possible to specify it in that much detail
>without restricting the options of an implementer.

It's not: Any specification, however weak, restricts the options of
the implementor. E.g., the specification of FILE-STATUS, useless as
it is, still restricts the option of the implementor to implement a
word called FILE-STATUS that has a different stack effect, and still
call his system standard.

I think that that's not a useful argument. If it was, we should stop
with our standardization work: We cannot add features because that
restricts the options of the system implementors, and we cannot remove
features because that breaks (potential) programs.

I think useful arguments are based on practice. If you can name a
system where LATESTXT would be hard or impossible to implement, that
would be a good counterargument. If I can name a number of programs
where LATESTXT was used to significant advantage, that would be a good
pro-argument.

Anton Ertl

unread,
Dec 11, 2011, 6:25:59 AM12/11/11
to
Arnold Doray <thinks...@gmail.com> writes:
>: mdef :noname :noname ;

The first :noname starts a colon definition and sets compilation
state, and leaves an xt and a colon-sys on the stack. The second one
typically does the same, although it's probably not defined what
happens when you start a colon definition while there is an unfinished
definition pending.

Arnold Doray

unread,
Dec 11, 2011, 6:35:43 AM12/11/11
to
On Sun, 11 Dec 2011 03:55:15 -0600, Andrew Haley wrote:

>> B) You can process multiple definitions at one go. Eg,
>>
>> : mdef :noname <do-something> :noname <do-something-else> ;
>>
>> This last definition doesn't even have a defined semantics in the
>> current way of doing things.
>
> I think you'll find it does. MDEF creates two :noname definitio

No, it shouldn't.

In the current behaviour, the first :NONAME sets the compilation flag and
puts the <xt><colon-sys> on the stack. The second :NONAME does the same.
When the text parser finally kicks in, it parses the input stream until ;
which clears the top <colon-sys> and resets the compilation state to
interpretation. This leaves <xt><colon-sys><xt'> on the stack. Only the
top xt' works. Also, because the compilation flag is cleared, the system
no longer parses the next definition. ( And even if it did, it would be
wrong since the <xt><colon-sys> is below <xt'> ).

Isn't this silly?

I tested Swift, Gforth and BigForth, which all behave this way.

VFX just gives an error.

Can you see why I say it's much more sensible to just kick off the text
parser immediately after :NONAME? Then you would indeed end up with two
working XTs:

: mdef :noname :noname ;

mdef ." bingo" ; ." little" ; ok \ DOES NOT WORK!
execute little ok \ DOES NOT HAPPEN!
execute bingo ok \ DOES NOT HAPPEN!

Cheers,
Arnold








Andrew Haley

unread,
Dec 11, 2011, 1:21:04 PM12/11/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>>>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>>>>Arnold Doray <thinks...@gmail.com> wrote:
>>>>>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a portable
>>>>>>> implementation?
>>>>>>
>>>>>>No. Practice varies so much between Forths that it hasn't been
>>>>>>possible to standardize it.
>>>>>
>>>>> This feature should be easy to insert into any standard Forth:
>>>>>
>>>>> Add a possibly (USERized) VALUE LATESTXT, and in every place where an
>>>>> xt is defined, add an "is latestxt".
>>>>
>>>>Not necessarily. For example, you don't know when the latest XT is
>>>>defined while compiling a colon definition; it might not be until
>>>>after ; .
>>>
>>> Is this based on a real, standard system (i.e., practice), or do you
>>> just make this up to support your claim?
>>
>>I don't think it needs any support: AFAIK it's allowed by the language
>>of the standard, even though I don't know of any existing standard
>>systems that do so.
>
> So it's not that practice varies; you just claimed that it does,
> without any support.

I did not claim any such thing.

>>Yes, but I'm not sure it's possible to specify it in that much detail
>>without restricting the options of an implementer.
>
> It's not: Any specification, however weak, restricts the options of
> the implementor. E.g., the specification of FILE-STATUS, useless as
> it is, still restricts the option of the implementor to implement a
> word called FILE-STATUS that has a different stack effect, and still
> call his system standard.
>
> I think that that's not a useful argument. If it was, we should stop
> with our standardization work: We cannot add features because that
> restricts the options of the system implementors, and we cannot remove
> features because that breaks (potential) programs.

I don't think that this reductio ad absurdum argument illuminates very
much. IMO, any new restrictions on Forth implementations should be
considered very carefully. If it produces something highly desirable,
a new restriction may be justified. However, several recent threads
on c.l.f. seem to me to have been of the form "How can I do X? You
can't. But let's standardize Y, and then you could." Let's not add
any more redundant language features.

> I think useful arguments are based on practice.

That's wholly backward-looking, though. I think that arguments should
also be based on what is possible in the future. For example, ANS
Forth to some extent anticipated Forth optimizers, which existed only
in a very crude form at the time. It did this by not specifying
implementation, but behaviour, with considerable success.

> If you can name a system where LATESTXT would be hard or impossible
> to implement, that would be a good counterargument. If I can name a
> number of programs where LATESTXT was used to significant advantage,
> that would be a good pro-argument.

That's true. As I said above, if it produces something highly
desirable, a new restriction [on implementers] may be justified. But
I am suggesting that the bar should be set at "highly desirable".
IMO, minor notational convenience isn't sufficient justification.

Andrew.

Elizabeth D. Rather

unread,
Dec 11, 2011, 1:55:53 PM12/11/11
to
On 12/11/11 1:25 AM, Anton Ertl wrote:
> Arnold Doray<thinks...@gmail.com> writes:
>> : mdef :noname :noname ;
>
> The first :noname starts a colon definition and sets compilation
> state, and leaves an xt and a colon-sys on the stack. The second one
> typically does the same, although it's probably not defined what
> happens when you start a colon definition while there is an unfinished
> definition pending.

[Forth94] 3.4.5 Compilation
A program shall not attempt to nest compilation of definitions.
During the compilation of the current definition, a program shall not
execute any defining word, :NONAME, or any definition that allocates
dictionary data space. The compilation of the current definition may be
suspended using [ (left-bracket) and resumed using ] (right-bracket).
While the compilation of the current definition is suspended, a program
shall not execute any defining word, :NONAME, or any definition that
allocates dictionary data space.

BruceMcF

unread,
Dec 11, 2011, 2:05:03 PM12/11/11
to
On Dec 11, 4:46 am, Arnold Doray <thinksqua...@gmail.com> wrote:
> But I still think it's not the best way of doing things. It is
> much nicer for :NONAME to invoke the text parser before the next
> word runs.

You are proposing burning down the village to try to open a locked
door. What you are proposing is to completely abandon the incremental
compiler system and convert Forth to an all-interpreted language. The
whole *point* of the compiled definition is that the words execute *in
the sequence* that you specify.

Indeed, if :noname implicitly invoked the interpreter ... when would
the interpreter *stop* interpreting and go *back to* executing the
rest of the word that contains :noname ?

BruceMcF

unread,
Dec 11, 2011, 2:13:56 PM12/11/11
to
Yes. That's what I said. But its not the text interpreter that
executes .S ~ its the execution of the word TEST. So the state of the
text interpreter does not modify the fact that .S is compiled into
TEST immediately after :NONAME with no flow control words in between,
and so execution of .S must happen immediately after execution
of :NONAME.

IOW, its the execution of TEST that executes .S and the state of the
text interpreter does not matter until TEST *returns to* the text
interpreter.

Elizabeth D. Rather

unread,
Dec 11, 2011, 3:59:17 PM12/11/11
to
On 12/11/11 1:35 AM, Arnold Doray wrote:
> On Sun, 11 Dec 2011 03:55:15 -0600, Andrew Haley wrote:
>
>>> B) You can process multiple definitions at one go. Eg,
>>>
>>> : mdef :noname<do-something> :noname<do-something-else> ;
>>>
>>> This last definition doesn't even have a defined semantics in the
>>> current way of doing things.
>>
>> I think you'll find it does. MDEF creates two :noname definitio
>
> No, it shouldn't.

I agree, this time. It shouldn't because the effect is to nest
definitions: the second :NONAME is executing while the system was
prepared to construct something useful. Attempting to nest definitions
is explicitly called out as an error in ANS Forth.

> In the current behaviour, the first :NONAME sets the compilation flag and
> puts the<xt><colon-sys> on the stack. The second :NONAME does the same.
> When the text parser finally kicks in, it parses the input stream until ;
> which clears the top<colon-sys> and resets the compilation state to
> interpretation. This leaves<xt><colon-sys><xt'> on the stack. Only the
> top xt' works. Also, because the compilation flag is cleared, the system
> no longer parses the next definition. ( And even if it did, it would be
> wrong since the<xt><colon-sys> is below<xt'> ).
>
> Isn't this silly?

It depends on your definition of "silly". I think it's behaving exactly
as specified, and attempting to put two :nonames in a colon definition
is silly. IMO even putting one :noname in a colon definition is silly.
That is not how these words are supposed to be used. What you're doing
is silly in the same way that attempting to use a screwdriver to hammer
nails is silly. Don't blame the screwdriver for your failure.

BruceMcF

unread,
Dec 11, 2011, 4:26:13 PM12/11/11
to
On Dec 11, 6:35 am, Arnold Doray <thinksqua...@gmail.com> wrote:
> In the current behaviour, the first :NONAME sets the compilation flag
> and puts the <xt><colon-sys> on the stack. The second :NONAME does the
> same. When the text parser finally kicks in, it parses the input
> stream until ; which clears the top <colon-sys> and resets the
> compilation state to interpretation. This leaves <xt><colon-sys><xt'>
> on the stack. Only the top xt' works. Also, because the compilation
> flag is cleared, the system no longer parses the next definition.
> ( And even if it did, it would be wrong since the <xt><colon-sys>
> is below <xt'> ).

> Isn't this silly?

Doing something silly when the program asks for something silly to be
done ... yes its silly to ask the compiler to do that, but unless the
compiler promises to be sandboxed against being asked to do silly
things, there's nothing particularly silly about a given compiler
doing whatever happens to occur when you try to improperly nest
definitions.

This is the point of the quotations idea raised in some thread
sometime this last week ...
... [: ... ;] ...
... in the context of a definition could be is embedded into the
definition like:
... S" ..." ...
... is embedded in a definition, so that at runtime, execution passes
over the quotation and pushes the XT of the quotation on the stack.
Since its not a definition, there's no particular impediment to
nesting quotations.

Josh Grams

unread,
Dec 11, 2011, 6:25:29 PM12/11/11
to
BruceMcF wrote:
At semicolon, or [, whatever changes back to interpretation state, of
course. There are (or have been) Forth systems which work this way;
it's just not ANS-compatible. There's even a note in one of the ANS
rationale sections to that effect. Basic Forth code works the same on
both; it's only when you go constructing definitions with postpone that
you would even notice the difference.

And in those other systems it is pretty easy to create definitions the
ANS way if that's what you want; easier, in fact, than doing it the
other way from an ANS system. So you could possibly construct a good
argument that the other way is actually better. But this is what we
have, and like it or not, since the two are not compatible, there's no
realistic way to change it at this point.

(Not that I'm complaining about the way things are, just pointing out
that there aren't *overwhelming* technical problems with having separate
interpretation and compilation loops).

--Josh

BruceMcF

unread,
Dec 11, 2011, 7:58:00 PM12/11/11
to
On Dec 11, 6:25 pm, Josh Grams <j...@qualdan.com> wrote:
> BruceMcF wrote:
> > Indeed, if :noname implicitly invoked the interpreter ... when would
> > the interpreter *stop* interpreting and go *back to* executing the
> > rest of the word that contains :noname ?

> At semicolon, or [, whatever changes back to interpretation state, of
> course.

That sounds incredibly brittle. You are going along with your :noname
based definer ...

S" foo" []:: <code> ;

... fine. Then somewhere along the way, someone modifies it because
there are two different was to do things, on two different systems ...

S" foo" []:: <code> [ test? ] [IF] <alt1> [ELSE] <alt2> [THEN] ;

... except now instead of the words executing after :noname in []::
executing when the ";" executes, when it presumably grabs the xt and
does something to it ...

... it executes before "test?" when there is no xt to grab.

Better do what you gotta do up front in one word, then do what you
gotto do at the end in a second word:

S" foo" [:: <code> ;;]

Arnold Doray

unread,
Dec 11, 2011, 9:19:00 PM12/11/11
to
On Sun, 11 Dec 2011 10:59:17 -1000, Elizabeth D. Rather wrote:

> On 12/11/11 1:35 AM, Arnold Doray wrote:
>> On Sun, 11 Dec 2011 03:55:15 -0600, Andrew Haley wrote:
>>
>>>> B) You can process multiple definitions at one go. Eg,
>>>>
>>>> : mdef :noname<do-something> :noname<do-something-else> ;
>>>>
>>>> This last definition doesn't even have a defined semantics in the
>>>> current way of doing things.
>>>
>>> I think you'll find it does. MDEF creates two :noname definitio
>>
>> No, it shouldn't.
>
> I agree, this time. It shouldn't because the effect is to nest
> definitions: the second :NONAME is executing while the system was
> prepared to construct something useful. Attempting to nest definitions
> is explicitly called out as an error in ANS Forth.
>

Exactly. If the text parser kicks off after the MDEF completes, then the
definitions are indeed nested. But if the text parser is immediately
triggered by :NONAME then the definitions are serialized.

What I am trying to understand is the *rationale* behind the current
behaviour. I'm sure that there is a good explanation, but it eludes me.

>> In the current behaviour, the first :NONAME sets the compilation flag
>> and puts the<xt><colon-sys> on the stack. The second :NONAME does the
>> same. When the text parser finally kicks in, it parses the input stream
>> until ; which clears the top<colon-sys> and resets the compilation
>> state to interpretation. This leaves<xt><colon-sys><xt'> on the stack.
>> Only the top xt' works. Also, because the compilation flag is cleared,
>> the system no longer parses the next definition. ( And even if it did,
>> it would be wrong since the<xt><colon-sys> is below<xt'> ).
>>
>> Isn't this silly?
>
> It depends on your definition of "silly". I think it's behaving exactly
> as specified, and attempting to put two :nonames in a colon definition
> is silly. IMO even putting one :noname in a colon definition is silly.
> That is not how these words are supposed to be used. What you're doing
> is silly in the same way that attempting to use a screwdriver to hammer
> nails is silly. Don't blame the screwdriver for your failure.
>

I'm simply trying to understand the rationale behind the current
behaviour.

I've explained how you can simplify the semantics of :NONAME and extend
its range of use at the same time, without impacting current code. Surely
that's "Forth Way"?

Cheers,
Arnold

Arnold Doray

unread,
Dec 11, 2011, 10:21:44 PM12/11/11
to
On Sun, 11 Dec 2011 11:05:03 -0800, BruceMcF wrote:

> On Dec 11, 4:46 am, Arnold Doray <thinksqua...@gmail.com> wrote:
>> But I still think it's not the best way of doing things. It is much
>> nicer for :NONAME to invoke the text parser before the next word runs.
>
> You are proposing burning down the village to try to open a locked door.
> What you are proposing is to completely abandon the incremental compiler
> system and convert Forth to an all-interpreted language. The whole
> *point* of the compiled definition is that the words execute *in the
> sequence* that you specify.

Just in case there's a misunderstanding, let me try to describe clearly:

: mdef :noname :noname ;

Here's what I propose should happen to something like:

mdef ." bingo" ; ." rover" ;

1) MDEF executes.

2) The first :NONAME executes, putting <xt1><colon-sys> on the stack and
switches to compilation state. My proposal is that it also kicks off the
text parser.

3) The text parser reads from the input stream. It parses ." bingo" into
the current XT and terminates at ; because ; is immediate. ; signals an
end to the parsing and removes <colon-sys> from the stack.

4) At this point, in ANS forth, the text parsing will continue with
." rover" and executing it. It then goes on to the next ; giving an error
since we are now in interpretative state. My proposal is that the text
parser instead be suspended after the first ; and control passed back to
the next word to execute.

5) The next :NONAME executes, steps (2) and (3) are repeated. The stack
is now <xt1><xt2>.

6) MDEF terminates.

And the advantages:

1) All definitions are serialized. This makes the semantics of :NONAME
obvious.

2) It increases the range of use of :NONAME. For instance, the MDEF would
work. Currently it does not.

3) The XT of the :NONAME would be available to definitions following it.

4) It doesn't break existing code, as far as I can see.

In fact, as others have pointed out, polyForth behaved this way. If true,
it's been done in the past. The current forths I've tested, include
GForth don't do this.

It is the "why" I am interested in. There must be a good reason. I
suspect it's because it involves changing the behaviour of ; to pass
control to the next word, instead of letting the text parser continue
(step 4).

In any case, I don't see how the changes in (2) and (4) convert Forth to
an "all-interpretative" language as you claim. Could you please elaborate?

Thanks,
Arnold













Elizabeth D. Rather

unread,
Dec 11, 2011, 10:38:30 PM12/11/11
to
On 12/11/11 4:19 PM, Arnold Doray wrote:
...
>>> In the current behaviour, the first :NONAME sets the compilation flag
>>> and puts the<xt><colon-sys> on the stack. The second :NONAME does the
>>> same. When the text parser finally kicks in, it parses the input stream
>>> until ; which clears the top<colon-sys> and resets the compilation
>>> state to interpretation. This leaves<xt><colon-sys><xt'> on the stack.
>>> Only the top xt' works. Also, because the compilation flag is cleared,
>>> the system no longer parses the next definition. ( And even if it did,
>>> it would be wrong since the<xt><colon-sys> is below<xt'> ).
>>>
>>> Isn't this silly?
>>
>> It depends on your definition of "silly". I think it's behaving exactly
>> as specified, and attempting to put two :nonames in a colon definition
>> is silly. IMO even putting one :noname in a colon definition is silly.
>> That is not how these words are supposed to be used. What you're doing
>> is silly in the same way that attempting to use a screwdriver to hammer
>> nails is silly. Don't blame the screwdriver for your failure.
>>
>
> I'm simply trying to understand the rationale behind the current
> behaviour.
>
> I've explained how you can simplify the semantics of :NONAME and extend
> its range of use at the same time, without impacting current code. Surely
> that's "Forth Way"?

It's hard to imagine simplifying the semantics of :NONAME beyond what
they are:

"Create an execution token xt, enter compilation state and start the
current definition, producing colon-sys."

You would have it also actually start running the text interpreter. That
would be inconsistent with virtually every system in existence.
Moreover, if you're advocating permitting colon definitions to nest,
that's a whole massive can of worms for which rules need to be defined
that will cover ITC, DTC, compile-to-code, and optimizing compilers in
some transparently consistent way. The mind boggles.

As far as "extending the range of use" of :noname, no one but you seems
to perceive a need, and I'm not sure what that is. Strings of nameless
bits of code with xts floating around are a nightmare to manage. Truly,
it's much easier to just make definitions with names and reference them
when you want to.

Elizabeth D. Rather

unread,
Dec 11, 2011, 10:52:13 PM12/11/11
to
I understand what you want. You want the compilation to nest, somehow.
Do you advocate extending this behavior to : ? Do you understand what
havoc this can create with optimizing compilers?

> 6) MDEF terminates.
>
> And the advantages:
>
> 1) All definitions are serialized. This makes the semantics of :NONAME
> obvious.

The semantics of :NONAME are already obvious. They just aren't what you
want them to be.

> 2) It increases the range of use of :NONAME. For instance, the MDEF would
> work. Currently it does not.
>
> 3) The XT of the :NONAME would be available to definitions following it.

Why would this be better than having named definitions?

> 4) It doesn't break existing code, as far as I can see.

It absolutely does. No system behaves this way. The text interpreter is
a simple structure, with simple rules. As soon as you start allowing
compilation to nest the simplicity of the atomic text interpreter is broken.

> In fact, as others have pointed out, polyForth behaved this way. If true,
> it's been done in the past. The current forths I've tested, include
> GForth don't do this.

No. polyFORTH had separate compile and interpret loops. It most
assuredly did not support nested compilation or do what you're talking
about. And when FORTH, Inc. changed to the current ANS Forth-compatible
model, it was an improvement on all fronts.

> It is the "why" I am interested in. There must be a good reason. I
> suspect it's because it involves changing the behaviour of ; to pass
> control to the next word, instead of letting the text parser continue
> (step 4).

It involves coupling the text interpreter to compilation in ways that
open cans of worms that no one wants to deal with.

> In any case, I don't see how the changes in (2) and (4) convert Forth to
> an "all-interpretative" language as you claim. Could