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

LatestXT

73 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 you please elaborate?

I would not use that term, but I assure you it's a significant change
whose benefit is unclear and whose consequences are unattractive.

Andrew Haley

unread,
Dec 12, 2011, 4:51:03 AM12/12/11
to
Arnold Doray <thinks...@gmail.com> 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.
>
> 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'> ).

I am assuming that <do-something> does a postpone ; at some point
before the next :noname . Otherwise it's not legal code.

> Can you see why I say it's much more sensible to just kick off the text
> parser immediately after :NONAME?

Yes, I can. So, if you want to do that, just do it.

Andrew.

Andrew Haley

unread,
Dec 12, 2011, 4:54:24 AM12/12/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>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 ; ;
>
> Not
>
> : CONSTANT CREATE colon USE [COMPILE] LITERAL [COMPILE] ; ;
>
> ?

You are right. That was a thinko of mine.

Andrew.

Stephen Pelc

unread,
Dec 12, 2011, 5:34:27 AM12/12/11
to
On Mon, 12 Dec 2011 02:19:00 +0000 (UTC), Arnold Doray
<thinks...@gmail.com> wrote:

>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.

You are thinking of :NONAME in the form
:NONAME .... ;

Think of it as a constructor. e.g.

: hex: \ -- xt
:noname
postpone base postpone @ postpone >r
postpone hex
;

: ;hex \ --
postpone r> postpone base postpone !
postpone ;
;

The behaviour of :NONAME works very well in this situation.

Stephen


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

Arnold Doray

unread,
Dec 12, 2011, 6:14:32 AM12/12/11
to
On Mon, 12 Dec 2011 03:51:03 -0600, Andrew Haley wrote:

> Arnold Doray <thinks...@gmail.com> 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.
>>
>> 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'> ).
>
> I am assuming that <do-something> does a postpone ; at some point before
> the next :noname . Otherwise it's not legal code.
>

Do you mean:

: mdef :noname postpone ; :noname ;

Well, it doesn't work either:

When MDEF is executed:

1) The first :NONAME puts <xt1><colon-sys1> on the stack, creates the
definition and sets compilation state.

2) The postponed ; runs immediately completing the previous, empty
definition. It removes the <colon-sys1>, you're left with a NOOP <xt1> on
the stack.

3) The next :NONAME runs. The stack contains <xt1><xt2><colon-sys2>.

4) Finally the text parser runs, hits the ; and completes the definition.
leaving <xt1><xt2> on the stack.

So you're left with two XTs. The top one executes your definition. The
bottom one is a NOOP.

>> Can you see why I say it's much more sensible to just kick off the text
>> parser immediately after :NONAME?
>
> Yes, I can. So, if you want to do that, just do it.
>

How??

I've seen words in the spec called WORD or the newer PARSE, but I don't
understand how they work in this context.

Thanks,
Arnold

Andrew Haley

unread,
Dec 12, 2011, 6:37:47 AM12/12/11
to
Right. You've created an empty colon definition. I don't know why
you'd want to do that, but it is legal.

> 3) The next :NONAME runs. The stack contains <xt1><xt2><colon-sys2>.
>
> 4) Finally the text parser runs, hits the ; and completes the definition.
> leaving <xt1><xt2> on the stack.
>
> So you're left with two XTs. The top one executes your definition. The
> bottom one is a NOOP.

Correct. As I said:

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

>>> Can you see why I say it's much more sensible to just kick off the text
>>> parser immediately after :NONAME?
>>
>> Yes, I can. So, if you want to do that, just do it.
>
> How??

I suppose the easiest way would be to grab some text (with PARSE) and
feed it to EVALUATE . I don't know what problem that would solve,
though.

I think you're looking at it the wrong way by trying to push a problem
through a filter of how you think Forth should work, rather than how
it does work. This isn't a profitable way to proceed. What are you
trying to do with this?

Andrew

Bernd Paysan

unread,
Dec 12, 2011, 6:58:33 AM12/12/11
to
Arnold Doray 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. It is in compilation state, but the text parser now has called
TEST, and waits for TEST to return. Once TEST returns, the text parser
will parse the next word, and, since it is in compilation state now,
compile it, and repeat (parse another word, compile it, etc.).

:NONAME is not calling the text parser.

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

Bernd Paysan

unread,
Dec 12, 2011, 7:22:06 AM12/12/11
to
Elizabeth D. Rather wrote:
> 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.

It's actually not that bad. The implementations of [: ;] (nesting
unnamed definitions) are a few lines, and to make them work in VFX
requires a little bit other platform specific code than in bigForth or
Gforth. No big difference, only a small difference.

The way to go is to use AHEAD ... THEN to jump over the allocated memory
area of the nested function. And then to save and restore all the
internal state necessary for the compiler to proceed - that's the LATEST
variable or something similar, and some internal state of the locals.
And in VFX you have to tell the inliner, that this function should not
be inlined.

Stephen and I had some discussion about this sort of nesting a while
ago, and there are other places where you want to put some random data
inside a definition, similar to a string, but not identical - the i18n
wordset has this localized string constant, which is an opaque type, and
a sort-of database entry.

The IMHO "right" factors for this would be a word which postpones the
AHEAD and saves the compiler state, and another word which restores the
compiler state and postpones the THEN, let's call it save[ and ]restore
(both non-immediate, they are only building blocks). So

: [: save[ :noname ;
: ;] postpone ; >r ]restore r> postpone Literal ; immediate

could be defined portably, just as putting a string would be portable
with

: s" save[ [char] " parse tuck here swap move here swap dup allot
>r >r ]restore r> postpone literal r> postpone literal ;
immediate

Most of the time, named definitions are better, though.

Arnold Doray

unread,
Dec 12, 2011, 7:32:41 AM12/12/11
to
On Mon, 12 Dec 2011 10:34:27 +0000, Stephen Pelc wrote:

> On Mon, 12 Dec 2011 02:19:00 +0000 (UTC), Arnold Doray
> <thinks...@gmail.com> wrote:
>
>>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.
>
> You are thinking of :NONAME in the form
> :NONAME .... ;
>
> Think of it as a constructor. e.g.
>
> : hex: \ -- xt
> :noname
> postpone base postpone @ postpone >r postpone hex
> ;
>
> : ;hex \ --
> postpone r> postpone base postpone ! postpone ;
> ;
>
> The behaviour of :NONAME works very well in this situation.
>
> Stephen

Finally some clarity! Your idea is probably clearer with quotations:

: hex:
:noname
[: <stuff prefixed to the anonymous function> ;] ;

: ;hex
[: <stuff appended to anonymous function> ;] ;

hex: <my definitions> ;hex
execute

In fact, based on your reasoning, this should work too:

hex: ." hello world" ;

Unfortunately, both forms give an error with VFX. I'm not sure why.

But yes, this is a very compelling reason not to kick off the text parser
automatically after :NONAME.

To accommodate the behaviour I mentioned in this thread, you'd have to
include an extra word in ANS to explicitly kick off the text parser.

Thanks!

Cheers
Arnold

Arnold Doray

unread,
Dec 12, 2011, 7:54:57 AM12/12/11
to
On Mon, 12 Dec 2011 05:37:47 -0600, Andrew Haley wrote:

>
> I think you're looking at it the wrong way by trying to push a problem
> through a filter of how you think Forth should work, rather than how it
> does work. This isn't a profitable way to proceed. What are you trying
> to do with this?
>

