albert@spenarnc.xs4all.nl writes:
If you pass an address a as a tail call is it approximately equal
to coroutines:
No I don't think so. The tail call is just a jump to that address
(changes the program counter). A coroutine jump also has to change the
stack pointer. See the section "Knuth's coroutines" here:
https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
Some Forths have a CO primitive that I think is similar. There is
something like it on the Greenarrays processor.
Never having looked at coroutines before I tried implementing the
examples in the above paper. The resulting code is: ...
https://doi.org/10.1145/1462166.1462167
albert@spenarnc.xs4all.nl writes:
If you pass an address a as a tail call is it approximately equal
to coroutines:
No I don't think so. The tail call is just a jump to that address
(changes the program counter). A coroutine jump also has to change the stack pointer. See the section "Knuth's coroutines" here:
https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
Some Forths have a CO primitive that I think is similar. There is
something like it on the Greenarrays processor.
Gerry Jackson <do-not-use@swldwa.uk> writes:
Never having looked at coroutines before I tried implementing the
examples in the above paper. The resulting code is: ...
It would take me a while to understand that, but [:] is cool (haven't
seen it before),
and it lets you do something similar to protothreads.
Paul Rubin <no.email@nospam.invalid> writes:
For coroutines in general you should also read this:
https://doi.org/10.1145/1462166.1462167
It discusses "stackful" coroutines where each coroutine has a separate
call stack that is preserved across coroutine jumps. It's similar to
Forth's cooperative multitasking.
https://doi.org/10.1145/1462166.1462167
Ehh, that article is very theoretical. I had forgotten what it was
like, or maybe confused it with a different article. The below is
probably more readable:
https://www.lua.org/doc/jucs04.pdf
I've never heard of protothreads let alone used them. Apparently they
Thanks for the link, very interesting. According to that paper the
Forth implementation in my first post is an asymmetric coroutine as
are Lua coroutines which they justify in an appendix,
For the first point, in my example data local to the parser is
retained but in global variables. That can be made local by putting
them in a separate wordlist. Using Forth local variables doesn't make
sense when [:] is used. If it did make sense then local variable
values wouldn't be retained.
The re-entry point has to be called by name. I would think that makes
it more readable.
6. Nested colon definitions e.g. a possible use - unsure of its utility.
: a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
b 2 3
b is effectively a nested colon definition - forbidden by the standard
Gerry
Gerry Jackson <do-not-use@swldwa.uk> writes:
I've never heard of protothreads let alone used them. Apparently they
They are basically a fancier version of Simon Tatham's preprocessor
scheme. In fact I confused the two. See:
https://dunkels.com/adam/pt/index.html
Thanks for the link, very interesting. According to that paper the
Forth implementation in my first post is an asymmetric coroutine as
are Lua coroutines which they justify in an appendix,
I think there's a big difference, which is that in Lua, you can call something as a coroutine, and it can yield from several levels deep in function calls and later resume where it left off.
couldn't do that, but it gained the ability later. It's how
asynchronous i/o works in Python. It also lets you implement
multitasking, by having the tasks avoid any blocking operations and
yield frequently to not hog the cpu.
Forth also often implements something like that, with a cooperative multitasker API where you PAUSE every so often, and communicate through mailboxes rather than with return values. It's equivalent though.
The re-entry point has to be called by name. I would think that makes
it more readable.
Does that mean the caller has to know where the coroutine returns from? That's more bookkeeping.
In article <10qunhm$1nnbt$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
<SNIP>
6. Nested colon definitions e.g. a possible use - unsure of its utility.
: a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
b 2 3
b is effectively a nested colon definition - forbidden by the standard
The term forbidden sneaks in probably by implementors that have
absolutely no intention to implement this.
Normal it would be phrased as,
"A standard Forth is not required to accommodate nested definitions.
A program relying on such has an environmental dependancy"
Note that [: .. ;] is in fact nesting definitions. 1]
In ciforth you can load an extension { } [ ]
Your example
: a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
then becomes
: a 1 . [ : b 2 . 3 . ; ] b drop 4 . ;
1]--
Definition or word, or dictionary entry.
Definition: a dictionary entry is a logical part of the dictionary that bundles the properties of a word/definition.
Definition: It is identified by a handle, the dea (dictionary entry address) CDFLN SX
It has a code address: for executing the word, native code.
It has a data address: contains a pointer to data (buffer, ITC, DTC,)
It has a flag address: individual bits identify immediate smudged etc.
It has a link address: that defines a relation its wordlist
It has a name address: contains a (pointer to) the name
Extra fields can be added by an implementation.
Example a source address: points to the source of a word^H^H^H^H d.e..
Each and all of this fields can be modified without disturbing
the identity of a dea, e.g.
"drop" ALLOCATE$ ' DROP >NFA !
It makes no sense to have a word without a name, old view.
OTOH a d.e. where the name address contains a null pointer
makes perfect sense, new view.
Using dea as an xt :
EXECUTE ( dea -- ?? ) jump to the address found via the cfa.
This can be accomplished while the d.e. is not (yet) linked
into a wordlist, or floating in ALLOCATEd space, or temporary
in a spare dictionary area that is about to be destroyed,
or even if the "word" has no name.
Groetjes Albert
I think there's a big difference, which is that in Lua, you can call >something as a coroutine, and it can yield from several levels deep in >function calls and later resume where it left off. Python originally >couldn't do that, but it gained the ability later. It's how
asynchronous i/o works in Python. It also lets you implement
multitasking, by having the tasks avoid any blocking operations and
yield frequently to not hog the cpu.
On 06/04/2026 12:51, albert@spenarnc.xs4all.nl wrote:
In article <10qunhm$1nnbt$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
<SNIP>
6. Nested colon definitions e.g. a possible use - unsure of its utility. >>> : a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;The term forbidden sneaks in probably by implementors that have
b 2 3
b is effectively a nested colon definition - forbidden by the standard >>
absolutely no intention to implement this.
Hmm I just scanned the Forth 2012 document to see if nested definition
were ambiguous or had an environmental dependency and I couldn't find >anything. I always assumed it wasn't permited - perhaps it is.
--
Gerry
On 06/04/2026 12:51, albert@spenarnc.xs4all.nl wrote:
In article <10qunhm$1nnbt$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
<SNIP>
6. Nested colon definitions e.g. a possible use - unsure of its utility. >>> : a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
b 2 3
b is effectively a nested colon definition - forbidden by the
standard
The term forbidden sneaks in probably by implementors that have
absolutely no intention to implement this.
Hmm I just scanned the Forth 2012 document to see if nested definition
were ambiguous or had an environmental dependency and I couldn't find anything. I always assumed it wasn't permited - perhaps it is.
It is in section 3.4.5, in particular the 2nd paragraph:
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >certain architectures.
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:...
It is in section 3.4.5, in particular the 2nd paragraph:
3.4.5
Compilation
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.
It seems entirely frivolous to me, but maybe it is difficult to do for
certain architectures.
I think it was existing practice: Most systems did not support nested definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
On 4/6/26 4:20 PM, Gerry Jackson wrote:
On 06/04/2026 12:51, albert@spenarnc.xs4all.nl wrote:
In article <10qunhm$1nnbt$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
<SNIP>
6. Nested colon definitions e.g. a possible use - unsure of its
utility.
: a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
b 2 3
b is effectively a nested colon definition - forbidden by the
standard
The term forbidden sneaks in probably by implementors that have
absolutely no intention to implement this.
Hmm I just scanned the Forth 2012 document to see if nested definition
were ambiguous or had an environmental dependency and I couldn't find
anything. I always assumed it wasn't permited - perhaps it is.
It is in section 3.4.5, in particular the 2nd paragraph:
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.
On 07/04/2026 12:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
On the contrary, Ruvim posted some code that is a standard program and
which distinguises between a parsing TO and one that sets a flag for a >following VALUE to act on.
I can't find the post but the gist of it was (I think):
1 value v1
2 value v2 immediate
: test to v2 v1 ;
Running test with
3 test
A parsing TO will set v2 to 3
A flagging TO will execute v2 during compilation of test because it is >immediate. So test will set v1 to 3 leaving v2 unchanged.
--
Gerry
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested definitions when Forth-94 was standardized, and I guess that most
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.
It seems entirely frivolous to me, but maybe it is difficult to do for
certain architectures.
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
On 07/04/2026 15:28, Krishna Myneni wrote:
On 4/6/26 4:20 PM, Gerry Jackson wrote:
On 06/04/2026 12:51, albert@spenarnc.xs4all.nl wrote:
In article <10qunhm$1nnbt$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
<SNIP>
6. Nested colon definitions e.g. a possible use - unsure of its
utility.
: a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
b 2 3
b is effectively a nested colon definition - forbidden by the >>>>> standard
The term forbidden sneaks in probably by implementors that have
absolutely no intention to implement this.
Hmm I just scanned the Forth 2012 document to see if nested definition
were ambiguous or had an environmental dependency and I couldn't find
anything. I always assumed it wasn't permited - perhaps it is.
It is in section 3.4.5, in particular the 2nd paragraph:
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.
Thanks I missed that. Those statements would seem to rule out quotations >except that it could be argued that the definition of [: and ;] does not >suspend compilation - its part of the enclosing colon definition.
--
Gerry
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested
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.
It seems entirely frivolous to me, but maybe it is difficult to do for
certain architectures.
definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
--
Gerry
In article <10r3nfo$33464$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 12:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
On the contrary, Ruvim posted some code that is a standard program and
which distinguises between a parsing TO and one that sets a flag for a
following VALUE to act on.
I can't find the post but the gist of it was (I think):
1 value v1
2 value v2 immediate
: test to v2 v1 ;
Running test with
3 test
A parsing TO will set v2 to 3
A flagging TO will execute v2 during compilation of test because it is
immediate. So test will set v1 to 3 leaving v2 unchanged.
No it doesn't. It leaves garbage on the stack during compilation,
leading to mostly an error.
I leave it up to the reader whether this counts as a standard program.
I overlooked this clever example.As did everybody else until Ruvim devised it.
So I guess my VALUE is non compliant, proven by a contrived test.
It still makes no sense to forbid a flagging implementation.
(Also VALUE's don't make sense, anyway.)
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:
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.
It seems entirely frivolous to me, but maybe it is difficult to do for
certain architectures.
I think it was existing practice: Most systems did not support nested definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
- anton
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >>>> certain architectures.
definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >>>> certain architectures.
definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
( This is the infamous Pythogarean triangle. )--
On 4/8/26 6:16 AM, albert@spenarnc.xs4all.nl wrote:
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >>>>> certain architectures.
definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
I assume you can also compile :NONAME definitions while the current definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ;
ok
3 4 hyp^2 .
25 ok
Incidentally, is the scope of your definition of SQ limited to the definition of hyp*2 in your example above? Or is SQ added to the
dictionary like a regular definition?
In article <10r5atl$3g8d5$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 15:28, Krishna Myneni wrote:
On 4/6/26 4:20 PM, Gerry Jackson wrote:
On 06/04/2026 12:51, albert@spenarnc.xs4all.nl wrote:
In article <10qunhm$1nnbt$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
<SNIP>
6. Nested colon definitions e.g. a possible use - unsure of its
utility.
: a 1 . [: [:] b 2 . 3 . ;] drop 4 . ;
b 2 3
b is effectively a nested colon definition - forbidden by the >>>>>> standard
The term forbidden sneaks in probably by implementors that have
absolutely no intention to implement this.
Hmm I just scanned the Forth 2012 document to see if nested definition >>>> were ambiguous or had an environmental dependency and I couldn't find
anything. I always assumed it wasn't permited - perhaps it is.
It is in section 3.4.5, in particular the 2nd paragraph:
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.
Thanks I missed that. Those statements would seem to rule out quotations
except that it could be argued that the definition of [: and ;] does not
suspend compilation - its part of the enclosing colon definition.
"part of the" a really Jezuitic argument.
It also forbids
: there 3 ;
: test .. [ ' three COMPILE, ] ... ;
a technique that should be kosher.
It is more proof that the term "forbid" has no place in the wording of the restriction. An implementor of [: has options he sees fit, includingMy system has unconstrained nesting but it doesn't need any change to [
- skipping over an area, that is unused by the current definition,
- temperarily compiling to an alternative HERE, transporting back later
to the regular HERE. ( FAR-DP SWAP-DP TRIM approach use for my OO).
After the current definition finishes copy bake to a new HERE.
- using ALLOCATEd space, or
- invoking a c-compiler.
[: ;] renamed { } to ( include :NONAME ) is readily implemented
by the four nestings of the apocalypse:
: { (( (s ({) ; IMMEDIATE
: } >R (}) s) )) R> 'LITERAL EXECUTE ; IMMEDIATE
With a refurbished [ ] it implements unconstrained nesting :
: doit .. [ .. { ..} .. { .. [ .. ] .. } .. ] .. ;
(The four brackets comprise one screen. Only words
from the ciforth kernel needed. So in a proper architecture
it is straightforward. )
On 07/04/2026 12:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
On the contrary, Ruvim posted some code that is a standard program and
which distinguises between a parsing TO and one that sets a flag for a following VALUE to act on.
On 4/8/26 6:16 AM, albert@spenarnc.xs4all.nl wrote:
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >>>>> certain architectures.
definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
I assume you can also compile :NONAME definitions while the current >definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ;
ok
3 4 hyp^2 .
25 ok
Incidentally, is the scope of your definition of SQ limited to the
definition of hyp*2 in your example above? Or is SQ added to the
dictionary like a regular definition?
----
Krishna
In article <10r60qk$3nqft$1@dont-email.me>,
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
On 4/8/26 6:16 AM, albert@spenarnc.xs4all.nl wrote:Actually you can't. After -nesting- the brackets use the data stack extensively.
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested >>>>> definitions when Forth-94 was standardized, and I guess that most
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >>>>>> certain architectures.
systems do not support general nesting to this day, and when they do, >>>>> the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
I assume you can also compile :NONAME definitions while the current
definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ;
ok
3 4 hyp^2 .
25 ok
You enter an isolated world between [ and ] .
Your example could become
"
WANT -nesting- CASE-INSENSITIVE :NONAME
: hyp^2 [ :NONAME dup * ; CONSTANT NONAME ] NONAME dup >r execute swap r> execute + ;
"
On 08/04/2026 17:47, Krishna Myneni wrote:
On 4/8/26 6:16 AM, albert@spenarnc.xs4all.nl wrote:
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested >>>>> definitions when Forth-94 was standardized, and I guess that most
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.
It seems entirely frivolous to me, but maybe it is difficult to do >>>>>> for
certain architectures.
systems do not support general nesting to this day, and when they do, >>>>> the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
I assume you can also compile :NONAME definitions while the current
definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ;
ok
3 4 hyp^2 .
25 ok
Works on my system. Both HYP^2 and SQ are added to the current wordlist.
...
On 4/9/26 6:01 AM, albert@spenarnc.xs4all.nl wrote:No, but you don't use nesting normally.
In article <10r60qk$3nqft$1@dont-email.me>,
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
On 4/8/26 6:16 AM, albert@spenarnc.xs4all.nl wrote:Actually you can't. After -nesting- the brackets use the data stack extensively.
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested >>>>>> definitions when Forth-94 was standardized, and I guess that most
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.
It seems entirely frivolous to me, but maybe it is difficult to do for >>>>>>> certain architectures.
systems do not support general nesting to this day, and when they do, >>>>>> the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
I assume you can also compile :NONAME definitions while the current
definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ;
ok
3 4 hyp^2 .
25 ok
You enter an isolated world between [ and ] .
Your example could become
"
WANT -nesting- CASE-INSENSITIVE :NONAME
: hyp^2 [ :NONAME dup * ; CONSTANT NONAME ] NONAME dup >r execute swap r> execute + ;
"
So you can never use "[ ... ] LITERAL" when nesting is in effect in
ciforth?
--
Krishna
On 4/8/26 3:48 PM, Gerry Jackson wrote:
On 08/04/2026 17:47, Krishna Myneni wrote:
On 4/8/26 6:16 AM, albert@spenarnc.xs4all.nl wrote:
In article <10r5bgp$3gdvd$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 07/04/2026 17:12, Anton Ertl wrote:
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:I think it was existing practice: Most systems did not support nested >>>>>> definitions when Forth-94 was standardized, and I guess that most
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.
It seems entirely frivolous to me, but maybe it is difficult to do >>>>>>> for
certain architectures.
systems do not support general nesting to this day, and when they do, >>>>>> the syntax is system-dependent.
I agree except that a few systems I tried compiled existing syntax
e.g.
: foo ... [ : bar ... ; ] ... ;
but the results didn't work
You didn't try ciforth.
~/PROJECT/ciforths/ciforth: lina -a
WANT -nesting-
[ : ISN'T UNIQUE
] : ISN'T UNIQUE
-nesting- : (WARNING) NOT PRESENT, THOUGH WANTED
OK
: hyp*2 [ : SQ DUP * ; ] SQ SWAP SQ + ;
OK
3 4 hyp*2 .
25 OK
...
I assume you can also compile :NONAME definitions while the current
definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ;
ok
3 4 hyp^2 .
25 ok
Works on my system. Both HYP^2 and SQ are added to the current wordlist.
...
Thanks, Gerry. I was going to suggest that maybe we can propose to get
the reference to :NONAME removed from the Forth 20xx standard statement
in 3.4.5 Compilation,
"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."
There may not be enough common practice, though.
--
Krishna
In article <10r84e9$9tt0$1@dont-email.me>,...
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
No, but you don't use nesting normally.Actually you can't. After -nesting- the brackets use the data stack extensively.
I assume you can also compile :NONAME definitions while the current
definition is suspended in ciforth e.g.
: hyp^2 [ :NONAME dup * ; ] literal dup >r execute swap r> execute + ; >>>> ok
3 4 hyp^2 .
25 ok
You enter an isolated world between [ and ] .
Your example could become
"
WANT -nesting- CASE-INSENSITIVE :NONAME
: hyp^2 [ :NONAME dup * ; CONSTANT NONAME ] NONAME dup >r execute swap r> execute + ;
"
So you can never use "[ ... ] LITERAL" when nesting is in effect in
ciforth?
I use extra facilities parsimonily.
I never do those LITERAL trick anyway.
In article <10r84nr$9tt0$2@dont-email.me>,....
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
"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."
There may not be enough common practice, though.
I propose a different view. A denotation can occupy (dictionary) space, e.g. a string.
"AAPESTRING" reserves space, and leaves a pointer to the data structure.
Like wise
{ DUP * } defines a behaviour and leaves a pointer. There is actually
not much difference.
On 4/9/26 9:41 AM, albert@spenarnc.xs4all.nl wrote:
In article <10r84nr$9tt0$2@dont-email.me>,....
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
"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."
There may not be enough common practice, though.
I propose a different view. A denotation can occupy (dictionary) space, e.g. >> a string.
"AAPESTRING" reserves space, and leaves a pointer to the data structure.
Like wise
{ DUP * } defines a behaviour and leaves a pointer. There is actually
not much difference.
The notation " ... }" conflicts directly with the Forth Scientific
Library notation for arrays of different types, unless "}" is simply a >delimiter for a parsing word. In your usage, I don't think "{" is a
parsing word.
I remember pointing this out when "{ ... }" was proposed for a newer
version of locals and the notation was changed.
--
Krishna
In article <10r8rgf$i0s4$2@dont-email.me>,
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
On 4/9/26 9:41 AM, albert@spenarnc.xs4all.nl wrote:
In article <10r84nr$9tt0$2@dont-email.me>,....
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
"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."
There may not be enough common practice, though.
I propose a different view. A denotation can occupy (dictionary) space, e.g.
a string.
"AAPESTRING" reserves space, and leaves a pointer to the data structure. >>> Like wise
{ DUP * } defines a behaviour and leaves a pointer. There is actually
not much difference.
The notation " ... }" conflicts directly with the Forth Scientific
Library notation for arrays of different types, unless "}" is simply a
delimiter for a parsing word. In your usage, I don't think "{" is a
parsing word.
I remember pointing this out when "{ ... }" was proposed for a newer
version of locals and the notation was changed.
We run out of brackets. Maybe abandon ( ) for comments, and use only \ .
Then ( ) is freed for math formulaes.
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of. Why, you ask? Because every name basically returns a pointer - unless we DOES> something different.
Sure, you can have different ways to store a value, but a parsing word? Really? And all of a sudden it should do different things depending on type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler figures out what the most optimal way of handling this retrieval or assignment is. Is the address known at compile time, we handle it like a VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some smart@$$ "TO" even less. What a waste of code.. And what a horrible design.
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of. Why, you ask? Because every name basically returns a pointer - unless we DOES> something different.
Sure, you can have different ways to store a value, but a parsing word? Really? And all of a sudden it should do different things depending on
type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler
figures out what the most optimal way of handling this retrieval or assignment is. Is the address known at compile time, we handle it like a VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some
smart@$$ "TO" even less. What a waste of code.. And what a horrible design.
Hans Bezemer
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of.
Why, you ask? Because every name basically returns a pointer - unless we >DOES> something different.
Sure, you can have different ways to store a value, but a parsing word? >Really? And all of a sudden it should do different things depending on
type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler
figures out what the most optimal way of handling this retrieval or >assignment is. Is the address known at compile time, we handle it like a >VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some
smart@$$ "TO" even less. What a waste of code.. And what a horrible design.
Hans Bezemer
In article <nnd$5fbdae9b$6428335d@7ddbf5ece7eb9625>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of.
Why, you ask? Because every name basically returns a pointer - unless we
DOES> something different.
Sure, you can have different ways to store a value, but a parsing word?
Really? And all of a sudden it should do different things depending on
type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler
figures out what the most optimal way of handling this retrieval or
assignment is. Is the address known at compile time, we handle it like a
VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some
smart@$$ "TO" even less. What a waste of code.. And what a horrible design.
In ciforth you can do this:
Prefixes ("recognizers") are supposed to be parsing the remainder
lf tne word, like $DEADBEAT
Abuse follows.
\ In the minimal wordlist, not masking regular @ !
'ONLY >WID CURRENT !
: @ NAME EVALUATE @ ; PREFIX IMMEDIATE
: ! NAME EVALUATE ! ; PREFIX IMMEDIATE
DEFINITINS \ Snap back.
VARIABLE AAP
12 !AAP
@AAP .
12 OK
13 !AAP
@AAP .
13 OK
Just saying.
(I don't recommend this, by the way.)
On 12/04/2026 6:03 am, albert@spenarnc.xs4all.nl wrote:
In article <nnd$5fbdae9b$6428335d@7ddbf5ece7eb9625>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:In ciforth you can do this:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of. >>> Why, you ask? Because every name basically returns a pointer - unless we >>> DOES> something different.
Sure, you can have different ways to store a value, but a parsing word?
Really? And all of a sudden it should do different things depending on
type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler
figures out what the most optimal way of handling this retrieval or
assignment is. Is the address known at compile time, we handle it like a >>> VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some
smart@$$ "TO" even less. What a waste of code.. And what a horrible design. >>
Prefixes ("recognizers") are supposed to be parsing the remainder
lf tne word, like $DEADBEAT
Abuse follows.
\ In the minimal wordlist, not masking regular @ !
'ONLY >WID CURRENT !
: @ NAME EVALUATE @ ; PREFIX IMMEDIATE
: ! NAME EVALUATE ! ; PREFIX IMMEDIATE
DEFINITINS \ Snap back.
VARIABLE AAP
12 !AAP
@AAP .
12 OK
13 !AAP
@AAP .
13 OK
Just saying.
(I don't recommend this, by the way.)
AFAICT the majority of HLL's use 'self-fetching' variables. Setting a >variable required something like := which corresponds to forth's TO.
IMO local variables in forth was less about 'stack juggling' than
simulating the 'look and feel' code of other languages. Forth locals
code uses a fair number of TO's. Hugh once suggested locals ought to
have used @ ! . This would have been very forth-like - but completely
misses what locals aficionados were trying to do!
For me at least, VALUEs are an 'almost CONSTANT' in which TO rarely gets >used. Without that distinction I'd find it hard justifying VALUEs - or >indeed know when to use them. By clearly stating their intent and usage, >they provide semantic value to written code and the language in general.
But I'm not sure ANS ever did say - leaving users to muddle it out for >themselves. Locals' use of 'values' and TO only muddied the waters.
On 12/04/2026 6:03 am, albert@spenarnc.xs4all.nl wrote:
In article <nnd$5fbdae9b$6428335d@7ddbf5ece7eb9625>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:In ciforth you can do this:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of. >>> Why, you ask? Because every name basically returns a pointer - unless we >>> DOES> something different.
Sure, you can have different ways to store a value, but a parsing word?
Really? And all of a sudden it should do different things depending on
type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler
figures out what the most optimal way of handling this retrieval or
assignment is. Is the address known at compile time, we handle it like a >>> VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some
smart@$$ "TO" even less. What a waste of code.. And what a horrible design. >>
Prefixes ("recognizers") are supposed to be parsing the remainder
lf tne word, like $DEADBEAT
Abuse follows.
\ In the minimal wordlist, not masking regular @ !
'ONLY >WID CURRENT !
: @ NAME EVALUATE @ ; PREFIX IMMEDIATE
: ! NAME EVALUATE ! ; PREFIX IMMEDIATE
DEFINITINS \ Snap back.
VARIABLE AAP
12 !AAP
@AAP .
12 OK
13 !AAP
@AAP .
13 OK
Just saying.
(I don't recommend this, by the way.)
AFAICT the majority of HLL's use 'self-fetching' variables. Setting a variable required something like := which corresponds to forth's TO.
IMO local variables in forth was less about 'stack juggling' than
simulating the 'look and feel' code of other languages.
Without that distinction I'd find it hard justifying VALUEs - or
indeed know when to use them. By clearly stating their intent and usage, they provide semantic value to written code and the language in general.
But I'm not sure ANS ever did say - leaving users to muddle it out for themselves. Locals' use of 'values' and TO only muddied the waters.
For me at least, VALUEs are an 'almost CONSTANT' in which TO rarely
gets used.
AFAICT the majority of HLL's use 'self-fetching' variables.
Forth locals
code uses a fair number of TO's. Hugh once suggested locals ought to
have used @ ! . This would have been very forth-like - but completely misses what locals aficionados were trying to do!
For me at least, VALUEs are an 'almost CONSTANT' in which TO rarely gets
used.
On 12-04-2026 12:13:
For me at least, VALUEs are an 'almost CONSTANT' in which TO rarely gets >>> used.
In a sense, CONSTANTs are *almost* VALUEs:
10 constant ten ok
16 ' ten ! ok
ten . 16 ok
It won't work like that in 4tH (because ' ten would return "10"), but it works fine in most Forths since '78.
Using this definition:
: reconstant state @ if postpone ['] postpone ! else ' ! then ; immediate
.. you could write:
16 RECONSTANT ten
.. and you'd *almost* have a VALUE. Cool, huh? :-)
On 12/04/2026 6:03 am, albert@spenarnc.xs4all.nl wrote:
In article <nnd$5fbdae9b$6428335d@7ddbf5ece7eb9625>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 07-04-2026 13:35, albert@spenarnc.xs4all.nl wrote:In ciforth you can do this:
A similar situation applies to "TO must scan". It turns out there
is no standard program that can detect this. It steers implementation
towards a scanning TO.
Frankly, I consider VALUE one of these Forth errors we never got rid of. >>> Why, you ask? Because every name basically returns a pointer - unless we >>> DOES> something different.
Sure, you can have different ways to store a value, but a parsing word?
Really? And all of a sudden it should do different things depending on
type? Yuk!
Personally, I do VALUE and TO. But only for VALUE. And the compiler
figures out what the most optimal way of handling this retrieval or
assignment is. Is the address known at compile time, we handle it like a >>> VALUE, otherwise like a VARIABLE.
And yeah, we have FTO and 2TO. I don't like it - but I like some
smart@$$ "TO" even less. What a waste of code.. And what a horrible design. >>
Prefixes ("recognizers") are supposed to be parsing the remainder
lf tne word, like $DEADBEAT
Abuse follows.
\ In the minimal wordlist, not masking regular @ !
'ONLY >WID CURRENT !
: @ NAME EVALUATE @ ; PREFIX IMMEDIATE
: ! NAME EVALUATE ! ; PREFIX IMMEDIATE
DEFINITINS \ Snap back.
VARIABLE AAP
12 !AAP
@AAP .
12 OK
13 !AAP
@AAP .
13 OK
Just saying.
(I don't recommend this, by the way.)
AFAICT the majority of HLL's use 'self-fetching' variables. Setting a
variable required something like := which corresponds to forth's TO.
IMO local variables in forth was less about 'stack juggling' than
simulating the 'look and feel' code of other languages. Forth locals
code uses a fair number of TO's. Hugh once suggested locals ought to
have used @ ! . This would have been very forth-like - but completely
misses what locals aficionados were trying to do!
For me at least, VALUEs are an 'almost CONSTANT' in which TO rarely gets >used. Without that distinction I'd find it hard justifying VALUEs - or >indeed know when to use them. By clearly stating their intent and usage, >they provide semantic value to written code and the language in general.
But I'm not sure ANS ever did say - leaving users to muddle it out for >themselves. Locals' use of 'values' and TO only muddied the waters.
On 13/04/2026 1:39 am, Hans Bezemer wrote:
On 12-04-2026 12:13:
For me at least, VALUEs are an 'almost CONSTANT' in which TO rarely gets >>>> used.
In a sense, CONSTANTs are *almost* VALUEs:
10 constant ten ok
16 ' ten ! ok
ten . 16 ok
It won't work like that in 4tH (because ' ten would return "10"), but it works fine in most Forths since '78.
It probably needs a >BODY . Forth-in-ROM then no cigar. Inlining compilers?
Do away with CONSTANTs and keep VALUEs ? :)
I presume that means that the coroutine yielding has to have its own
return and data stacks which I've not considered. If that's the case
then an alternative to call by name suggested below should be able to
handle that case.
IMO local variables in forth was less about 'stack juggling' than
simulating the 'look and feel' code of other languages. Forth locals
code uses a fair number of TO's. Hugh once suggested locals ought to
have used @ ! . This would have been very forth-like - but completely
misses what locals aficionados were trying to do!
Gerry Jackson <do-not-use@swldwa.uk> writes:
I presume that means that the coroutine yielding has to have its own
return and data stacks which I've not considered. If that's the case
then an alternative to call by name suggested below should be able to
handle that case.
Yes, that's correct about separate stacks. I'm not sure about the call
by name alternative. I think Forth does ok with multi-tasking (when >supported) instead of stackful coroutines.
dxf <dxforth@gmail.com> writes:
IMO local variables in forth was less about 'stack juggling' than
simulating the 'look and feel' code of other languages. Forth locals
code uses a fair number of TO's. Hugh once suggested locals ought to
have used @ ! . This would have been very forth-like - but completely
misses what locals aficionados were trying to do!
When I've used locals it's been to avoid contortions reaching into the
stack, including the floating point stack, where FPICK is non-standard. There's also the realization that computer memory except for a few specialized Forth chips is always made from RAM. So ideological
devotion to a pure stack VM seems to pass up perfectly good hardware capabilities.
Gforth does support address-like locals if you want to use them.
dxf <dxforth@gmail.com> writes:
IMO local variables in forth was less about 'stack juggling' than
simulating the 'look and feel' code of other languages. Forth locals
code uses a fair number of TO's. Hugh once suggested locals ought to
have used @ ! . This would have been very forth-like - but completely
misses what locals aficionados were trying to do!
When I've used locals it's been to avoid contortions reaching into the
stack, including the floating point stack, where FPICK is non-standard. There's also the realization that computer memory except for a few specialized Forth chips is always made from RAM. So ideological
devotion to a pure stack VM seems to pass up perfectly good hardware capabilities.
Gforth does support address-like locals if you want to use them.
I know there are situations when there are six values on the data
stack and four on the return stack which leave you with few other
options. But you can always use vanilla variables or an extra stack
(which is trivial to implement) to remedy that.
Using Forth means being resourceful. Not to choose the most convenient
and lazy solution imaginable.
Hans Bezemer <the.beez.speaks@gmail.com> writes:
I know there are situations when there are six values on the data
stack and four on the return stack which leave you with few other
options. But you can always use vanilla variables or an extra stack
(which is trivial to implement) to remedy that.
Using Forth means being resourceful. Not to choose the most convenient
and lazy solution imaginable.
Stack allocation is efficient because stack storage is released when the function returns. Global variables instead occupy storage even when the function isn't in use. And, implementing an extra stack under the interpreter is both extra contortions and extra overhead. "Resourceful" sounds more like "masochistic" here. I thought the idea was to do the straightforward thing. There is really something that I'm missing.
...
Forth advocates cautious use of globals. If it aids stack flow, efficiency, then use it. It's the *belief* locals are efficient, can replace stack ops, replace thinking, that is mistaken and leads to inefficiency. Even with
the resources, the fancy compilers, forth users still favour stack ops and thinking. So much so locals users have to use 'time saving' and 'ease' as justification.
c.l.f is traditionally political and controversial - and that's fine. But
on reddit forth where it's more laid back, locals don't get anything like
the support or coverage. If anything, there seems to be push-back - old hands correcting unwarranted notions that beginners may have picked up.
dxf <dxforth@gmail.com> writes:<SNIP>
I once wrote a function that used floating-point locals and was
recursive, so globals wouldn't have worked, and I didn't see a way to use >stack juggling, and implementing an auxiliary stack sounded absurd.
So I saw no way to avoid the locals.
dxf <dxforth@gmail.com> writes:
Forth advocates cautious use of globals. If it aids stack flow, efficiency, >> then use it. It's the *belief* locals are efficient, can replace stack ops, >> replace thinking, that is mistaken and leads to inefficiency. Even with
the resources, the fancy compilers, forth users still favour stack ops and >> thinking. So much so locals users have to use 'time saving' and 'ease' as >> justification.
In a simple interpreter, can be inefficient, but that doesn't bother me
too much. "Time saving" and "ease" count for a lot. That's why Forth
was developed in the first place if I'm not mistaken. To be quicker and easier than programming in assembly language, though much slower.
In asm though, one can program in a stack-oriented style while still accessing the stack interior. So Forth has lost something by
comparison, ISTM.
I once wrote a function that used floating-point locals and was
recursive, so globals wouldn't have worked, and I didn't see a way to use stack juggling, and implementing an auxiliary stack sounded absurd.
So I saw no way to avoid the locals.
It occurs to me now that I could maybe get the binary float
representations using "F," and juggle them on to the D and R stacks, but yecch.
c.l.f is traditionally political and controversial - and that's fine. But >> on reddit forth where it's more laid back, locals don't get anything like
the support or coverage. If anything, there seems to be push-back - old
hands correcting unwarranted notions that beginners may have picked up.
I'm not sure what you mean here. Do you mean CLF is more pro-locals
than Reddit Forth?
In asm though, one can program in a stack-oriented style while still accessing the stack interior. So Forth has lost something by
comparison, ISTM.
I once wrote a function that used floating-point locals and was
recursive, so globals wouldn't have worked, and I didn't see a way to use stack juggling, and implementing an auxiliary stack sounded absurd.
So I saw no way to avoid the locals.
Perhaps Wil Baden's locals scheme:
https://www.taygeta.com/fsl/library/fsl-util.fs
On 25-04-2026 14:06, dxf wrote:
Perhaps Wil Baden's locals scheme:
https://www.taygeta.com/fsl/library/fsl-util.fs
We do have N>R (https://forth-standard.org/standard/tools/NtoR). So if the whole problem is "there is no more room on the FP stack", there is a way out.
We do have N>R (https://forth-standard.org/standard/tools/NtoR). So if
the whole problem is "there is no more room on the FP stack", there is
a way out.
On 25/04/2026 11:11 pm, Hans Bezemer wrote:
On 25-04-2026 14:06, dxf wrote:
Perhaps Wil Baden's locals scheme:
https://www.taygeta.com/fsl/library/fsl-util.fs
We do have N>R (https://forth-standard.org/standard/tools/NtoR). So if the whole problem is "there is no more room on the FP stack", there is a way out.
Occasionally there's a proposal for F>R FR> but interest has always been lacking - despite it potentially addressing 'stack juggling', recursion etc. How to explain other than 'solution looking for a problem'? ISTM locals
are the same. In the following reply, the underwhelment is palpable.
https://youtu.be/V9ES9UZHaag?t=3065
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:
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.
It seems entirely frivolous to me, but maybe it is difficult to do for
certain architectures.
I think it was existing practice: Most systems did not support nested definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
- anton
On 07-04-2026 18:12, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
It is in section 3.4.5, in particular the 2nd paragraph:
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.
It seems entirely frivolous to me, but maybe it is difficult to do for
certain architectures.
I think it was existing practice: Most systems did not support nested
definitions when Forth-94 was standardized, and I guess that most
systems do not support general nesting to this day, and when they do,
the syntax is system-dependent.
- anton
4tH has supported nested definitions since its inception. But - agreed -
it doesn't have a dictionary, which makes the whole thing a lot easier.
You see, the 4tH ":" word dumps a location and a reference on the
control stack - and compiles a BRANCH. Any nested definition does the
same thing. ":NONAME" compiles a location as a literal and then does the
same thing as ":".
That's all.
Hans Bezemer
In article <10sqcrp$35rsn$1@dont-email.me>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
4tH has supported nested definitions since its inception. But - agreed -
it doesn't have a dictionary, which makes the whole thing a lot easier.
You see, the 4tH ":" word dumps a location and a reference on the
control stack - and compiles a BRANCH. Any nested definition does the
same thing. ":NONAME" compiles a location as a literal and then does the
same thing as ":".
ciforth does approximately the same thing. A dictionary and wordlists
doesnot make this difficult. However an anonymous definition is
bracketed with { } . :NONAME ending with a semi colon is a mistake.
It's an old problem - something that ought not be required, yet appears to fill a need. In addition to VALUE, I have INTEGER (aka 0 VALUE). Thus far I've not tired of it. Sometimes I could use 2VALUE in an app but have resisted the urge. The occasions are simply too few to warrant. I provide definitions for 2VALUE 2TO FVALUE FTO should a user really, really, want them.
Hans Bezemer <the.beez.speaks@gmail.com> writes:
Using Forth means being resourceful. Not to choose the most convenient
and lazy solution imaginable.
Stack allocation is efficient because stack storage is released when the function returns. Global variables instead occupy storage even when the function isn't in use. And, implementing an extra stack under the interpreter is both extra contortions and extra overhead.
I do remember writing some words a while ago to implement multiple
stacks, so there are reasons to want those sometimes.
"Resourceful"
sounds more like "masochistic" here.
I thought the idea was to do the
straightforward thing.
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,116 |
| Nodes: | 10 (0 / 10) |
| Uptime: | 88:36:44 |
| Calls: | 14,306 |
| Calls today: | 1 |
| Files: | 186,338 |
| D/L today: |
1,422 files (469M bytes) |
| Messages: | 2,525,555 |