I am simply trying to understand the current rationale for the behaviour
of :NONAME. Why doesn't it go ahead and kick off the text parser?

Stephen has given a simple, really compelling reason -- it's because you
can inject additional behaviour into the anonymous definition using
COMPILE, or just by POSTPONE'ing additional words right after :NONAME.

EG:

: hello ." hello " ;
: greeting :noname postpone hello ;

greeting ." world" ; ok
execute hello world ok

If the text parser kicked off immediately this would not work.

Cheers,
Arnold

Anton Ertl

unread,
Dec 12, 2011, 7:41:57 AM12/12/11
to
Arnold Doray <thinks...@gmail.com> writes:
>2) It increases the range of use of :NONAME. For instance, the MDEF would
>work. Currently it does not.

And other things wouldn't work. That's not an increase, it's a shift.

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

It is.

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

Sure it does. Bernd Paysan presented one example:

: myconstant ( n "name" -- )
>r : r> postpone literal postpone ; ;
5 myconstant foo
foo .

If : invoked the text interpreter, as you desire, this would result in
a "undefined" word error at the second occurence of FOO instead of the
intended behaviour of definining a colon definition equivalent to

: foo 5 ;

and then executing it and printing the result.

>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.

It's non-standard. Why is it non-standard? There may be something in
the standard that discusses the reasons, but I do not find it at the
moment. Anyway, the standardized approach certainly had been widely
practiced in systems such as fig-Forth, and apparently the committee
felt that the benefits to programs of standardizing it outweighed the
benefits to systems on not standardizing it. As someone who makes use
of this feature in my programs, I think that was the right decision.

Bernd Paysan

unread,
Dec 12, 2011, 9:00:53 AM12/12/11
to
Anton Ertl wrote:
> It's non-standard. Why is it non-standard? There may be something in
> the standard that discusses the reasons, but I do not find it at the
> moment. Anyway, the standardized approach certainly had been widely
> practiced in systems such as fig-Forth, and apparently the committee
> felt that the benefits to programs of standardizing it outweighed the
> benefits to systems on not standardizing it. As someone who makes use
> of this feature in my programs, I think that was the right decision.

It's about meta-programming, about using macros. You should be able to
mix :noname and postpone in one definition, to create further
definitions without resorting to string manipulations and evaluate.

Hugh Aguilar fortunately is quiet ATM, but he proposed :name for even
more meta-programming, since : is parsing, and when you want to meta-
program, you probably also don't want the name of the function to be
parsed from the input stream. His :name proposal failed, since it
solves the problem only for one word (colon), and Anton suggested
execute-parsing as more general solution.

Stephen Pelc

unread,
Dec 12, 2011, 9:55:33 AM12/12/11
to
On Mon, 12 Dec 2011 12:32:41 +0000 (UTC), Arnold Doray
<thinks...@gmail.com> wrote:

>> : hex: \ -- xt
>> :noname
>> postpone base postpone @ postpone >r postpone hex
>> ;
>>
>> : ;hex \ --
>> postpone r> postpone base postpone ! postpone ;
>> ;
immediate

Sorry, needs IMMEDIATE.

>In fact, based on your reasoning, this should work too:
>
>hex: ." hello world" ;
>
>Unfortunately, both forms give an error with VFX. I'm not sure why.

See the IMMEDIATE problem for ;HEX and note that you *must* balance
return stack stack usage to avoid an exception!

Arnold Doray

unread,
Dec 12, 2011, 11:18:31 AM12/12/11
to
On Mon, 12 Dec 2011 14:55:33 +0000, Stephen Pelc wrote:

>
> See the IMMEDIATE problem for ;HEX and note that you *must* balance
> return stack stack usage to avoid an exception!
>

So, you're saying Bernd's example is actually ANS compliant?

: constant >r : r> postpone literal postpone ; ;

I was concerned that the : might put stuff on the return stack when it
fires up, making this version of CONSTANT not portable.

Thanks,
Arnold




BruceMcF

unread,
Dec 12, 2011, 12:09:14 PM12/12/11
to
I was concerned about that with the "pass" definition given in a
previous discussion:
: pass >R : R> ;

... but while the specification of the compilation stack specifies
that it may be on the data stack, it does not allow it to be on the
return stack ~ not by saying that it can't be on the return stack, but
by omitting language that would allow it:

QUOTE
3.2.3.2 Control-flow stack
The control-flow stack is a last-in, first out list whose elements
define the permissible matchings of control-flow words and the
restrictions imposed on data-stack usage during the compilation of
control structures.

The elements of the control-flow stack are system-compilation data
types.

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.
UNQUOTE

Anton Ertl

unread,
Dec 12, 2011, 12:20:25 PM12/12/11
to
Maybe POSTPONE is better after all:-)

Anton Ertl

unread,
Dec 12, 2011, 12:21:33 PM12/12/11
to
Josh Grams <jo...@qualdan.com> writes:
>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.

Can you give an example of how to do the equivalent of

: myconstant ( n "name" -- )
>r : r> postpone literal postpone ; ;
5 myconstant foo
foo .

in a system where : calls a text interpreter?

The mdef example is not particularly hard:

: parsing-:noname
:noname [char] ; parse evaluate postpone ; ;
: mdef
parsing-:noname parsing-:noname ;
mdef ." foo" ; ." bar" ;
execute
execute

In general it is harder to get rid of unwanted functionality than to
add wanted functionality. I would be surprised if getting rid of the
text interpreter would be as easy.

BruceMcF

unread,
Dec 12, 2011, 12:37:08 PM12/12/11
to
On Dec 11, 10:21 pm, Arnold Doray <thinksqua...@gmail.com> wrote:

> : 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.

How do you make it *not* kick off the text parser, when you want to
*keep executing stuff* and have the text interpreter naturally start
compiling because its in compiler state? By making the kicking off of
the text parser automatic instead of manual
... ' EXECUTE ...
... [CHAR] ; PARSE EVALUATE POSTPONE ; ...

... you complicate the entire system, requiring some kind of mode
variable to *prevent* the compilation state from firing off when you
don't want it to.

All to avoid:

: mdef: dostuff :noname ;
: ;mdef POSTPONE ; domorestuff ; IMMEDIATE

mdef: ." bingo" ;mdef
mdef: ." rover" ;mdef

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

The semantics of :NONAME is already obvious to someone who is used to
Forth but has never seen :NONAME before.

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

Preventing one thing and allowing another is not an increase in the
range, its a shift in the range. You have not said anything that makes
the shift in the range look attractive to me. Losing the ability to
build the start of a definition (whether named or unnamed, if as I
presume, for consistency the same change is done to ":") and then
allow the existing built-in compiler to finish it is far more lost
than the ability to define definition initiators that require an
arbitrary number of definitions before I can escape back to
interpretation mode.

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

All you need is a close definition word corresponding to your start
definition word to grab the XT when it is available. So it seems like
this is about a reluctance to define a set of words as opposed to a
single word.

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

Either you are making :NONAME inconsistent with : or else it causes
code breakage of a word as simple as pass:
: pass: >R : R> ;

Under your proposal, the literal that has been passed is no longer on
the stack at the start of compilation, because compilation proceeds
from ":" until the definition is completed, and "then" the literal is
put on the stack.

Changing the timing of execution of every word with a : or a :NONAME
compiled into it *and then followed by additional code*, which at
present is performed *before* the following definition and under your
proposal would now happen *after* the following definition ...
obviously that is going to cause code breakage.

> 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?

I hadn't made sense of precisely what you were asking for.

You are asking for :noname to, in effect, contain the compiler, rather
than switch the state of the two-state interpreter/compiler. That is a
fundamental design decision. The changes that it entails would cause
code breakage, all over the place. Its not a "modification" of
Forth94, but rather the start of specifying an entirely distinct
family of Forth.

Arnold Doray

unread,
Dec 12, 2011, 12:51:12 PM12/12/11
to
On Mon, 12 Dec 2011 09:09:14 -0800, BruceMcF wrote:

>
> I was concerned about that with the "pass" definition given in a
> previous discussion:
> : pass >R : R> ;
>
> ... but while the specification of the compilation stack specifies that
> it may be on the data stack, it does not allow it to be on the return
> stack ~ not by saying that it can't be on the return stack, but by
> omitting language that would allow it:
>

I thought anything not explicitly forbidden by the spec is allowed.

> QUOTE
>
> 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.
>
> UNQUOTE

Poorly phrased, IMHO.

It seems to say that after doing >R, you can't access the data stack
until after doing R>. In fact, any construct like IF or DO/LOOP which
affects the return stack would render the data stack unreadable. Surely
this can't be right?

Cheers,
Arnold


Andrew Haley

unread,
Dec 12, 2011, 12:53:57 PM12/12/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:
>>>>Bernd Paysan <bernd....@gmx.de> wrote:
>>>>> : Constant >r : r> postpone literal postpone ; ;
>>>>
>>>>polyFORTH could (can?) do that too, just a different way:
>>>>
>>>>: CONSTANT CREATE colon USE COMPILE LITERAL COMPILE ; ;
>>>
>>> Not
>>>
>>> : CONSTANT CREATE colon USE [COMPILE] LITERAL [COMPILE] ; ;
>>>
>>> ?
>>
>>You are right. That was a thinko of mine.
>
> Maybe POSTPONE is better after all:-)

I don't doubt that for a moment.

Andrew.

Andrew Haley

unread,
Dec 12, 2011, 1:03:31 PM12/12/11
to
Arnold Doray <thinks...@gmail.com> wrote:
> On Mon, 12 Dec 2011 09:09:14 -0800, BruceMcF wrote:
>
>>
>> I was concerned about that with the "pass" definition given in a
>> previous discussion:
>> : pass >R : R> ;
>>
>> ... but while the specification of the compilation stack specifies that
>> it may be on the data stack, it does not allow it to be on the return
>> stack ~ not by saying that it can't be on the return stack, but by
>> omitting language that would allow it:
>
> I thought anything not explicitly forbidden by the spec is allowed.

It's the other way around, and this is true for ISO standards in
general, I believe. It's certainly true of programming language
standards: if the standard doesn't grant permission, you can't do it.
Sometimes additional language such as "a program may NOT" is used for
clarity.

>> QUOTE
>>
>> 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.
>>
>> UNQUOTE
>
> Poorly phrased, IMHO.
>
> It seems to say that after doing >R, you can't access the data stack
> until after doing R>.

Hint: the return stack is not the control-flow stack. :-)

Andrew.

Anton Ertl

unread,
Dec 12, 2011, 12:35:51 PM12/12/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:
>>>>>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.

I did not keep the quoted text because I am too lazy to remove it, but
because it proves that you did. Here it is again:

>>>>>>>No. Practice varies so much between Forths that it hasn't been
>>>>>>>possible to standardize it.

>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.

Sure. On the other hand, in this case you unpack the
"restrict-the-implementation" sledgehammer without giving any
evidence, so you reduced the argument to absurdity yourself.

>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.

If you cannot do X without Y, Y is not redundant.

As for redundant features, I could mention a few that were discussed
relatively recently, but let's not get distracted.

>> 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.

We tend not to accept such arguments when it comes to adding features,
we should also be very wary of such arguments when it comes to
rejecting features.

Sure, if you can give good, hard, support that a feature will be a
hindrance to future development, some system implementors may see an
opportunity to improve their systems in the future and will resist the
feature.

But just writing that it might restrict systems, and that you can
think up a system in ten minutes that would be made non-standard by
the feature is not any more helpful than the absurd argument in my
reductio-ad-absurdum. For any feature, including those already
standardized, I can think up a system in 10 minutes that does not have
the feature and is otherwise standard.

>For example, ANS
>Forth to some extent anticipated Forth optimizers, which existed only
>in a very crude form at the time.

Tom Almy's cforth (later renamed ForthCMP) was available in 1982 and
its code generation is not that far from what VFX is doing now
(including register shuffle at basic block boundaries). It had a
number of restrictions, though (batch compilation etc.). Fortunately
the Forth-94 TC did not get rid of the "interactivity" restriction in
order to make it easier to write compilers with that kind of code
quality.

>> 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".

The question of whether we find a feature desirable enough to include
it is a different one. I just don't want any chaff from
"restricts the system" arguments without any evidence.

And, BTW, if we restrict the systems in ways that they become
non-standard if they miscompiled code like GCC does, I would be all
for it. Unfortunately such restrictions are probably not easy to
specify.

Anton Ertl

unread,
Dec 12, 2011, 1:18:53 PM12/12/11
to
Arnold Doray <thinks...@gmail.com> writes:
>On Mon, 12 Dec 2011 14:55:33 +0000, Stephen Pelc wrote:
>
>>
>> See the IMMEDIATE problem for ;HEX and note that you *must* balance
>> return stack stack usage to avoid an exception!
>>
>
>So, you're saying Bernd's example is actually ANS compliant?
>
>: constant >r : r> postpone literal postpone ; ;

yes.

>I was concerned that the : might put stuff on the return stack

No, ":" must not do that. Look at its stack comment. Also, on most
systems defining a word like

: foo
;

would not work if ":" put stuff on the return stack, because the text
interpreter typically internally performs a return at the end of the
line, and the junk produced by ":" would be in the way.

BruceMcF

unread,
Dec 12, 2011, 1:51:38 PM12/12/11
to
The >R goes to the return stack. The R> comes from the return stack.
That is done to AVOID possible interference with the control-flow
stack.

The control-flow stack is explicitly *allowed* to be the data-stack.
Nowhere is it allowed to be the return stack. IF cannot affect the
return stack. BEGIN ... WHILE ... REPEAT cannot effect the return
stack. Only words specified to affect the return stack affect the
return stack.

As far as IF ... ELSE ... THEN and BEGIN ... WHILE ... REPEAT ... of
*course* they can make the data stack unreadable during compiling, on
systems that use the data stack as the control flow stack.

It seems like that's most systems, of course, because dropping the
orig or dest on the data stack is easier and simpler than creating a
separate stack for those.

As far as "surely this can't be right", you are confusing the data
stack usage during compilation of the word and the data stack usage
during execution of the word. The control-flow stack is a compilation-
time thing, to allow the structures to be compiled. Since nested
compilation is not allowed, and since well-structure code removes from
the control-flow stack that is placed on it during compiling the word,
we can be sure that with well-structured code, the compilation is
finished, the control flow stack is empty.

Josh Grams

unread,
Dec 12, 2011, 4:50:47 PM12/12/11
to
Anton Ertl wrote: <2011Dec1...@mips.complang.tuwien.ac.at>
> Josh Grams <jo...@qualdan.com> writes:
>>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.
>
> Can you give an example of how to do the equivalent of
>
>: myconstant ( n "name" -- )
> >r : r> postpone literal postpone ; ;
> 5 myconstant foo
> foo .
>
> in a system where : calls a text interpreter?

When this argument came up way back when, someone who was interested in
such systems gave an example showing that there were underlying factors
available which did not invoke the text interpreter.

I couldn't find the actual discussion, sorry. It was a long time ago,
and Google seems flaky about old newsgroup results...

--Josh

Andrew Haley

unread,
Dec 13, 2011, 6:19:55 AM12/13/11
to
Ah, I see where you're coming from. That was in response to a
completely different question:

>Arnold Doray <thinks...@gmail.com> wrote:
>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a
>> portable implementation?

There may be as many ways to get the address of the latest word in the
dictionary as there are Forths. I've seen LAST @ , LATEST @, LATEST @
@, and so on. And these generally point to to the name field, and
there are different ways use to get from there to the XT, etc. So, I
think it's fair to say that practice varies, which is why there's no
portable implementation of LATESTXT.

>>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.
>
> Sure. On the other hand, in this case you unpack the
> "restrict-the-implementation" sledgehammer without giving any
> evidence, so you reduced the argument to absurdity yourself.

So, perhaps we don't substantially disagree about that.
This is the crucial point:

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.
>
> If you cannot do X without Y, Y is not redundant.

That need not be true if X is not really useful!

> As for redundant features, I could mention a few that were discussed
> relatively recently, but let's not get distracted.

>>> 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.
>
> We tend not to accept such arguments when it comes to adding features,
> we should also be very wary of such arguments when it comes to
> rejecting features.
>
> Sure, if you can give good, hard, support that a feature will be a
> hindrance to future development, some system implementors may see an
> opportunity to improve their systems in the future and will resist the
> feature.
>
> But just writing that it might restrict systems, and that you can
> think up a system in ten minutes that would be made non-standard by
> the feature is not any more helpful than the absurd argument in my
> reductio-ad-absurdum.

I don't think so. I believe that there is commonly a severe lack of
imagination displayed by posters to c.l.f. IMO, people suggest a new
language feature without

a. Considering how the same thing may be done in the standard
language.

b. Considering what the side-effects of standardizing such a feature
may be.

The first thing to do, whenever any new feature is suggested, is to
think of these two things. Even if a particular option has little
chance of being useful in the future, it's still worth talking about
lest we miss something important. Even if the side-effects are so
minor that they will never effect anyone, they are still worth talking
about.

> For any feature, including those already standardized, I can think
> up a system in 10 minutes that does not have the feature and is
> otherwise standard.

I think that's a different matter. It's obviously true for any new
word that you add.

>>> 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".
>
> The question of whether we find a feature desirable enough to include
> it is a different one. I just don't want any chaff from
> "restricts the system" arguments without any evidence.

You may not want them, but these arguments are, IMO, essential.
Robust scientific argument is good, but mere brainstorming can be
useful too; even if a poster turns out to be wrong some useful ideas
may come out of the discussion.

Andrew.

Arnold Doray

unread,
Dec 13, 2011, 6:46:32 AM12/13/11
to
On Mon, 12 Dec 2011 17:21:33 +0000, Anton Ertl wrote:

>
> The mdef example is not particularly hard:
>
> : parsing-:noname
> :noname [char] ; parse evaluate postpone ; ;
> : mdef
> parsing-:noname parsing-:noname ;
> mdef ." foo" ; ." bar" ;
> execute
> execute
>

mdef ." close;" ; ." but no cigar" ;

Cheers,
Arnold

Arnold Doray

unread,
Dec 13, 2011, 7:16:25 AM12/13/11
to
On Mon, 12 Dec 2011 10:51:38 -0800, BruceMcF wrote:

<good stuff snipped>

Thank you for the explanation.

>
> As far as "surely this can't be right", you are confusing the data stack
> usage during compilation of the word and the data stack usage during
> execution of the word.

Yes, that's it exactly.

I confused the "control stack", which is a compile-time structure with
the loop's usage of the return stack during run time.

It also makes the spec's verboten clearer.

41 .S
: bad do [ . ] loop ; \ WRONG!

But then, this should never be done, since the : itself may use the data
stack as a scratchpad:

41 .S
: bad [ . ] ; \ WRONG!

But is this always OK?

: bad?? do [ 1 1 + . ] loop ; \ OK??

Cheers,
Arnold

BruceMcF

unread,
Dec 13, 2011, 7:28:34 AM12/13/11
to
I presume this refers to the brittleness of the implementation (names
beginning with ";", definitions longer than one line)?

Both of those can be dealt with in various ways, but OTOH none of the
examples you've shown requires more than a one-liner, so you haven't
posed a problem that *required* a less brittle solution.

And the solution of pairing the opening word with a closing word
naturally extends to bridge words that close then immediately open
again, to give the same effect without the brittleness of your
*definition*'s hard wiring the number of different definitions to
follow each other without any indication of how many successive
definitions are required. As a dummy:

: my: ( act1here ) :noname ( act2here ) ;
: ;my ( act3here )
POSTPONE ; ( act4here ) ; IMMEDIATE
: ;my: POSTPONE ;my my: ; IMMEDIATE

my: ." solution" ;my: ." better"
;my: SPACE ;my: CR ;my

EXECUTE SWAP EXECUTE EXECUTE EXECUTE

I don't have time to benchtest that, so tell me if it works.

Anton Ertl

unread,
Dec 13, 2011, 10:11:44 AM12/13/11
to
Arnold Doray <thinks...@gmail.com> writes:
>But is this always OK?
>
>: bad?? do [ 1 1 + . ] loop ; \ OK??

Sure, whu not?

Anton Ertl

unread,
Dec 13, 2011, 10:12:41 AM12/13/11
to
Sure, but in your answer you made claims beyond the answer to the
question.

>There may be as many ways to get the address of the latest word in the
>dictionary as there are Forths. I've seen LAST @ , LATEST @, LATEST @
>@, and so on. And these generally point to to the name field, and
>there are different ways use to get from there to the XT, etc. So, I
>think it's fair to say that practice varies, which is why there's no
>portable implementation of LATESTXT.

Yes, but that does not make standardization impossible.

>>>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.
>>
>> If you cannot do X without Y, Y is not redundant.
>
>That need not be true if X is not really useful!

"redundant" is not a synonym for "useless". A feature can be useless
without being redundant (maybe FILE-STATUS, but one might discuss
that), and it can be redundant but still useful (TH would be an
example).

>> But just writing that it might restrict systems, and that you can
>> think up a system in ten minutes that would be made non-standard by
>> the feature is not any more helpful than the absurd argument in my
>> reductio-ad-absurdum.
>
>I don't think so. I believe that there is commonly a severe lack of
>imagination displayed by posters to c.l.f. IMO, people suggest a new
>language feature without
>
>a. Considering how the same thing may be done in the standard
>language.
>
>b. Considering what the side-effects of standardizing such a feature
>may be.

Sure, but that does not mean there is a lack of imagination. There
have also been cases where the standard specified some particular
behaviour, and someone started inventing imaginary implementations
that are ruled out by the standard, and then argued that this standard
behaviour must not be standard because the standard is intended to
accomodate many different implementation approaches. Just in case you
are wondering, that "someone" was not you for the discussion I am
remembering.

>> The question of whether we find a feature desirable enough to include
>> it is a different one. I just don't want any chaff from
>> "restricts the system" arguments without any evidence.
>
>You may not want them, but these arguments are, IMO, essential.
>Robust scientific argument is good, but mere brainstorming can be
>useful too; even if a poster turns out to be wrong some useful ideas
>may come out of the discussion.

I find that this kind of chaff tends to kill any brainstorming,
because instead of letting the brains storm, they get focussed on
shooting down the chaff (that's the purpose of chaff, after all), and
on demonstrating to the others that it is just chaff (and the others
also have to think about the chaff). I am no expert at brainstorming,
but from what I read about it, the most important rule is not to raise
objections in the brainstorming phase.

In the present case we wasted a lot of time arguing about your claim
that (paraphrased) "varying *practice* has made standardization
*impossible*", when standardization has never been attempted, and
there are good reasons (including practice) to assume that
standardization would be possible; whether it is desirable and worth
the effort is another question that we never got to because we were
dealing with the chaff.

Anton Ertl

unread,
Dec 13, 2011, 11:44:46 AM12/13/11
to
Josh Grams <jo...@qualdan.com> writes:
>Anton Ertl wrote: <2011Dec1...@mips.complang.tuwien.ac.at>
>> Josh Grams <jo...@qualdan.com> writes:
>>>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.
>>
>> Can you give an example of how to do the equivalent of
>>
>>: myconstant ( n "name" -- )
>> >r : r> postpone literal postpone ; ;
>> 5 myconstant foo
>> foo .
>>
>> in a system where : calls a text interpreter?
>
>When this argument came up way back when, someone who was interested in
>such systems gave an example showing that there were underlying factors
>available which did not invoke the text interpreter.

Ok, so if one just changed the standard to invoke the text interpreter
from : and ], one could not do it in a standard program. One would
need to standardize additional words. Ok, with these rules, one might
make the text interpreter available as word in Forth-94, and then you
could easily emulate the other behaviour (in a less brittle way than
my first attempt).

Hmm, maybe we can do it already:

variable inner? inner? off
variable inner>in
: ;
postpone ;
inner? @ if
>in @ inner>in !
12345 throw
then ; immediate

: inner-text-interpreter ( -- )
inner? @ >r inner? on
source >in @ /string
['] evaluate catch dup 12345 = if
drop 2drop 0 inner>in @ >in +!
then
r> inner? !
throw ;

: :noname-parsing :noname inner-text-interpreter ;
: mdef :noname-parsing :noname-parsing ;
mdef ." bla;" ; ." bli" ;

This does not work, but the idea should be workable.

Andrew Haley

unread,
Dec 13, 2011, 12:55:05 PM12/13/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:

>>>
>>> I did not keep the quoted text because I am too lazy to remove it, but
>>> because it proves that you did.
>>> Here it is again:
>>>
>>>>>>>>>>No. Practice varies so much between Forths that it hasn't been
>>>>>>>>>>possible to standardize it.
>>
>>Ah, I see where you're coming from. That was in response to a
>>completely different question:
>>
>>>Arnold Doray <thinks...@gmail.com> wrote:
>>>> I'm beginning to appreciate Gforth's LATESTXT word. Is there a
>>>> portable implementation?
>
> Sure, but in your answer you made claims beyond the answer to the
> question.
>
>>There may be as many ways to get the address of the latest word in the
>>dictionary as there are Forths. I've seen LAST @ , LATEST @, LATEST @
>>@, and so on. And these generally point to to the name field, and
>>there are different ways use to get from there to the XT, etc. So, I
>>think it's fair to say that practice varies, which is why there's no
>>portable implementation of LATESTXT.
>
> Yes, but that does not make standardization impossible.

Fair enough. Perhaps all of this is only about the difference between
"Practice varies so much it hasn't been possible to standardize" and
"Practice varies so much it hasn't been standardized."

>>>>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.
>>>
>>> If you cannot do X without Y, Y is not redundant.
>>
>>That need not be true if X is not really useful!
>
> "redundant" is not a synonym for "useless". A feature can be useless
> without being redundant (maybe FILE-STATUS, but one might discuss
> that), and it can be redundant but still useful (TH would be an
> example).

I was using the common English meaning of the word rather than its
more specialized engineering definition. That meaning *is* almost
synonymous with "useless", i.e.

redundant
Adjective:

1. No longer needed or useful; superfluous.
2. (of words or data) Able to be omitted without loss of meaning or function.

> In the present case we wasted a lot of time arguing about your claim
> that (paraphrased) "varying *practice* has made standardization
> *impossible*", when standardization has never been attempted, and
> there are good reasons (including practice) to assume that
> standardization would be possible; whether it is desirable and worth
> the effort is another question that we never got to because we were
> dealing with the chaff.

So let's deal with that instead.

My posting wasn't intended to be chaff. When people make a
suggestion, it's reasonable (and useful!) to think of a possible
counterexample.

Andrew.

Elizabeth D. Rather

unread,
Dec 13, 2011, 1:00:52 PM12/13/11
to
On 12/13/11 2:16 AM, Arnold Doray wrote:
...
> But is this always OK?
>
> : bad?? do [ 1 1 + . ] loop ; \ OK??

Sure. Of course, the stuff in the brackets will only execute once, at
compile-time.

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."
==================================================

Gerry Jackson

unread,
Dec 13, 2011, 5:13:13 PM12/13/11
to
An intriguing exercise that I couldn't resist. The following works but
has defects in that the mdef code has to be on one line, like the above,
and the mdef code can't contain
POSTPONE ; or ['] ;
These could be redefined in the nonamex-wordlist. Making it multi-line
would be more difficult.

: >order ( wid -- )
>r get-order 1+ r> swap set-order
;

wordlist constant nonamex-wordlist

get-current nonamex-wordlist set-current
: ; >in @ postpone \ ; immediate
set-current

: :nonamex \ Extended :noname
nonamex-wordlist >order
:noname
source >in @ dup >r /string evaluate
previous r> + >in ! postpone ;
;

: mdef :nonamex :nonamex :nonamex ;
mdef ." reversed" ; ." was " ; ." This " ;

cr cr execute execute execute

--
Gerry

Arnold Doray

unread,
Dec 14, 2011, 12:40:17 AM12/14/11
to
On Tue, 13 Dec 2011 04:28:34 -0800, BruceMcF wrote:

> On Dec 13, 6:46 am, Arnold Doray <thinksqua...@gmail.com> wrote:
>> On Mon, 12 Dec 2011 17:21:33 +0000, Anton Ertl wrote:
>>
>> > The mdef example is not particularly hard:
>>
>> > : parsing-:noname
>> >   :noname [char] ; parse evaluate postpone ; ;
>> > : mdef
>> >   parsing-:noname parsing-:noname ;
>> > mdef ." foo" ; ." bar" ;
>> > execute
>> > execute
>>
>> mdef ." close;" ; ." but no cigar" ;
>
> I presume this refers to the brittleness of the implementation (names
> beginning with ";", definitions longer than one line)?
>

The brittleness is that PARSE needs to know when to stop. Using ; as a
stop token is what's brittle about Anton's solution.

> Both of those can be dealt with in various ways, but OTOH none of the
> examples you've shown requires more than a one-liner, so you haven't
> posed a problem that *required* a less brittle solution.
>

MDEF is a puzzle, like a Sudoku or crossword puzzle.

But more than just a puzzle, it can pique curiosity, stir interest and
promote learning. Aren't these goals worthy of a less brittle solution?

IMHO, to be an effective Forth programmer, you need to understand
*clearly* how these constructs work and how Forth works internally.

Your collective responses to the MDEF puzzle have helped me understand
clearly how :NONAME , : , ; the text parser, PARSE , EVALUATE and
POSTPONE work.

That's a lot of pedagogical mileage from a single simple example, yes?


> And the solution of pairing the opening word with a closing word
> naturally extends to bridge words that close then immediately open
> again, to give the same effect without the brittleness of your
> *definition*'s hard wiring the number of different definitions to follow
> each other without any indication of how many successive definitions are
> required. As a dummy:
>
> : my: ( act1here ) :noname ( act2here ) ; : ;my ( act3here )
> POSTPONE ; ( act4here ) ; IMMEDIATE
> : ;my: POSTPONE ;my my: ; IMMEDIATE
>
> my: ." solution" ;my: ." better"
> ;my: SPACE ;my: CR ;my
>
> EXECUTE SWAP EXECUTE EXECUTE EXECUTE
>
> I don't have time to benchtest that, so tell me if it works.

Yes, this is similar to Stephen's example upthread. It works.

Cheers,
Arnold

Elizabeth D. Rather

unread,
Dec 14, 2011, 2:24:52 AM12/14/11
to
On 12/13/11 7:40 PM, Arnold Doray wrote:
...
> MDEF is a puzzle, like a Sudoku or crossword puzzle.
>
> But more than just a puzzle, it can pique curiosity, stir interest and
> promote learning. Aren't these goals worthy of a less brittle solution?
>
> IMHO, to be an effective Forth programmer, you need to understand
> *clearly* how these constructs work and how Forth works internally.
>
> Your collective responses to the MDEF puzzle have helped me understand
> clearly how :NONAME , : , ; the text parser, PARSE , EVALUATE and
> POSTPONE work.
>
> That's a lot of pedagogical mileage from a single simple example, yes?

I'm glad you've learned a lot. However, many of the most effective
Forth programmers I know have little interest in the internal working of
these things, but they know very well how to use Forth to solve
real-world application problems, which rarely require this sort of
arcana. If asked about using multiple :nonames in a definition, they
just blink and say, "WHY???"

One of the big differences between folks on c.l.f and workaday Forth
programmers is that the folks here are motivated more by intellectual
curiosity than by a concern with making code work effectively in the
project at hand. God knows I have nothing against intellectual
curiosity, but it's a very different pov.

Andrew Haley

unread,
Dec 14, 2011, 5:05:13 AM12/14/11
to
Arnold Doray <thinks...@gmail.com> wrote:
>
> MDEF is a puzzle, like a Sudoku or crossword puzzle.
>
> But more than just a puzzle, it can pique curiosity, stir interest and
> promote learning. Aren't these goals worthy of a less brittle solution?
>
> IMHO, to be an effective Forth programmer, you need to understand
> *clearly* how these constructs work and how Forth works internally.

You certainly do not have to know all this arcane internal stuff to be
an effective Forth programmer.

There's a classic syndrome of Forth programmers inventing their own
parsers, syntaxes, and control structures, not for any practical
reason but because they can. Not everyone suffers from this: some
just learn straightforward Forth and get on with what they really
wanted to do. Most sufferers eventually get over it, and go back to
straightforward coding.

Extending the language can be really useful, but if you do it
everywhere you'll end up with something that is very hard to maintain.
Think of metaprogramming as being like strong drink or MSG: useful,
but best used in moderation. Many LISPers tend to think of LISP
macros in the same terms, for much the same reasons.

Andrew.

Krishna Myneni

unread,
Dec 15, 2011, 7:30:21 PM12/15/11
to
On Dec 10, 6:24 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:
> Andrew Haley <andre...@littlepinkcloud.invalid> writes:
> >Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> >> Andrew Haley <andre...@littlepinkcloud.invalid> writes:
> >>>Arnold Doray <thinksqua...@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?
>

Er. ... maybe not standard, but kForth does not assign a code field
address (the xt) until semicolon executes, due to its dynamic
dictionary model. AFAIK, doing it this way does not violate the
standard.

--
int CPP_colon()
{
:
State = TRUE;
:
NewWord.Pfa = NULL;
NewWord.Cfa = NULL; // no xt available after ":" executes
:
}

int CPP_semicolon()
{
:
NewWord.Pfa = new byte[pCurrentOps->size()];
NewWord.Cfa = NewWord.Pfa;

// Resolve any self references (recursion)
:
pCompilationWL->push_back(NewWord);
:
State = FALSE;
:
}
--

Krishna

Anton Ertl

unread,
Dec 16, 2011, 12:11:31 PM12/16/11
to
Krishna Myneni <krishna...@ccreweb.org> writes:
>Er. ... maybe not standard, but kForth does not assign a code field
>address (the xt) until semicolon executes, due to its dynamic
>dictionary model. AFAIK, doing it this way does not violate the
>standard.

For ":", it doesn't. For :NONAME, it does.

BruceMcF

unread,
Dec 16, 2011, 7:15:19 PM12/16/11
to
On Dec 16, 12:11 pm, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:
> Krishna Myneni <krishna.myn...@ccreweb.org> writes:
> >Er. ... maybe not standard, but kForth does not assign a code field
> >address (the xt) until semicolon executes, due to its dynamic
> >dictionary model. AFAIK, doing it this way does not violate the
> >standard.
>
> For ":", it doesn't.  For :NONAME, it does.

If xt is beneath colon-sys, and colon-sys can only be portably removed
by ";", then isn't that one of those "it complies if there is no
discernible difference from an implementation that complies" cases?

Andrew Haley

unread,
Dec 17, 2011, 4:22:16 AM12/17/11
to
BruceMcF <agi...@netscape.net> wrote:
> On Dec 16, 12:11?pm, an...@mips.complang.tuwien.ac.at (Anton Ertl)
> wrote:
>> Krishna Myneni <krishna.myn...@ccreweb.org> writes:
>> >Er. ... maybe not standard, but kForth does not assign a code field
>> >address (the xt) until semicolon executes, due to its dynamic
>> >dictionary model. AFAIK, doing it this way does not violate the
>> >standard.
>>
>> For ":", it doesn't. ?For :NONAME, it does.
>
> If xt is beneath colon-sys, and colon-sys can only be portably removed
> by ";", then isn't that one of those "it complies if there is no
> discernible difference from an implementation that complies" cases?

I think it can be accessed via some devious use of DEPTH and PICK. I
don't know that anyone has ever done that, but it's possible.

Andrew.

Arnold Doray

unread,
Dec 17, 2011, 10:34:48 AM12/17/11
to
See Josh's reply upthread:

: :noname
depth 1+ >r :noname depth >r - pick ;

In any case, kForth does not yet have :NONAME.

Cheers,
Arnold

Krishna Myneni

unread,
Dec 17, 2011, 11:04:56 AM12/17/11
to
I've never added it, because it seems entirely superfluous. Just
redefine the word NONAME as many times as needed, for typical use (see
kForth's mini-oof-demo, for example). Is there any good argument to be
made for the existence of :NONAME ?

Krishna

Arnold Doray

unread,
Dec 17, 2011, 12:20:07 PM12/17/11
to
Yes, but that only works outside a definition.

In contrast, you can use :NONAME within a definition. An example of this
is in the '94 spec (see page 150).

If you tried this with your technique, you'd force both the systems
developer (who creates the defining words) and the app developer who uses
these words to litter their code with superfluous "noname" names.

This may not be practicable, depending on the circumstances. For example,
in the performance profiling code of the spec's example (ie, page 150),
using your solution would force the app developer to prefix *every* word
he writes with "noname".

Also as Anton pointed out, they behave differently. : doesn't have to put
the XT immediately on the stack, while :NONAME must, which means you
could portably access the XT using DEPTH and PICK at the defining word's
runtime.

You can't with your solution without resorting to special terminating
words in lieu of ; . Which again is a burden to the app programmer.

I would welcome a correctly implemented :NONAME in kForth.

Cheers,
Arnold


















BruceMcF

unread,
Dec 17, 2011, 12:38:38 PM12/17/11
to
On Dec 17, 4:22 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> I think it can be accessed via some devious use of DEPTH and PICK.  I
> don't know that anyone has ever done that, but it's possible.

Aha, you're right ~ if DEPTH and PICK exist on the system, I think its
something like the following:

VARIABLE noname-xt

: :noname
DEPTH >R :noname DEPTH 1- R> - PICK noname-xt ! ;

... works on gforth.

BruceMcF

unread,
Dec 17, 2011, 12:43:33 PM12/17/11
to
On Dec 17, 11:04 am, Krishna Myneni <krishna.myn...@ccreweb.org>
wrote:
> I've never added it, because it seems entirely superfluous. Just
> redefine the word NONAME as many times as needed, for typical use (see
> kForth's mini-oof-demo, for example). Is there any good argument to be
> made for the existence of :NONAME ?

That's one of the arguments right there ~ creating a redundant
dictionary entry each time a definition is used *only* to create an xt
that is put into an object and only used via the object name and
method name is a dictionary space inefficiency.

But if there is no :noname in your system, then generating the xt at
the time of ; is not a violation of the standard.

Andrew Haley

unread,
Dec 17, 2011, 1:38:40 PM12/17/11
to
Arnold Doray <thinks...@gmail.com> wrote:
> On Sat, 17 Dec 2011 08:04:56 -0800, Krishna Myneni wrote:
>
>> On Dec 17, 9:34?am, Arnold Doray <thinksqua...@gmail.com> wrote:
>
>>> In any case, kForth does not yet have :NONAME.
>>
>> I've never added it, because it seems entirely superfluous. Just
>> redefine the word NONAME as many times as needed, for typical use (see
>> kForth's mini-oof-demo, for example). Is there any good argument to be
>> made for the existence of :NONAME ?
>
> Yes, but that only works outside a definition.

variable booger

: :noname s" : noname" evaluate 1 booger ! ;

: : 0 booger ! : ;

: ;
postpone ;
booger @ if s" ' noname " evaluate then ; immediate

(A more hygienic variant would use EXECUTE-PARSING; see discussion in
c.l.f passim.)

> Also as Anton pointed out, they behave differently. : doesn't have
> to put the XT immediately on the stack, while :NONAME must, which
> means you could portably access the XT using DEPTH and PICK at the
> defining word's runtime.

You could, but the usefulness of that is pretty questionable.

Andrew.

Arnold Doray

unread,
Dec 17, 2011, 11:01:32 PM12/17/11
to
On Sat, 17 Dec 2011 12:38:40 -0600, Andrew Haley wrote:

> Arnold Doray <thinks...@gmail.com> wrote:
>> On Sat, 17 Dec 2011 08:04:56 -0800, Krishna Myneni wrote:
>>
>>> On Dec 17, 9:34?am, Arnold Doray <thinksqua...@gmail.com> wrote:
>>
>>>> In any case, kForth does not yet have :NONAME.
>>>
>>> I've never added it, because it seems entirely superfluous. Just
>>> redefine the word NONAME as many times as needed, for typical use (see
>>> kForth's mini-oof-demo, for example). Is there any good argument to be
>>> made for the existence of :NONAME ?
>>
>> Yes, but that only works outside a definition.
>
> variable booger
>
> : :noname s" : noname" evaluate 1 booger ! ;
>
> : : 0 booger ! : ;
>
> : ;
> postpone ;
> booger @ if s" ' noname " evaluate then ; immediate
>
> (A more hygienic variant would use EXECUTE-PARSING; see discussion in
> c.l.f passim.)
>

No, your solution is off spec. You need to put the <xt> on the stack as
soon as :noname is called.

>> Also as Anton pointed out, they behave differently. : doesn't have to
>> put the XT immediately on the stack, while :NONAME must, which means
>> you could portably access the XT using DEPTH and PICK at the defining
>> word's runtime.
>
> You could, but the usefulness of that is pretty questionable.
>

What do you mean precisely by "useful" or "questionable"?

Any set of examples given in response to such questions is bound to
elicit the comment that it can be "done another way". And it probably
can.

To me , the fact that it's in the spec and behaves that way, seems to say
that it's useful to the community. It's something I can rely on in any
ANS compliant forth.

I could use it to clean up your memoization solution by introducing just
one extra word - :NONAME* that uses DEPTH and PICK.

: slot ( n table - slot)
dup cell+ >r @ mod 2 cells * r> + ;

: hash.key ( a - a') ;
: hash.value ( a - a') cell+ ;

hex 80000000 constant min-int decimal
: ,hashtable ( n)
dup ,
0 do min-int , 0 , loop ;

: memoized-execute ( n table xt - n')
>r
over swap slot ( n slot)

2dup hash.key @ = if ( We found it)
hash.value @ swap r> 2drop exit then

( n slot) over r> execute
( n slot n') dup >r
-rot ( n' n slot) 2! r> ;

: do-memoize
does> ( n) dup cell+ swap @ memoized-execute ;

: :noname*
depth 1+ >r :noname depth r> - pick ;

: :: ( n)
create here >r 0 , ,hashtable do-memoize
:noname* r> ! ;

\ Here's how it's used:

29 :: fib
dup 1 > if dup 1- fib swap 2 - fib + then ;

Which is better than your original (YMMV of course):

29 memoize fib
:noname ( n - n')
dup 1 > if dup 1- fib swap 2 - fib + then ;
' fib >body !

There are other ways to do this. But that doesn't mean that :NONAME's
current behaviour isn't useful.

Cheers,
Arnold

BruceMcF

unread,
Dec 18, 2011, 1:06:54 AM12/18/11
to
On Dec 17, 11:01 pm, Arnold Doray <thinksqua...@gmail.com> wrote:
> To me , the fact that it's in the spec and behaves that way, seems
> to say that it's useful to the community.

Alternatively, it could say that those implementations that had
a :noname word (under whatever name) happened to do it like that, so
that there was no need to modify the existing ";".

Indeed, the fact that its CORE EXT suggests that at least some on the
committee did not think it was an essential facility.

All Krishna has to do to comply with the standard and generate his xt
when ";" executes is to call it something other than ":noname".
":anon" would do.

Mark Wills

unread,
Dec 18, 2011, 4:08:08 AM12/18/11
to
Doesn't look correct to this novice. Where does the compiler get
switched on?

It occurs to me that something akin to noname might be useful whereby
HERE is not changed by the compilation process. The fact that loops
and IFs can only be compiled is inconvenient for command line
testing.

: test: here >r ] >r dup h ! Execute ;

Or something like that. The point is, HERE is corrected after
compilation so the next word rolls over the temporary test definition.
Not an issue with a gig of RAM but when you have 32k like I do....!

Use like this...

Test: 100 0 do thing loop if this else that then ;

Hmmm.... interesting. I must try that later...

Mark

Mark Wills

unread,
Dec 18, 2011, 4:38:45 AM12/18/11
to
I think the above would work on my own forth system, but one would
need a different terminator to ; since ; modifies the dictionary entry
(un-smudge) which of course isn't present. So... (very basic)...

: ;; [ ; immediate

Test: ... ... ... ;;

Hopefully I'm on the right track with that...

Mark

Andrew Haley

unread,
Dec 18, 2011, 5:40:22 AM12/18/11
to
Arnold Doray <thinks...@gmail.com> wrote:
> On Sat, 17 Dec 2011 12:38:40 -0600, Andrew Haley wrote:
>
>> Arnold Doray <thinks...@gmail.com> wrote:
>>> On Sat, 17 Dec 2011 08:04:56 -0800, Krishna Myneni wrote:
>>>
>>>> On Dec 17, 9:34?am, Arnold Doray <thinksqua...@gmail.com> wrote:
>>>
>>>>> In any case, kForth does not yet have :NONAME.
>>>>
>>>> I've never added it, because it seems entirely superfluous. Just
>>>> redefine the word NONAME as many times as needed, for typical use (see
>>>> kForth's mini-oof-demo, for example). Is there any good argument to be
>>>> made for the existence of :NONAME ?
>>>
>>> Yes, but that only works outside a definition.
>>
>> variable booger
>>
>> : :noname s" : noname" evaluate 1 booger ! ;
>>
>> : : 0 booger ! : ;
>>
>> : ;
>> postpone ;
>> booger @ if s" ' noname " evaluate then ; immediate
>>
>> (A more hygienic variant would use EXECUTE-PARSING; see discussion in
>> c.l.f passim.)
>>
>
> No, your solution is off spec. You need to put the <xt> on the stack as
> soon as :noname is called.

That doesn't matter, IMO.

>>> Also as Anton pointed out, they behave differently. : doesn't have to
>>> put the XT immediately on the stack, while :NONAME must, which means
>>> you could portably access the XT using DEPTH and PICK at the defining
>>> word's runtime.
>>
>> You could, but the usefulness of that is pretty questionable.
>
> What do you mean precisely by "useful" or "questionable"?

I mean that it's not very useful. I don't know how to define "useful"
in any way other than referring to a dictionary. I'm not using the
word in any special technical sense.

> Any set of examples given in response to such questions is bound to
> elicit the comment that it can be "done another way". And it probably
> can.
>
> To me , the fact that it's in the spec and behaves that way, seems
> to say that it's useful to the community.

Not necessarily. I suspect it's just an artefact. The fact that
getting to the XT requires messigng about with DEPTH and PICK is a
clue.

> : :noname*
> depth 1+ >r :noname depth r> - pick ;
>
> : :: ( n)
> create here >r 0 , ,hashtable do-memoize
> :noname* r> ! ;
>
> \ Here's how it's used:
>
> 29 :: fib
> dup 1 > if dup 1- fib swap 2 - fib + then ;
>
> Which is better than your original (YMMV of course):

If you worry (excessively, IMO) about syntax, yes, it's better. It's
not better in any practical sense, although it's surely possible to
come up with an ad hoc example that uses it.

> 29 memoize fib
> :noname ( n - n')
> dup 1 > if dup 1- fib swap 2 - fib + then ;
> ' fib >body !
>
> There are other ways to do this.

Indeed there are.

> But that doesn't mean that :NONAME's current behaviour isn't useful.

Actually, that's exactly what it means! You really don't need the XT
early on because you can't use it until ; .

Andrew.

Arnold Doray

unread,
Dec 18, 2011, 6:31:15 AM12/18/11
to
On Sun, 18 Dec 2011 04:40:22 -0600, Andrew Haley wrote:

>
> Not necessarily. I suspect it's just an artefact. The fact that
> getting to the XT requires messigng about with DEPTH and PICK is a clue.
>

It's probably because ; expects a <colon-sys> on TOS. So the simplest
implementation option is using <xt><colon-sys> for :NONAME's actions.

But yes, using :NONAME* is a kludge. I could be wrong, but I feel words
like DEPTH should never ever be used. I'm not quite sure why, they just
feel wrong.

There must be a better way to create anonymous functions. Any suggestions?

>> : :noname*
>> depth 1+ >r :noname depth r> - pick ;
>>
>> : :: ( n)
>> create here >r 0 , ,hashtable do-memoize :noname* r> ! ;
>>
>> \ Here's how it's used:
>>
>> 29 :: fib
>> dup 1 > if dup 1- fib swap 2 - fib + then ;
>>
>> Which is better than your original (YMMV of course):
>
> If you worry (excessively, IMO) about syntax, yes, it's better. It's
> not better in any practical sense, although it's surely possible to come
> up with an ad hoc example that uses it.
>

No, it isn't needless.

Especially when you're developing words that are likely to be used by
other programmers, it pays to give them a clean, simple syntax. A clean
syntax reduces visual noise making code that much more readable. It also
makes code reuse easier.

To paraphrase Steve Jobs:

"You've got to start with the Application Programmer experience and work
back toward the defining words -- not the other way around".

>> 29 memoize fib
>> :noname ( n - n')
>> dup 1 > if dup 1- fib swap 2 - fib + then ;
>> ' fib >body !
>>

This syntax of yours doesn't make maintenance or code verification easy.
The app programmer who uses it needs to keep 3 or 4 things in mind in
order to use it. This gets harder in a larger application.

Cheers,
Arnold

Arnold Doray

unread,
Dec 18, 2011, 6:47:40 AM12/18/11
to
On Sat, 17 Dec 2011 22:06:54 -0800, BruceMcF wrote:

> On Dec 17, 11:01 pm, Arnold Doray <thinksqua...@gmail.com> wrote:
>> To me , the fact that it's in the spec and behaves that way, seems to
>> say that it's useful to the community.
>
> Alternatively, it could say that those implementations that had a
> :noname word (under whatever name) happened to do it like that, so that
> there was no need to modify the existing ";".
>

Yes, you're probably right. ; expects <colon-sys> on TOS, so that leaves
you with <xt><colon-sys> for :NONAME unless you want to fiddle with ;

> Indeed, the fact that its CORE EXT suggests that at least some on the
> committee did not think it was an essential facility.
>

:NONAME is all about metaprogramming. You don't need metaprogramming
tools for many of the bread-n-butter issues. So CORE EXT is actually a
logical choice.

> All Krishna has to do to comply with the standard and generate his xt
> when ";" executes is to call it something other than ":noname". ":anon"
> would do.

Technically you're right of course.

But no one would use :ANON precisely because it's not in the spec. I
certainly would not. It makes code that much harder to port. And if you
consider that :NONAME is used in metaprogramming situations, which may
have subtle bugs if you attempted to port :ANON to :NONAME.

I would really like to see a compliant :NONAME in kForth.

Cheers
Arnold


It is loading more messages.
0 new messages