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

RfD - Enhanced local variable syntax, v4 (long)

14 views
Skip to first unread message

Stephen Pelc

unread,
Aug 11, 2008, 8:56:24 AM8/11/08
to
Well, it's that time of year again, so I'm in proposal mode.
Don't forget to attend EuroForth 2008 and the Forth200x standards
meeting in gorgeous glorious Vienna from 25-28 September 2008.
http://www.euroforth.org

I have separated the enhanced local variable syntax from the
local buffer proposal. The main extension in this proposal
is the separation of initialised local arguments from
uninitialised local values.

Stephen

RfD - Enhanced local variable syntax, v4
====================================
Stephen Pelc - 11 August 2008

20080811 Removed references to local buffers as appropriate.
20070914 Moved local buffers to separate proposal.
20070607 Wordsmithing. Corrected reference implementation.
20060822 Added explanatory text.
Corrected reference implementation.
Updated ambiguous conditions.

Problem
=======
1) The current LOCALS| ... | notation explicitly forces all locals
to be initialised from the data stack.
2) 1) The current LOCALS| ... | notation defines locals in reverse
order to the normal stack notation.

This proposal is derived from implementations that have existed for
more than 15 years.


Solution
========
Base version
------------
The following syntax for local arguments and local values is
proposed. The sequence:
{ ni1 ni2 ... | lv1 lv2 ... -- o1 o2 ... }
defines local arguments, local values, and outputs. The local
arguments are automatically initialised from the data stack on
entry, the rightmost being taken from the top of the data stack.
Local arguments and local values can be referenced by name within
the word during compilation. The output names are dummies to allow
a complete stack comment to be generated.
The items between { and | are local arguments.
The items between | and -- are local values or local buffers.
The items between -- and } are outputs for formal comments only.

The outputs are provided in the notation so that complete stack
comments can be produced. However, all text between -- and } is
ignored. The facility is there to permit the notation to form a
complete stack comment. This eases documentation and current
users of the notation like this facility.

Local arguments and values return their values when referenced,
and must be preceded by TO to perform a store.

Any name ending in the '[' character is reserved for compatibility
with existing implementations.

In the example below, a and b are local arguments, a+b and a*b are
local values, and arr[ is a 10 byte local buffer.

: foo { a b | a+b a*b -- }
a b + to a+b
a b * to a*b
cr a+b . a*b .
;

Local types and extensions
--------------------------
Some current Forth systems use indicators to define local values
of sizes other than a cell. It is proposed that any name ending
in a ':' (colon) be reserved for this use.

: foo { a b | F: f1 F: f2 -- c }
...
;

At least one significant Forth implementation uses local value
names ending in the '[' character to indicate local buffers. This
character is reserved to prevent disenfranchising implementations
that have that behaviour. For similar reasons the use of '[' and
'\' as local argument or value names is also reserved.


Discussion
==========
The '|' (ASCII 0x7C) character is widely used as the separator
between local arguments and local values. Other characters
accepted in current Forth implementations are '\' (ASCII 0x5C) and
'Ś' (ASCII 0xA6).. Since the ANS standard is defined in terms of
7 bit ASCII, and with regard to internationalistion, we propose only
to consider the '|' and '\' characters further. Only recognition of
the '|' separator is mandatory.

The use of local types is contentious as they only become useful
if TO is available for these. In practice, some current systems
permit TO to be used with floats (children of FVALUE) and other
data types. Such systems often provide additional operators such
as +TO (add from stack to item) for children of VALUE and FVALUE.
Standardisation of operators with (for example) floats needs to
be done before the local types extension can be incorporated into
Forth200x. Apart from forcing allocation of buffer space, no
additional functionality is provided by local types that cannot
be obtained using local buffers. More preparatory standardisation
needs to be done before local types can be standardised.

It has been noted that one widely used implementation uses brace
for multiline comments. However, inspection of the vendor's code
shows that this use only occurs during interpretation. The
interpretation semantics of brace in this proposal are undefined
in order for that implementation to coexist with this proposal.


Forth 200x text
===============
13.6.2.xxxx {
brace LOCAL EXT

Interpretation: Interpretation semantics for this word are undefined.

Compilation:
( "<spaces>arg1" ... "<spaces>argn" | "<spaces>lv1" ... "<spaces>lvn"
-- )

Create up to eight local arguments by repeatedly skipping leading
spaces, parsing arg, and executing implementation defined actions.
The list of local arguments to be defined is terminated by "|",
"--" or "}". Append the run-time semantics for local arguments
given below to the current definition. If a space delimited '|' is
encountered, create up to eight local values by repeatedly skipping
leading spaces, parsing the "lv" token, and creating the local
element. The list of local values to be defined is terminated by
"--" or "}". Append the run-time semantics for local values
given below to the current definition. If "--" has
been encountered, further text between "--" and } is ignored.

Local argument run-time: ( x1 ... xn -- )
Local value run-time: ( -- )

Initialize up to eight local arguments from the data stack
Local argument arg1 is initialized with x1, arg2 with x2 up
to argn from xn, which is on the top of the data stack. When
invoked, each local argument will return its value. The value
of a local argument may be changed using 13.6.1.2295 TO.

Initialize up to eight local values. The initial contents of local
values are undefined. When invoked, each local value
returns its value. The value of a local value may be changed
using 13.6.1.2295 TO. The size of a local value is a cell.
The user may make no assumption about the order and contiguity of
local values in memory.

Ambiguous conditions:
a) The { ... } text extends over more than one line.
b) { ... } is declared more than once in a word.
c) Parsing units '|', ']', '--' and '}' are not whitespace delimited.


Reference implementation
=========================
(currently untested)

0 [if]
BUILDLV c-addr u +n mode
When executed during compilation, BUILDLV passes a message to the
system identifying a new local argument whose definition name is
given by the string of characters identified by c-addr u. The size
of the data item is given by +n address units, and the mode
identifies the construction required as follows:
0 - finish construction of initialisation and data storage
allocation code. C-addr and u are ignored. +n is 0
(other values are reserved for future use).
1 - identify a local argument, +n = cell
2 - identify a local value, +n = cell
3+ - reserved for future use
-ve - implementation specific values

The result of executing BUILDLV during compilation of a definition
is to create a set of named local arguments, values and/or
buffers, each of which is a definition name, that only have
execution semantics within the scope of that definition's source.
[then]

: BUILDLV \ c-addr u +n mode --
\ Dummy for testing
CR 2SWAP TYPE SPACE SWAP . .
;

: TOKEN \ -- caddr u
\ Get the next space delimited token from the input stream.
\ Can be extended to permit multiple line declarations.
PARSE-NAME
;

: LTERM? \ caddr u -- flag
\ Return true if the string caddr/u is "--" or "}"
2DUP S" --" COMPARE 0= >R
S" }" COMPARE 0= R> OR
;

: LSEP? \ caddr u -- flag
\ Return true if the string caddr/u is the separator between
\ local arguments and local values or buffers.
2DUP S" |" COMPARE 0= >R
S" \" COMPARE 0= R> OR
;

: { ( -- )
0 >R \ indicate arguments
BEGIN
TOKEN 2DUP LTERM? 0=
WHILE \ -- caddr len
2DUP LSEP? IF \ if '|'
R> DROP 1 >R \ change to vars and buffers
ELSE
R@ 0= IF \ argument?
CELL 1
ELSE \ value or buffer
CELL 2
THEN
BUILDLV
THEN
REPEAT
BEGIN
S" }" COMPARE
WHILE
TOKEN
REPEAT
0 0 0 0 BUILDLV
R> DROP
; IMMEDIATE

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

Josh Grams

unread,
Aug 11, 2008, 10:35:47 AM8/11/08
to
Stephen Pelc wrote:
> In the example below, a and b are local arguments, a+b and a*b are
> local values, and arr[ is a 10 byte local buffer.
>
>: foo { a b | a+b a*b -- }
> a b + to a+b
> a b * to a*b
> cr a+b . a*b .
> ;

Looks like you missed this text when removing the local buffer stuff...

--Josh

Andrew Haley

unread,
Aug 11, 2008, 12:10:06 PM8/11/08
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> The following syntax for local arguments and local values is
> proposed. The sequence:
> { ni1 ni2 ... | lv1 lv2 ... -- o1 o2 ... }
> defines local arguments, local values, and outputs. The local
> arguments are automatically initialised from the data stack on
> entry, the rightmost being taken from the top of the data stack.
> Local arguments and local values can be referenced by name within
> the word during compilation. The output names are dummies to allow
> a complete stack comment to be generated.
> The items between { and | are local arguments.
> The items between | and -- are local values or local buffers.
> The items between -- and } are outputs for formal comments only.

So far, reasonable enough.

> The outputs are provided in the notation so that complete stack
> comments can be produced. However, all text between -- and } is
> ignored. The facility is there to permit the notation to form a
> complete stack comment. This eases documentation and current
> users of the notation like this facility.

No, this is vile. Mixing semantically significant code with comments
in such an arbitrary way is a bad idea: it has no precedent in Forth,
and it is unnecessarily confusing. I thought that { a b -- c d }
meant that the contents of the variables after the "--" would be
automatically returned as the result, but this is not what happens.
While this convention may be in use in some systems it isn't suitable
for standardization.

In any case, it makes no sense to use the { } as the stack comment
for a word since not every to a word need be placed into a local
variable.

Andrew.

Aleksej Saushev

unread,
Aug 11, 2008, 3:41:12 PM8/11/08
to
steph...@mpeforth.com (Stephen Pelc) writes:

> Well, it's that time of year again, so I'm in proposal mode.
> Don't forget to attend EuroForth 2008 and the Forth200x standards
> meeting in gorgeous glorious Vienna from 25-28 September 2008.
> http://www.euroforth.org
>

> RfD - Enhanced local variable syntax, v4

> Stephen Pelc - 11 August 2008

...

> Any name ending in the '[' character is reserved for compatibility
> with existing implementations.

I don't like standards, which start from exceptions.
Why is this the only character reserved?
Why don't we reserve other characters from "!@#$%^&*()[]\~;':<>?,./" set?

Instead of conceptually clear syntax you're making precedent for all sort
of quirks. I strongly object to such attitude to the standard.
It is going to be yet another Perl at this pace.

If you want some characters to be reserved, put your locals library
into public domain and let it spread. At least we'll see, what is
actually used in community.


--
CE3OH...

Stephen Pelc

unread,
Aug 11, 2008, 6:00:52 PM8/11/08
to
On Mon, 11 Aug 2008 23:41:12 +0400, Aleksej Saushev <as...@inbox.ru>
wrote:

>steph...@mpeforth.com (Stephen Pelc) writes:
>> Any name ending in the '[' character is reserved for compatibility
>> with existing implementations.
>
>I don't like standards, which start from exceptions.
>Why is this the only character reserved?

As you quoted


"for compatibility with existing implementations."

To prevent code breakage in VFX Forth systems both hosted and
embedded. MPE has been using the nortation
: foo { a b | c d e[ 5 cells ] f[ 7 cells ] -- }
for local arrays for 15 years or so. I'm not silly enough to
put forward a proposal that will break our own code. See the
local buffers proposal.

The point of this proposal is that it introduces uninitialised
local values as well as local arguments.

>If you want some characters to be reserved, put your locals library
>into public domain and let it spread. At least we'll see, what is
>actually used in community.

See the reference implementation(s). Yes, there's carnal knowledge
involved, but if you've already implemented (LOCAL), implementing
BUILDLV is trivial. AS I've already said we've used it for 15 years,
and variants with a similar notation exist in Win32Forth and gForth.

Stephen

Elizabeth D Rather

unread,
Aug 11, 2008, 6:23:35 PM8/11/08
to

I strongly agree with Andrew. You shouldn't try to mix syntactic
elements with comments. Among other things, it creates the necessity
for reserving [ which Alexei deplores, and I do as well. This is
opening all sorts of Pandors's Boxes.

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

Stephen Pelc

unread,
Aug 11, 2008, 6:15:20 PM8/11/08
to
On Mon, 11 Aug 2008 11:10:06 -0500, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>> The outputs are provided in the notation so that complete stack
>> comments can be produced. However, all text between -- and } is
>> ignored. The facility is there to permit the notation to form a
>> complete stack comment. This eases documentation and current
>> users of the notation like this facility.
>
>No, this is vile. Mixing semantically significant code with comments
>in such an arbitrary way is a bad idea: it has no precedent in Forth,
>and it is unnecessarily confusing.

You don't have to do it that way
{ a b | c d }
is legal according to the proposal. There are, believe it or not,
Forth systems out there that use '--' as a comment to end of line.

To rephrase in a reductionist way:


"Mixing semantically significant code with comments

is a bad idea"
So all comments are a bad idea?

As you well know, the point of the '--' is to avoid having to
write both a stack comment and a very similar locals declaration.
As you well know, having those will be a source of error, so
in the best Forth practice, we eliminate the source of error.
After 15 years of use we and our clients know that this brace
notation works well. That it also exists in a similar form in
Win32Forth and gForth indicates utility. If you don't like
the '--', don't use it, and write a stack comment as well as
the locals declaration. Your choice.

Stephen

Stephen Pelc

unread,
Aug 11, 2008, 8:19:19 PM8/11/08
to
On Mon, 11 Aug 2008 12:23:35 -1000, Elizabeth D Rather
<era...@forth.com> wrote:

>I strongly agree with Andrew. You shouldn't try to mix syntactic
>elements with comments. Among other things, it creates the necessity
>for reserving [ which Alexei deplores, and I do as well.

The [ reservation has *nothing* to do with ignoring the section
between '--' and '}'. The '--' marker is *optional*.

This proposal has existed in VFX Forth and its predecessors for 15+
years and is supported (without the '[' reservation) in Win32Forth
and gforth.

Stephen

Stephen Pelc

unread,
Aug 11, 2008, 8:53:26 PM8/11/08
to
On Mon, 11 Aug 2008 23:41:12 +0400, Aleksej Saushev <as...@inbox.ru>
wrote:

>Instead of conceptually clear syntax you're making precedent for all sort


>of quirks. I strongly object to such attitude to the standard.
>It is going to be yet another Perl at this pace.

It's a standards proposal. The conceptual clarity comes from
considering the brace notation as a formal comment that mirrors
the conventional stack comment notation:
( a b c -- d e }
This now extended to include local values by adding the '|'
separator and changing the brackets to braces:
{ a b c | x y z -- d e }
Since we permit the data stack and return stack to be manipulated
between the closing '}' and ';' we chose 15+ years ago to ignore
what is between the '--' and the closing brace.

>If you want some characters to be reserved, put your locals library
>into public domain and let it spread. At least we'll see, what is
>actually used in community.

The system is implemented in Win32Forth and gforth (without the '['
reservation. The reservation (should be an ambiguous condition?) is
simply to indicate that VFX Forth uses it to mean something, and that
there is body of code in the wild that uses that meaning. I suspect
that use in VFX Forth, Win32Forth and gforth means that the idea has
traction.

None of the proposed local buffer notations read particularly
well, yet the facility is available one one way or another in
most Forths used for large applications. However, because of the
flame wars that arose in the previous draft proposal, I split
the local buffer extension into a separate proposal. The new
local buffer proposal adopt's Ed's notation which arose during
the last round of discussion.

I propose that the discussion of '[' and friends now moves to
the local buffer thread.

Stephen

Doug Hoffman

unread,
Aug 11, 2008, 11:27:05 PM8/11/08
to
Andrew Haley wrote:

>> The outputs are provided in the notation so that complete stack
>> comments can be produced. However, all text between -- and } is
>> ignored. The facility is there to permit the notation to form a
>> complete stack comment. This eases documentation and current
>> users of the notation like this facility.
>
> No, this is vile. Mixing semantically significant code with comments
> in such an arbitrary way is a bad idea: it has no precedent in Forth,

It works just the same as what I've used on two different Forths.

> and it is unnecessarily confusing. I thought that { a b -- c d }
> meant that the contents of the variables after the "--" would be
> automatically returned as the result, but this is not what happens.

Thankfully. That is too much automation, IMHO.


> While this convention may be in use in some systems it isn't suitable
> for standardization.

Where is the harm? 9 times out of 10 the { ... } locals declaration
can
do double duty as a stack effect comment. Yes, there are times where
it
doesn't quite work and then we have to do something like:

: foo ( a b c -- d )
{ b c }

no big deal, really and it is obvious what is going on


> In any case, it makes no sense to use the { } as the stack comment
> for a word since not every to a word need be placed into a local
> variable.

It is easy to handle that case in a way similar to what I've shown
just
above.

Again, I strongly prefer the ability to have the locals declaration do
double duty as a stack comment. It does no harm and most of the time
is
a help (less typing if the stack comment matches the locals
declaration,
which is often the case).

-Doug

Doug Hoffman

unread,
Aug 11, 2008, 11:27:47 PM8/11/08
to
Stephen Pelc wrote:

> It's a standards proposal. The conceptual clarity comes from
> considering the brace notation as a formal comment that mirrors
> the conventional stack comment notation:
> ( a b c -- d e }
> This now extended to include local values by adding the '|'
> separator and changing the brackets to braces:
> { a b c | x y z -- d e }
> Since we permit the data stack and return stack to be manipulated
> between the closing '}' and ';' we chose 15+ years ago to ignore
> what is between the '--' and the closing brace.

I actually thought I responded to this almost 12 hours ago. But I
don't
see it. So apologies if this is redundant.

Stephen is right. Having the benign "-- d e" does no harm but can
help
significantly in having the locals declaration do double duty as the
stack effect comment. This applies to most cases for me. Where the
stack effect doesn't match the locals declaration, no problem. Just
declare them separately. For example:

: foo ( a b c -- d e ) { b c }
...


> The system is implemented in Win32Forth and gforth

It is also used in Neon, Yerk, and PowerMops: spanning 24+ years of
successful use.

-Doug


Anton Ertl

unread,
Aug 12, 2008, 4:53:53 AM8/12/08
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:

>Stephen Pelc <steph...@mpeforth.com> wrote:
>> However, all text between -- and } is
>> ignored. The facility is there to permit the notation to form a
>> complete stack comment. This eases documentation and current
>> users of the notation like this facility.
>
>No, this is vile. Mixing semantically significant code with comments
>in such an arbitrary way is a bad idea: it has no precedent in Forth,
>and it is unnecessarily confusing.

This has been used for many years in many systems, so there is ample
precedent. And the users have not found it confusing, and I don't
remember a complaint about that part of the notation as used in real
code.

Let's consider one example (the first use of locals in
<http://www.complang.tuwien.ac.at/viewcvs/cgi-bin/viewcvs.cgi/gforth/libcc.fs?view=markup>

: front-string { c-addr1 u1 c-addr2 u2 -- c-addr3 u3 }
\ insert string c-addr2 u2 in buffer c-addr1 u1; c-addr3 u3 is the
\ remainder of the buffer.
assert( u1 u2 u>= )
c-addr2 c-addr1 u2 move
c-addr1 u1 u2 /string ;

Without the -- part we would have to write:

: front-string ( c-addr1 u1 c-addr2 u2 -- c-addr3 u3 )
\ insert string c-addr2 u2 in buffer c-addr1 u1; c-addr3 u3 is the
\ remainder of the buffer.
{ c-addr1 u1 c-addr2 u2 }
assert( u1 u2 u>= )
c-addr2 c-addr1 u2 move
c-addr1 u1 u2 /string ;

This is harder to read and write, and thus would discourage factoring.
Also, it adds redundancy, and that tends to lead to errors that are
relatively hard to find.

>I thought that { a b -- c d }
>meant that the contents of the variables after the "--" would be
>automatically returned as the result

That would throw away some of the advantages of having a stack, and
would require using locals where they are not needed. It would also
make the code longer. For the example above that would result in:

: front-string { c-addr1 u1 c-addr2 u2 -- c-addr3 u3 }
\ insert string c-addr2 u2 in buffer c-addr1 u1; c-addr3 u3 is the
\ remainder of the buffer.
assert( u1 u2 u>= )
c-addr2 c-addr1 u2 move
c-addr1 u1 u2 /string to u3 to c-addr3 ;

Not an improvement.

Anyway, that idea conflicts with the existing usage in many programs
and systems, so it wouldn't fly even if it was a good idea.

>In any case, it makes no sense to use the { } as the stack comment
>for a word since not every to a word need be placed into a local
>variable.

If you don't need every parameter as a local (that's what you meant,
right?), you are free to write an ordinary stack comment followed by a
locals definition without (or, if you want, with) "--".

- 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 2008: http://www.euroforth.org/ef08.html

Andrew Haley

unread,
Aug 12, 2008, 6:42:06 AM8/12/08
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Mon, 11 Aug 2008 11:10:06 -0500, Andrew Haley
> <andr...@littlepinkcloud.invalid> wrote:

> >> The outputs are provided in the notation so that complete stack
> >> comments can be produced. However, all text between -- and } is
> >> ignored. The facility is there to permit the notation to form a
> >> complete stack comment. This eases documentation and current
> >> users of the notation like this facility.

> >No, this is vile. Mixing semantically significant code with
> >comments in such an arbitrary way is a bad idea: it has no
> >precedent in Forth, and it is unnecessarily confusing.

> You don't have to do it that way
> { a b | c d }
> is legal according to the proposal. There are, believe it or not,
> Forth systems out there that use '--' as a comment to end of line.

> To rephrase in a reductionist way:
> "Mixing semantically significant code with comments
> is a bad idea"
> So all comments are a bad idea?

No, of course not. Comments are *separated* from the surrounding code
by clearly visible comment markers.

> As you well know, the point of the '--' is to avoid having to write
> both a stack comment and a very similar locals declaration. As you
> well know, having those will be a source of error, so in the best
> Forth practice, we eliminate the source of error.

How can that be so? The locals declaration and the stack comment
aren't necessarily the same.

> After 15 years of use we and our clients know that this brace
> notation works well. That it also exists in a similar form in
> Win32Forth and gForth indicates utility.

> If you don't like the '--', don't use it, and write a stack comment
> as well as the locals declaration. Your choice.

There is a very good part to this proposal, the part that allows for
un-initialized locals. There is also some syntactic sugar. And in
this case it's pure syntactic sugar: the part of the clause after "--"
has no effect whatsoever.

I guess you could justify any extension to Forth, no matter how awful,
with "You don't have to use it." I already know I don't have to use
it: the question is not whether I have to use it but whether something
this nasty should be standardized. Just to turn your argument around,
if you want a comment, why not do:

{ a b | c d ( -- n m ) }

At least then it's immediately obvious where the comment is. Forth
already has two comment syntaxes -- one more than it needs -- and
you're adding yet another.

This proposal is like the famous Pork Barrel bills in the US where a
senator will add a rider to support his home state to an essential
finance bill. People then have a single choice: yea or nay to the
bill. If you want the finance bill passed, vote for the senator's
rider.

Dammit Steve, I really want to support this, but...

Andrew.

Andrew Haley

unread,
Aug 12, 2008, 6:50:11 AM8/12/08
to

If you really want rest of the stack comment in the braces, put it
there:

: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }


\ insert string c-addr2 u2 in buffer c-addr1 u1; c-addr3 u3 is the
\ remainder of the buffer.

assert( u1 u2 u>= )
c-addr2 c-addr1 u2 move
c-addr1 u1 u2 /string ;

or here:

: front-string { c-addr1 u1 c-addr2 u2 } ( -- c-addr3 u3 )


\ insert string c-addr2 u2 in buffer c-addr1 u1; c-addr3 u3 is the
\ remainder of the buffer.

assert( u1 u2 u>= )
c-addr2 c-addr1 u2 move
c-addr1 u1 u2 /string ;

At least then it's immediately clear which part is the comment and
which the initialization of locals.

> This is harder to read and write, and thus would discourage factoring.
> Also, it adds redundancy, and that tends to lead to errors that are
> relatively hard to find.

There is no added redundancy, it's *easier* to read and it's not
significantly harder to write.

> >I thought that { a b -- c d } meant that the contents of the
> >variables after the "--" would be automatically returned as the
> >result

> That would throw away some of the advantages of having a stack, and
> would require using locals where they are not needed. It would also
> make the code longer.

It would. It's a despicable, dreadful idea. But it's what the
comment suggests.

Andrew.

Stephen Pelc

unread,
Aug 12, 2008, 10:34:58 AM8/12/08
to
On Tue, 12 Aug 2008 05:42:06 -0500, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>Stephen Pelc <steph...@mpeforth.com> wrote:
>> As you well know, the point of the '--' is to avoid having to write
>> both a stack comment and a very similar locals declaration. As you
>> well know, having those will be a source of error, so in the best
>> Forth practice, we eliminate the source of error.
>
>How can that be so? The locals declaration and the stack comment
>aren't necessarily the same.

Experience shows that in the majority of cases, they are.

>There is a very good part to this proposal, the part that allows for
>un-initialized locals. There is also some syntactic sugar. And in
>this case it's pure syntactic sugar: the part of the clause after "--"
>has no effect whatsoever.

It aids readability. I happen to think that's important.

I have been reminded that this notation is also supported by
Neon, Yerks and PowerMops, and has been in use for 24+ years.
One part of writing a standard is to formalise common practice.
Common practice is here in conflict with language purity.

The notation is a reasonable compromise for those who need
local values. It is sufficiently widespread and has enough
history to say that it is common practice.

>At least then it's immediately obvious where the comment is. Forth
>already has two comment syntaxes -- one more than it needs -- and
>you're adding yet another.

It's not for text comments - it's for completing a stack notation.
Certainly using the facility for text comments is bad practice, but
avoiding duplicate and potentially conflicting entries is good
practice, even at the expense of minor impurity that does not have
to be used by ideologues.

Stephen Pelc

unread,
Aug 12, 2008, 10:42:14 AM8/12/08
to
On Tue, 12 Aug 2008 05:50:11 -0500, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>If you really want rest of the stack comment in the braces, put it
>there:
>
>: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }

Now we've got to change common practice, and rewrite any validation
tools we may be using. In other words, this notation is a code
breaker. One of the successful parts of the ANS process was the
stringent effort to avoid breaking existing code.

>: front-string { c-addr1 u1 c-addr2 u2 } ( -- c-addr3 u3 )

Now you have broken code readability for those people (and they
exist) who use double comments on name lines to indicate either
compile and runtime actions of defining words, or to indicate
data stack and return stack actions.

Again, for a standard, common practice is important.

Stephen

Jonah Thomas

unread,
Aug 12, 2008, 11:11:57 AM8/12/08
to
steph...@mpeforth.com (Stephen Pelc) wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> wrote:
>
> >If you really want rest of the stack comment in the braces, put it
> >there:
> >
> >: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }
>
> Now we've got to change common practice, and rewrite any validation
> tools we may be using. In other words, this notation is a code
> breaker. One of the successful parts of the ANS process was the
> stringent effort to avoid breaking existing code.

I don't particularly advocate that change, but would it break much code?
You could rewrite a few vaidation tools to accept the new practice -- as
well as continue to accept what you already do. Or if you happen to
allow ( inside { then wouldn't the new code just work? Surely you don't
*require* every { to have a -- ending } addition, do you? If it's
commented out have you lost anything?

It does make sense to stay with common practice as a general rule, and I
don't see that this change would be an improvement. But would it really
break existing code?

Stephen Pelc

unread,
Aug 12, 2008, 12:19:28 PM8/12/08
to
On Tue, 12 Aug 2008 11:11:57 -0400, Jonah Thomas <jeth...@gmail.com>
wrote:

>steph...@mpeforth.com (Stephen Pelc) wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> wrote:
>>
>> >If you really want rest of the stack comment in the braces, put it
>> >there:
>> >
>> >: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }
>>
>> Now we've got to change common practice, and rewrite any validation
>> tools we may be using. In other words, this notation is a code
>> breaker. One of the successful parts of the ANS process was the
>> stringent effort to avoid breaking existing code.
>
>I don't particularly advocate that change, but would it break much code?
>You could rewrite a few vaidation tools to accept the new practice -- as
>well as continue to accept what you already do. Or if you happen to
>allow ( inside { then wouldn't the new code just work? Surely you don't
>*require* every { to have a -- ending } addition, do you? If it's
>commented out have you lost anything?

The majority of existing systems will generate and extra local called
'('. This will not be used. So I would expect most systems to survive.
However, we have tools with clients that process stack comments with
braces. These will have to be upgraded if they the client upgrades the
compiler.

We have to reserve '(', and presumably also '\'. Think of the
firestorm about the '[' reservation. Win32Forth accepts '\' as well
as '|' as the arguments/values separator. IMHO, staying with common
practice avoids the law of unintended consequences.

>It does make sense to stay with common practice as a general rule, and I
>don't see that this change would be an improvement. But would it really
>break existing code?

Yes.

Doug Hoffman

unread,
Aug 12, 2008, 12:27:10 PM8/12/08
to
On Aug 12, 11:11 am, Jonah Thomas <jethom...@gmail.com> wrote:
> stephen...@mpeforth.com (Stephen Pelc) wrote:

> > Andrew Haley <andre...@littlepinkcloud.invalid> wrote:
>
> > >If you really want rest of the stack comment in the braces, put it
> > >there:
>
> > >: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }
>
> > Now we've got to change common practice, and rewrite any validation
> > tools we may be using. In other words, this notation is a code
> > breaker. One of the successful parts of the ANS process was the
> > stringent effort to avoid breaking existing code.
>
> I don't particularly advocate that change, but would it break much code?

It breaks on PowerMops:

: foo { a b c d ( -- e f ) }
a b + c d + ;

Error # 245 ')' read when '}' expected
: foo { a b c d ( -- e f ) }
^

It breaks on my Carbon MacForth implementation (based on Roelf
Toxopeus's code):

: foo { a b c d ( -- e f ) }
a b + c d + ;

1 2 3 4 foo .s

( 1 ) \ 5

> You could rewrite a few vaidation tools to accept the new practice -- as
> well as continue to accept what you already do. Or if you happen to
> allow ( inside { then wouldn't the new code just work? Surely you don't
> *require* every { to have a -- ending } addition, do you? If it's
> commented out have you lost anything?

I believe that adding parens inside the braces adds nothing. It does
break existing code, and to my eye the above could easily be misread
as meaning foo takes no parameters from the stack.

> It does make sense to stay with common practice as a general rule,

Agreed.

> and I don't see that this change would be an improvement.

Agreed.

> But would it really break existing code?

Yes.

-Doug

Bernd Paysan

unread,
Aug 12, 2008, 12:29:32 PM8/12/08
to
Stephen Pelc wrote:

> Well, it's that time of year again, so I'm in proposal mode.
> Don't forget to attend EuroForth 2008 and the Forth200x standards
> meeting in gorgeous glorious Vienna from 25-28 September 2008.
> http://www.euroforth.org
>
> I have separated the enhanced local variable syntax from the
> local buffer proposal. The main extension in this proposal
> is the separation of initialised local arguments from
> uninitialised local values.

Thanks. My comment:

bigFORTH provides scoped local declarations. Unlike Gforth's scoping,
bigFORTH's is explicit (bigFORTH's syntax is older). The syntax for scoped
locals is

{ local .. local | code using the locals }

so that would conflict with the proposal. There is some actual use of the
scoped locals, though not very often (if you factor correctly, you only
have one point where locals need to be defined ;-). If you declare locals
once with { locala localb }, then the scope closes at the end of the
definition.

Like in Gforth, when I use scoped locals, then to escape the "problem" of
needing uninitialized locals. Just define the locals after the value is
computed. Multiple local definitions are possible in bigFORTH and Gforth.
I've never encountered the need to use an uninitialized local, apart from
local buffers (which are by default uninitialized, anyway).

I'm using typed locals, too, for float with the prefix f: and for structures
(records) with the prefix r: <structure> (together with bigFORTH's
structure package, but since that just does >BODY @ to obtain the size,
it's compatible with many other structure packages). r: <struct> is thus
equivalent to [ sizeof <struct> ] in the proposal.

Gforth has more types, and allows W: for normal cell locals (D: for double,
F: for float, C: for char). It also has pointer locals, declared with W^,
D^, F^, C^, but (yet) no buffer locals.

I could also imagine adding an o: <class> local for object pointers
(initialized).

Bottom line: In general, the proposal is good. I don't see much need for
uninitialized locals, don't do that, also avoid "to <local>".

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/

Elizabeth D Rather

unread,
Aug 12, 2008, 1:06:19 PM8/12/08
to

Excuse me, but the practice you're describing has been non-standard for
15 or 24 years (depending which statement you're referring to). No
reason why it can't continue to be if you prefer it. No code "broken"
that isn't already non-standard.

Stephen Pelc

unread,
Aug 12, 2008, 2:01:44 PM8/12/08
to
On Tue, 12 Aug 2008 07:06:19 -1000, Elizabeth D Rather
<era...@forth.com> wrote:

>Excuse me, but the practice you're describing has been non-standard for
>15 or 24 years (depending which statement you're referring to). No
>reason why it can't continue to be if you prefer it. No code "broken"
>that isn't already non-standard.

The guts of this proposal is a notation to add uninitialised
local values to Forth. There is common practice in the brace
notation, as indicated by implementation in:
gforth
Win32Forth
Neon
Yerk
PowerMops
VFX Forth and cross compilers
...

As I've heard you say many times, one function of a standard
is to codify common practice. This proposal codifies it. That's
all. The current ANS standard has no locals syntax with
uninitialised values. Common practice and postings here indicate
to me that this facility is required.

Gforth, iForth and MPE Forths include locals implementations with
more facilities than are in this proposal, which is thus a lowest
common denominator proposal. In the Forths that provide both the
brace notation and the LOCALS| ...| notation, the brace notation
is far more widely used, in one case by a factor of 20:1 or more.

Anton Ertl

unread,
Aug 12, 2008, 3:52:35 PM8/12/08
to
steph...@mpeforth.com (Stephen Pelc) writes:
>'Ś' (ASCII 0xA6)

That's not an ASCII character.

>The use of local types is contentious as they only become useful
>if TO is available for these.

That's nonsense. I hardly ever use TO with locals, but I do use F:
and D: now and then (and usually without using TO on those locals).
But it's ok if you don't want to deal with additional types in this
proposal; unlike some other people, I find proposals that propose
something useful acceptable even if they don't solve everything.

>Standardisation of operators with (for example) floats needs to
>be done before the local types extension can be incorporated into
>Forth200x.

No.

> More preparatory standardisation
>needs to be done before local types can be standardised.

No.

>Forth 200x text
>===============
>13.6.2.xxxx {
>brace LOCAL EXT
>
>Interpretation: Interpretation semantics for this word are undefined.
>
>Compilation:
>( "<spaces>arg1" ... "<spaces>argn" | "<spaces>lv1" ... "<spaces>lvn"
>-- )
>
>Create up to eight local arguments by repeatedly skipping leading
>spaces, parsing arg, and executing implementation defined actions.

Delete "up to eight". The limit is defined in Forth-94 13.3.3.2 f),
no need to repeat it here. (It's a bad excuse that this text is
modeled after the LOCALS| text; obviously LOCALS| is bad not just in
what it standardized, but also in how it was standardized.)

>The list of local arguments to be defined is terminated by "|",
>"--" or "}". Append the run-time semantics for local arguments
>given below to the current definition. If a space delimited '|' is
>encountered, create up to eight local values by repeatedly skipping

Delete "up to eight". Also, the total number should probably be 8 if
we consider 13.3.3.2 f).

>leading spaces, parsing the "lv" token,

I don't like the '"lv" token' language. Better make the stack comment

( "<spaces>name1" ... "<spaces>namem" | "<spaces>namem+1" ... "<spaces>namen" -- )

and always write 'parsing name'.

> and creating the local
>element. The list of local values to be defined is terminated by
>"--" or "}". Append the run-time semantics for local values
>given below to the current definition. If "--" has
>been encountered, further text between "--" and } is ignored.
>
>Local argument run-time: ( x1 ... xn -- )
>Local value run-time: ( -- )

There is just one run-time semantics for { with one stack comment:

( x1 ... xm -- )

The m here corresponds to the m in "namem" in my stack comment for
compilation.

>Initialize up to eight local arguments from the data stack

Delete "up to eight".

>Local argument arg1 is initialized with x1, arg2 with x2 up
>to argn from xn, which is on the top of the data stack. When
>invoked, each local argument will return its value. The value
>of a local argument may be changed using 13.6.1.2295 TO.
>
>Initialize up to eight local values. The initial contents of local
>values are undefined.

So they are uninitialized. I think these two sentences could be
deleted, or they should be reworded. Certainly delete "up to eight".

> When invoked, each local value
>returns its value. The value of a local value may be changed
>using 13.6.1.2295 TO. The size of a local value is a cell.
>The user may make no assumption about the order and contiguity of
>local values in memory.

The last sentence makes no sense. The user gets no address of local
values from the system, so there is no way they could make use of such
assumptions. Delete that sentence.

>
>Ambiguous conditions:
>a) The { ... } text extends over more than one line.
>b) { ... } is declared more than once in a word.

Replace "declared" with "used". Are there any systems that have this
restriction? Otherwise, I would suggest lifting it. Even if we want
to keep it, I would certainly not put it in this part; it's already in
13.3.3.2 (which may have to be suitably adapted).

>c) Parsing units '|', ']', '--' and '}' are not whitespace delimited.

What's the point of ']' here? A remnant of the old version?

If |, --, or } are not whitespace-delimited, they are not --, |, and
}, but funny local names. I don't think that one needs to specify
that explicitly.

OTOH, there is one thing you missed that should be specified explicitly:

c) Local names ending in ":" or "[" are an ambiguous condition.

>Reference implementation
>=========================
>(currently untested)

There is no need to put an untested implementation here that is based
on a horrible word that does not exist anywhere. We can have a tested
implementation based on the standard word (LOCAL). What is missing
and is more important than a reference implementation is tests. If
you put tests here, I'll update
<http://www.complang.tuwien.ac.at/forth/anslocal.fs> to support the
"|" part.

Anton Ertl

unread,
Aug 12, 2008, 4:41:46 PM8/12/08
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>If you really want rest of the stack comment in the braces, put it
>there:
>
>: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }
...

>or here:
>
>: front-string { c-addr1 u1 c-addr2 u2 } ( -- c-addr3 u3 )
...

These are two wrong stack-effect comments that are situated in funny
places. They are wrong because they claim that FRONT-STRING takes no
items from the stack, whereas in reality it takes four. I guess
Stephen would fire you on the spot for writing lying stack-effect
comments.

>At least then it's immediately clear which part is the comment and
>which the initialization of locals.

That's also clear with the { ... -- ... } notation once you are
literate in that notation.

[About


: front-string ( c-addr1 u1 c-addr2 u2 -- c-addr3 u3 )

{ c-addr1 u1 c-addr2 u2 }
]


>> This is harder to read and write, and thus would discourage factoring.
>> Also, it adds redundancy, and that tends to lead to errors that are
>> relatively hard to find.
>
>There is no added redundancy,

The stack elements occur twice.

> it's *easier* to read

It's longer, and one has to check whether the items in the stack
effect correspond to the local names. That all makes it harder to read.

> and it's not
>significantly harder to write.

It is harder, and every hardship is significant.

>> >I thought that { a b -- c d } meant that the contents of the
>> >variables after the "--" would be automatically returned as the
>> >result
>
>> That would throw away some of the advantages of having a stack, and
>> would require using locals where they are not needed. It would also
>> make the code longer.
>
>It would. It's a despicable, dreadful idea.

Ah, so it's just a straw man argument.

> But it's what the
>comment suggests.

Maybe it does to you. It does not to the significant number of people
who implemented this syntax, and not to the even larger number of
people who have used it. Should we keep away from standardizing
common practice just because one person has a misconception? If so,
we will never get anything standardized.

Jonah Thomas

unread,
Aug 12, 2008, 9:30:08 PM8/12/08
to
steph...@mpeforth.com (Stephen Pelc) wrote:
> Jonah Thomas <jeth...@gmail.com> wrote:
> >steph...@mpeforth.com (Stephen Pelc) wrote:
> >> Andrew Haley <andr...@littlepinkcloud.invalid> wrote:
> >>
> >> >If you really want rest of the stack comment in the braces, put it
> >> >there:
> >> >
> >> >: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }
> >>
> >> Now we've got to change common practice, and rewrite any validation
> >> tools we may be using. In other words, this notation is a code
> >> breaker. One of the successful parts of the ANS process was the
> >> stringent effort to avoid breaking existing code.
> >
> >I don't particularly advocate that change, but would it break much
> >code? You could rewrite a few vaidation tools to accept the new
> >practice -- as well as continue to accept what you already do. Or if
> >you happen to allow ( inside { then wouldn't the new code just work?
>
> The majority of existing systems will generate and extra local called
> '('. This will not be used. So I would expect most systems to survive.
> However, we have tools with clients that process stack comments with
> braces. These will have to be upgraded if they the client upgrades the
> compiler.

I still don't see that the " ( -- " notation is better, and I still
don't see why it should be a big deal to allow it.

When -- comments out to the end of the line, what harm would it do to
have ( be a comment too? In the case that -- starts a comment, it ought
to be very easy to have ( duplicate that.

And when -- starts a special tool to process stack comments, would it be
hard to have ( and ) in this special context be no-ops? You'd want to
extend your tools a very little bit in case some of your customers
started to use the new standard practice, but their old code needn't
break at all. It looks to me like the worst that would happen is that
some of your existing tools would not work with brand-new standard code.
Just like every Forth system in the world broke with POSTPONE and
ENVIRONMENT? and CS-PICK etc.

> We have to reserve '(', and presumably also '\'.

How likely is it that there's existing code which uses ( as a local
name?

> Think of the
> firestorm about the '[' reservation. Win32Forth accepts '\' as well
> as '|' as the arguments/values separator. IMHO, staying with common
> practice avoids the law of unintended consequences.
>
> >It does make sense to stay with common practice as a general rule,
> >and I don't see that this change would be an improvement. But would
> >it really break existing code?
>
> Yes.

I tend to think you're on the right side of this argument. It just looks
like you're arguing too hard, overstating your claims. Maybe I've
misunderstood.

Andrew Haley

unread,
Aug 13, 2008, 5:35:19 AM8/13/08
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Tue, 12 Aug 2008 05:50:11 -0500, Andrew Haley
> <andr...@littlepinkcloud.invalid> wrote:

> >If you really want rest of the stack comment in the braces, put it
> >there:
> >
> >: front-string { c-addr1 u1 c-addr2 u2 ( -- c-addr3 u3 ) }

> Now we've got to change common practice, and rewrite any validation
> tools we may be using. In other words, this notation is a code
> breaker. One of the successful parts of the ANS process was the
> stringent effort to avoid breaking existing code.

On the one hand we've got a request for discussion and on the other
"we must not change established practice." What, then, is the point
of the request for discussion? Going through the motions for
appearance's sake?

> >: front-string { c-addr1 u1 c-addr2 u2 } ( -- c-addr3 u3 )

> Now you have broken code readability for those people (and they
> exist) who use double comments on name lines to indicate either
> compile and runtime actions of defining words, or to indicate data
> stack and return stack actions.

I don't understand this comment. How does this "break code
readability?

I take your point about existing practice, but there is a flaw in your
reasoning. It seems that if someone invents something for Forth and
manages to get several implementations to use it, then it must be
adopted by the standard -- no matter how awful -- because we must not
break existing code. Is that really the case, or am I perhaps
misunderstanding you?

Andrew.

Stephen Pelc

unread,
Aug 13, 2008, 9:16:00 AM8/13/08
to
On Tue, 12 Aug 2008 19:52:35 GMT, an...@mips.complang.tuwien.ac.at
(Anton Ertl) wrote:

>There is no need to put an untested implementation here that is based
>on a horrible word that does not exist anywhere. We can have a tested
>implementation based on the standard word (LOCAL).

See Forth200x, rev 2, 13.3.3.1 b) 2) which conflicts with
uninitialised locals. We certainly could produce a lower level
factor. Perhaps you would like to provide one.

Brad Eckert

unread,
Aug 13, 2008, 10:36:10 AM8/13/08
to
On Aug 12, 10:06 am, Elizabeth D Rather <erat...@forth.com> wrote:
>
> Excuse me, but the practice you're describing has been non-standard for
> 15 or 24 years (depending which statement you're referring to).  No
> reason why it can't continue to be if you prefer it.  No code "broken"
> that isn't already non-standard.
>
Two factions have emerged. Those that use braces for comments and
those that use braces for locals.

What about extending the LOCAL| syntax? I think an automated tool
could convert the extended { a b c } syntax to the LOCAL| c b a |
syntax.

-Brad

Anton Ertl

unread,
Aug 13, 2008, 10:38:48 AM8/13/08
to
steph...@mpeforth.com (Stephen Pelc) writes:
>We have to reserve '(', and presumably also '\'.

That's a good idea, because at least some systems (at least Gforth)
already allow comments in locals definitions, and want to keep this
feature.

>Win32Forth accepts '\' as well
>as '|' as the arguments/values separator.

That's another reason to reserve '\'.

>>It does make sense to stay with common practice as a general rule, and I
>>don't see that this change would be an improvement. But would it really
>>break existing code?
>
>Yes.

You have programs that use '(' or '\' as a locals name? Even if you
do, reserving these names does not break these programs.

Anton Ertl

unread,
Aug 13, 2008, 10:48:49 AM8/13/08
to
steph...@mpeforth.com (Stephen Pelc) writes:
>On Tue, 12 Aug 2008 19:52:35 GMT, an...@mips.complang.tuwien.ac.at
>(Anton Ertl) wrote:
>
>>There is no need to put an untested implementation here that is based
>>on a horrible word that does not exist anywhere. We can have a tested
>>implementation based on the standard word (LOCAL).
>
>See Forth200x, rev 2,

There is no rev 2. Do you mean Draft 07.2r?

> 13.3.3.1 b) 2) which conflicts with
>uninitialised locals.

Not at all. Any implementation that initializes with any value is an
implementation of an uninitialized local. It's certainly better than
an untested implementation based on a word that is (fortunately) not
implemented anywhere.

Celime

unread,
Aug 13, 2008, 11:10:27 AM8/13/08
to

"Stephen Pelc" <steph...@mpeforth.com> a écrit dans le message de
news: 48a035e9....@192.168.0.50...
....
> Problem
> =======
> 1) The current LOCALS| ... | notation explicitly forces all locals
> to be initialised from the data stack.
> 2) 1) The current LOCALS| ... | notation defines locals in reverse
> order to the normal stack notation.
>
> This proposal is derived from implementations that have existed for
> more than 15 years.
>
>
> Solution
> ========
> Base version
> ------------

> The following syntax for local arguments and local values is
> proposed. The sequence:
> { ni1 ni2 ... | lv1 lv2 ... -- o1 o2 ... }

IMHO this diagram is far away from the Forth usage.
Also, the pipe '|' have another sense in normal stack comments.

I would prefer rather this kind of notation, more flexible and
immediately comprehensible:

: foo ( a b -- )
local b \ the second value
local a \ the first value
0 local t \ temp value
...... ;

I can write comment next the declarations.

-Charles

...


Anton Ertl

unread,
Aug 13, 2008, 11:13:03 AM8/13/08
to
steph...@mpeforth.com (Stephen Pelc) writes:
>On Tue, 12 Aug 2008 19:52:35 GMT, an...@mips.complang.tuwien.ac.at
>(Anton Ertl) wrote:
>
>>There is no need to put an untested implementation here that is based
>>on a horrible word that does not exist anywhere. We can have a tested
>>implementation based on the standard word (LOCAL).
>
>See Forth200x, rev 2,

There is no rev 2. Do you mean Draft 07.2r?

> 13.3.3.1 b) 2) which conflicts with
>uninitialised locals.

You produce the tests, and I'll do my implementation using (LOCAL).
Please do your worst in your tests to show that my implementation
conflicts with uninitialized locals (and also in other respects).

Peter Fälth

unread,
Aug 13, 2008, 1:17:43 PM8/13/08
to
On Aug 13, 5:10 pm, "Celime" <cm175...@scarlet.be> wrote:
> "Stephen Pelc" <stephen...@mpeforth.com> a écrit dans le message denews: 48a035e9.488425__BEGIN_MASK_n#9g02mG7!__...__END_MASK_i?a63jfAD$z...@192.168.0.50...
This is exactly what I have implemented in my Forth. It does not need
to be more complicated!

Peter

Marcel Hendrix

unread,
Aug 14, 2008, 3:08:11 PM8/14/08
to
"Celime" <cm17...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]

> I would prefer rather this kind of notation, more flexible and
> immediately comprehensible:

> : foo ( a b -- )
> local b \ the second value
> local a \ the first value
> 0 local t \ temp value
> ...... ;

> I can write comment next the declarations.

This way has been supported in iForth (with local, flocal, dlocal,
zlocal/ddlocal), for the past 15 years.

-marcel

Ed

unread,
Aug 14, 2008, 11:17:53 PM8/14/08
to

"Marcel Hendrix" <m...@iae.nl> wrote in message news:1215340...@frunobulax.edu...

Is there extra overhead involved declaring locals this way
i.e. individually as opposed to mass declaration { a b t } ?

On the surface this syntax does look cleaner and more forth-like
but wonder if there are any drawbacks to it.

A simple syntax can sometimes hide extraordinary complexity.
One would need to compare implementation and run-time costs
of the two schemes before a reasonable assessment could be
made.

Elizabeth D Rather

unread,
Aug 15, 2008, 12:05:40 AM8/15/08
to

Maybe microscopic overhead, but I can't imagine you'd declare a bunch of
locals in a definition that didn't have a lot of work to do, so the
difference disappears in the noise. Some spatial overhead on most
systems, particularly if the 0 is a compiled literal. An optimizing
compiler should clean most of it up.

I think it looks nice, too, but it does reflect the same stack order as
locals| ... | which is what the proponents of braces dislike.

Marcel Hendrix

unread,
Aug 15, 2008, 1:03:04 AM8/15/08
to
"Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)

[..]
> "Marcel Hendrix" <m...@iae.nl> wrote in message news:1215340...@frunobulax.edu...
>> "Celime" <cm17...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]
>> > : foo ( a b -- )
>> > local b \ the second value
>> > local a \ the first value
>> > 0 local t \ temp value
>> > ...... ;

>> > I can write comment next the declarations.

>> This way has been supported in iForth (with local, flocal, dlocal,
>> zlocal/ddlocal), for the past 15 years.

> Is there extra overhead involved declaring locals this way
> i.e. individually as opposed to mass declaration { a b t } ?

LOCAL adds a tiny bit of sugar to (LOCAL), the standard word.

> On the surface this syntax does look cleaner and more forth-like
> but wonder if there are any drawbacks to it.

No, it is a straightforward extension that makes (LOCAL) easier
to use. Actually, its meta definition is:

T: LOCAL PARSE-NAME (LOCAL) T;OIA \ <> LOCAL #<name># --> <>

> A simple syntax can sometimes hide extraordinary complexity.
> One would need to compare implementation and run-time costs
> of the two schemes before a reasonable assessment could be made.

I don't see so how you would validly compare runtime costs accross
implementations. What does it mean when it runs slowly on the one
and very fast on the others?

-marcel

Anton Ertl

unread,
Aug 15, 2008, 8:23:49 AM8/15/08
to
"Ed" <nos...@invalid.com> writes:
>
>"Marcel Hendrix" <m...@iae.nl> wrote in message news:1215340...@frunobulax.edu...
>> "Celime" <cm17...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4
>(long)
>> [..]
>> > I would prefer rather this kind of notation, more flexible and
>> > immediately comprehensible:
>>
>> > : foo ( a b -- )
>> > local b \ the second value
>> > local a \ the first value
>> > 0 local t \ temp value
>> > ...... ;
...

>Is there extra overhead involved declaring locals this way
>i.e. individually as opposed to mass declaration { a b t } ?

In 32-bit Gforth, there is:

: foo 0 { a b t } ; ok
: bar { b } { a } 0 { t } ; ok
simple-see foo
$B7A7A4C8 lit
$B7A7A4CC <0>
$B7A7A4D0 >l
$B7A7A4D4 >l
$B7A7A4D8 >l
$B7A7A4DC lp-
$B7A7A4E0 lp+2
$B7A7A4E4 ;s ok
simple-see bar
$B7A7A500 >l
$B7A7A504 lp-
$B7A7A508 >l
$B7A7A50C lp-
$B7A7A510 lit
$B7A7A514 <0>
$B7A7A518 >l
$B7A7A51C lp-
$B7A7A520 lp+!#
$B7A7A524 <24>
$B7A7A528 ;s ok

I.e., it keeps the locals pointer maximally aligned after each locals
definition; so with the individual definitions, you get three cells of
padding (and the code to create that padding) and the three locals
consume 24 bytes on the locals stack, whereas with the mass
definition, you get only one cell of padding, and the locals need only
16 bytes on the locals stack.

That's certainly something that could be fixed by adding complexity to
the compiler.

>On the surface this syntax does look cleaner and more forth-like
>but wonder if there are any drawbacks to it.

IMO the main drawback is that you have to define the locals in the
reverse order.

Ed

unread,
Aug 15, 2008, 10:38:55 AM8/15/08
to

"Marcel Hendrix" <m...@iae.nl> wrote in message news:1920160...@frunobulax.edu...

> "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
> [..]
> > "Marcel Hendrix" <m...@iae.nl> wrote in message news:1215340...@frunobulax.edu...
> >> "Celime" <cm17...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4
(long)
> [..]
> >> > : foo ( a b -- )
> >> > local b \ the second value
> >> > local a \ the first value
> >> > 0 local t \ temp value
> >> > ...... ;
>
> >> > I can write comment next the declarations.
>
> >> This way has been supported in iForth (with local, flocal, dlocal,
> >> zlocal/ddlocal), for the past 15 years.
>
> > Is there extra overhead involved declaring locals this way
> > i.e. individually as opposed to mass declaration { a b t } ?
>
> LOCAL adds a tiny bit of sugar to (LOCAL), the standard word.
>
> > On the surface this syntax does look cleaner and more forth-like
> > but wonder if there are any drawbacks to it.
>
> No, it is a straightforward extension that makes (LOCAL) easier
> to use. Actually, its meta definition is:
>
> T: LOCAL PARSE-NAME (LOCAL) T;OIA \ <> LOCAL #<name># --> <>

I didn't notice the reverse order, which others have since pointed out.
That might take away some of the shine.

Presumably then all locals are declared together at the start of the
definition and something else signals the end of locals (?)

> > A simple syntax can sometimes hide extraordinary complexity.
> > One would need to compare implementation and run-time costs
> > of the two schemes before a reasonable assessment could be made.
>
> I don't see so how you would validly compare runtime costs accross
> implementations. What does it mean when it runs slowly on the one
> and very fast on the others?

You're saying that you can't measure the relative merit of two
different schemes implemented on the same machine?

No need to go into details. I think I get the picture of what this
syntax would entail. Can't say I've encountered it before.
The syntax would make it easy to add new local types
(including presumably local buffers).

Peter Fälth

unread,
Aug 15, 2008, 11:15:13 AM8/15/08
to
On Aug 15, 7:03 am, m...@iae.nl (Marcel Hendrix) wrote:
> "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
> [..]
>
> > "Marcel Hendrix" <m...@iae.nl> wrote in messagenews:1215340...@frunobulax.edu...
> >> "Celime" <cm175...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4 (long)

> [..]
> >> > : foo   ( a b -- )
> >> >      local b \ the second value
> >> >      local a \ the first value
> >> >    0 local t \ temp value
> >> >    ......  ;
> >> > I can write comment next the declarations.
> >> This way has been supported in iForth (with local, flocal, dlocal,
> >> zlocal/ddlocal), for the past 15 years.
> > Is there extra overhead involved declaring locals this way
> > i.e. individually as opposed to mass declaration  { a b t }  ?
>
> LOCAL adds a tiny bit of sugar to (LOCAL), the standard word.
>
> > On the surface this syntax does look cleaner and more forth-like
> > but wonder if there are any drawbacks to it.
>
> No, it is a straightforward extension that makes (LOCAL) easier
> to use. Actually, its meta definition is:
>
> T: LOCAL        PARSE-NAME (LOCAL) T;OIA \ <> LOCAL #<name># --> <>
>
> > A simple syntax can sometimes hide extraordinary complexity.
> > One would need to compare implementation and run-time costs
> > of the two schemes before a reasonable assessment could be made.
>
> I don't see so how you would validly compare runtime costs accross
> implementations. What does it mean when it runs slowly on the one
> and very fast on the others?
>
> -marcel

I have the same definition

:p local parse-word (local) ;p

In my and also other systems this is possible as the 0 0 (local) to
end locals definitions is not needed. This requirement is also in the
proposed BUILDLV word. If the requirement was dropped the word could
be useful to construct different local syntax's.

Peter

Peter Fälth

unread,
Aug 15, 2008, 11:19:02 AM8/15/08
to
On Aug 15, 4:38 pm, "Ed" <nos...@invalid.com> wrote:
> "Marcel Hendrix" <m...@iae.nl> wrote in messagenews:1920160...@frunobulax.edu...

> > "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
> > [..]
> > > "Marcel Hendrix" <m...@iae.nl> wrote in messagenews:1215340...@frunobulax.edu...
> > >> "Celime" <cm175...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4

> (long)
> > [..]
> > >> > : foo   ( a b -- )
> > >> >      local b \ the second value
> > >> >      local a \ the first value
> > >> >    0 local t \ temp value
> > >> >    ......  ;
>
> > >> > I can write comment next the declarations.
>
> > >> This way has been supported in iForth (with local, flocal, dlocal,
> > >> zlocal/ddlocal), for the past 15 years.
>
> > > Is there extra overhead involved declaring locals this way
> > > i.e. individually as opposed to mass declaration  { a b t }  ?
>
> > LOCAL adds a tiny bit of sugar to (LOCAL), the standard word.
>
> > > On the surface this syntax does look cleaner and more forth-like
> > > but wonder if there are any drawbacks to it.
>
> > No, it is a straightforward extension that makes (LOCAL) easier
> > to use. Actually, its meta definition is:
>
> > T: LOCAL PARSE-NAME (LOCAL) T;OIA \ <> LOCAL #<name># --> <>
>
> I didn't notice the reverse order, which others have since pointed out.
> That might take away some of the shine.
>
I think the order is correct. The top of stack is on top :-)

: foo ( a b -- )

local b \ Top of stack
local a \ 2nd stack item


0 local t \ temp value
...... ;

Peter

Doug Hoffman

unread,
Aug 15, 2008, 12:38:53 PM8/15/08
to
Peter Fälth wrote:

> I think the order is correct. The top of stack is on top :-)
>
> : foo ( a b -- )
> local b \ Top of stack
> local a \ 2nd stack item
> 0 local t \ temp value
> ...... ;

I was first exposed to RPN on the Hewlett-Packard calculators. So I am
also predisposed to thinking that the stack grows "up". To me this
visualization helps when doing math. For example:

b
a
+ _


b
a
- _


b
a
x _


b
a
/ _


While the physical order doesn't matter for addition or multiplication,
it helps me for subtraction and division. Also, when we use DROP this
visual model works better (how do we DROP a plate from a spring-loaded
stack of plates?)

But then the commonly used stack diagram grows not down nor up, it grows
sideways. Oh well.


Btw, regardless of the above, I still prefer the { a b | t -- } syntax
with local variables (in this case, just t) initialized to zero as
default. But I'm not strong on initializing to zero and could live with
"undefined". or 0 { a b t -- }

-Doug

Doug Hoffman

unread,
Aug 15, 2008, 12:41:55 PM8/15/08
to
Doug Hoffman wrote:
> Peter Fälth wrote:
>
>> I think the order is correct. The top of stack is on top :-)
>>
>> : foo ( a b -- )
>> local b \ Top of stack
>> local a \ 2nd stack item
>> 0 local t \ temp value
>> ...... ;
>
> I was first exposed to RPN on the Hewlett-Packard calculators. So I am
> also predisposed to thinking that the stack grows "up". To me this
> visualization helps when doing math. For example:

Oops. I wasn't watching the "sideways" stack diagram for foo.
Well, you know what I meant...

Marcel Hendrix

unread,
Aug 15, 2008, 1:52:33 PM8/15/08
to
"Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)

>"Marcel Hendrix" <m...@iae.nl> wrote in message news:1920160...@frunobulax.edu...
>> "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]
>> > "Marcel Hendrix" <m...@iae.nl> wrote in message news:1215340...@frunobulax.edu...
>> >> "Celime" <cm17...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]

>> No, it is a straightforward extension that makes (LOCAL) easier
>> to use. Actually, its meta definition is:

>> T: LOCAL PARSE-NAME (LOCAL) T;OIA \ <> LOCAL #<name># --> <>

> I didn't notice the reverse order, which others have since pointed out.
> That might take away some of the shine.

The { } syntax is a mere 18 line lump of pure ANS sugar:
http://www.complang.tuwien.ac.at/forth/anslocal.fs

> Presumably then all locals are declared together at the start of the
> definition and something else signals the end of locals (?)

No, LOCALs can be defined everywhere in the word, outside of control
structures. No end signalling is needed.

>> > A simple syntax can sometimes hide extraordinary complexity.
>> > One would need to compare implementation and run-time costs
>> > of the two schemes before a reasonable assessment could be made.

>> I don't see so how you would validly compare runtime costs across


>> implementations. What does it mean when it runs slowly on the one
>> and very fast on the others?

> You're saying that you can't measure the relative merit of two
> different schemes implemented on the same machine?

No, I said across implementations, meaning different Forths. If I'd
implement this in iForth, there would be no difference (of course).

> No need to go into details. I think I get the picture of what this
> syntax would entail. Can't say I've encountered it before.
> The syntax would make it easy to add new local types
> (including presumably local buffers).

No, a local buffer can potentially be many Mbytes, so I'd implement
it using ALLOCATE . This means needing a new primitive to call FREE
for locals containing a pointer to allocated memory. This will
make removing locals at EXIT a little bit more expensive for *every*
word containing locals (unless I complicate the compiler further
by keeping track of this possibility).

iForth has a local strings package (using circular buffers) that makes
the need for local buffers as likely as finding a braincell in the
Catshuis.

-marcel

Ed

unread,
Aug 16, 2008, 12:48:38 AM8/16/08
to

"Marcel Hendrix" <m...@iae.nl> wrote in message news:9003360...@frunobulax.edu...

> "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
>
> >"Marcel Hendrix" <m...@iae.nl> wrote in message news:1920160...@frunobulax.edu...
> >> "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
> [..]
> >> > A simple syntax can sometimes hide extraordinary complexity.
> >> > One would need to compare implementation and run-time costs
> >> > of the two schemes before a reasonable assessment could be made.
>
> >> I don't see so how you would validly compare runtime costs across
> >> implementations. What does it mean when it runs slowly on the one
> >> and very fast on the others?
>
> > You're saying that you can't measure the relative merit of two
> > different schemes implemented on the same machine?
>
> No, I said across implementations, meaning different Forths. If I'd
> implement this in iForth, there would be no difference (of course).

It was clear what was being asking.

Bruce McFarling

unread,
Aug 17, 2008, 6:07:13 PM8/17/08
to
On Aug 15, 11:19 am, Peter Fälth <peter.fa...@tin.it> wrote:
> : foo ( a b -- )
> local b \ Top of stack
> local a \ 2nd stack item
> 0 local t \ temp value
> ...... ;

The difference to "LOCAL| b a |" is that this is *vertical*, so there
is no *visual* contradiction to the normal stack comment.

How does this approach create local variables as opposed to local
values? I took it that was the point of this RfD.

Celime

unread,
Aug 18, 2008, 3:52:21 AM8/18/08
to

"Peter Fälth" <peter...@tin.it> a écrit dans le message de news:
d726871b-9350-487b...@y38g2000hsy.googlegroups.com...

I don't think it is possible to define my LOCAL example with (LOCAL):

: foo ( a b -- )
local b

local a
0 local t
a .
b .
t . ;

2 3 foo \ 2 0 3

Marcel Hendrix

unread,
Aug 18, 2008, 1:13:58 PM8/18/08
to
"Celime" <cm17...@scarlet.be> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]

> I don't think it is possible to define my LOCAL example with (LOCAL):

> : foo ( a b -- )
> local b
> local a
> 0 local t
> a .
> b .
> t . ;

> 2 3 foo \ 2 0 3

Nothing in the ANS specification for (LOCAL) requires ( c-addr 0 -- )
to be used. Most vendors use solutions that make this a noop.

I can compile your example just fine, but the runtime output is indeed
different from yours.

FORTH> : foo ( a b -- )
<3>[FORTH>] local b
<3>[FORTH>] local a
<3>[FORTH>] 0 local t
<3>[FORTH>] a .
<3>[FORTH>] b .
<3>[FORTH>] t . ; ok
FORTH> 2 3 foo 2 3 0 ok
FORTH>

Is the output you show really intended?

-marcel

Celime

unread,
Aug 18, 2008, 1:32:16 PM8/18/08
to

"Marcel Hendrix" <m...@iae.nl> a écrit dans le message de news:
9710363...@frunobulax.edu...

Yes, it is the result I expected - nice that you have that
in your system. I will try to modify the (LOCAL) definition
in my Forthcad program ;-).

>
> -marcel
>


Ed

unread,
Aug 19, 2008, 12:09:57 AM8/19/08
to

"Celime" <cm17...@scarlet.be> wrote in message
news:48a9b195$0$2195$5f6a...@news.scarlet.nl...

Beyond the ability to intersperse comments between local
definitions, there doesn't seem much advantage in LOCAL
over LOCALS| .

With LOCAL one *might* be able to put executable code
between local declarations. But that's a dubious feature
anyway.

The more I think about locals syntax, the more I keep coming
back to LOCALS| . Byte for byte LOCALS| is probably the
most efficient syntax for implementing forth locals. While some
may detest the stack ordering etc etc, others will be buoyed by
the fact there is no shorter way.

As for (LOCAL) it is not particularly good. It's easier to write
LOCALS| without it. In retrospect, (LOCAL) and LOCALS|
should have been transposed in the Standard.

Doug Hoffman

unread,
Aug 19, 2008, 1:46:07 AM8/19/08
to
Ed wrote:

> Byte for byte LOCALS| is probably the
> most efficient syntax for implementing forth locals.

Byte for byte. My very dated PC has 750 meg of RAM and I forget how
many gigs of hard drive space. I really don't care about conserving a
few bytes here and there if I get something of value in return.


> While some may detest the stack ordering

Yes.

> etc etc, others will be buoyed by
> the fact there is no shorter way.

That would have to be those who *are* concerned about a few bytes. Who
are they? Logically not those using Forth on a PC. Must be those doing
embedded stuff. Once again I wonder, is there a division of interest in
Forth between the two application areas? Does that division lead to a
conflict in how people want to see Forth evolve?

Now one could always say that "smaller is better no matter what". That
may have been true a decade or two ago. But this is 2008. Things have
changed. I would gladly give up a few bytes for a tool that lets me get
the job done faster and with fewer errors along the way.

-Doug

George Hubert

unread,
Aug 19, 2008, 3:51:00 AM8/19/08
to
On Aug 19, 6:46 am, Doug Hoffman <dhoff...@talkamerica.net> wrote:
> Ed wrote:
> > Byte for byte  LOCALS|  is probably the
> > most efficient syntax for implementing forth locals.
>
> Byte for byte.  My very dated PC has 750 meg of RAM and I forget how
> many gigs of hard drive space.  I really don't care about conserving a
> few bytes here and there if I get something of value in return.
>
> > While some may detest the stack ordering
>
> Yes.
>
> > etc etc, others will be buoyed by
> > the fact there is no shorter way.
>
> That would have to be those who *are* concerned about a few bytes.  Who
> are they?  Logically not those using Forth on a PC.  Must be those doing
> embedded stuff.  Once again I wonder, is there a division of interest in
> Forth between the two application areas?  Does that division lead to a
> conflict in how people want to see Forth evolve?
>

Surely an embedded system would be programmed with a cross compiler,
so the locals stuff will be on the host anyway (we're not talking
about the size of the generated code, since a decent optimiser
would produce the same code anyway). Also most people find locals
most useful for interfacing to the host OS so on an embedded system
w/o an OS are they useful anyway.

> Now one could always say that "smaller is better no matter what".  That
> may have been true a decade or two ago.  But this is 2008.  Things have
> changed.  I would gladly give up a few bytes for a tool that lets me get
> the job done faster and with fewer errors along the way.
>

I agree.

George Hubert

Anton Ertl

unread,
Aug 19, 2008, 3:58:28 AM8/19/08
to
Doug Hoffman <dhof...@talkamerica.net> writes:
>Ed wrote:
>
>> Byte for byte LOCALS| is probably the
>> most efficient syntax for implementing forth locals.
>
>Byte for byte. My very dated PC has 750 meg of RAM and I forget how
>many gigs of hard drive space. I really don't care about conserving a
>few bytes here and there if I get something of value in return.
>
>
>> While some may detest the stack ordering
>
>Yes.

Yes!

>> etc etc, others will be buoyed by
>> the fact there is no shorter way.
>
>That would have to be those who *are* concerned about a few bytes.

Not really. Those who are concerned about a few bytes, and who like
the shortest way prefer not to use locals at all.

This is also reflected in usage. Almost nobody uses LOCALS| (and the
main example I know of probably does not do it to save a few bytes).
Either people use { or they don't use locals at all.

Doug Hoffman

unread,
Aug 19, 2008, 10:42:44 AM8/19/08
to
Anton Ertl wrote:
> Doug Hoffman <dhof...@talkamerica.net> writes:
>> Ed wrote:
>>
>>> Byte for byte LOCALS| is probably the
>>> most efficient syntax for implementing forth locals.
>> Byte for byte. My very dated PC has 750 meg of RAM and I forget how
>> many gigs of hard drive space. I really don't care about conserving a
>> few bytes here and there if I get something of value in return.
>>
>>
>>> While some may detest the stack ordering
>> Yes.
>
> Yes!
>
>>> etc etc, others will be buoyed by
>>> the fact there is no shorter way.
>> That would have to be those who *are* concerned about a few bytes.
>
> Not really. Those who are concerned about a few bytes, and who like
> the shortest way prefer not to use locals at all.
>
> This is also reflected in usage. Almost nobody uses LOCALS| (and the
> main example I know of probably does not do it to save a few bytes).
> Either people use { or they don't use locals at all.

Interesting. That would seem to make the adoption of the proposal a
simpler issue. We need just get the details of implementing { agreed
to. Sounds good to me.

-Doug

Doug Hoffman

unread,
Aug 19, 2008, 10:53:33 AM8/19/08
to
George Hubert wrote:
> On Aug 19, 6:46 am, Doug Hoffman <dhoff...@talkamerica.net> wrote:
>> That would have to be those who *are* concerned about a few bytes. Who
>> are they? Logically not those using Forth on a PC. Must be those doing
>> embedded stuff. Once again I wonder, is there a division of interest in
>> Forth between the two application areas? Does that division lead to a
>> conflict in how people want to see Forth evolve?
>>
>
> Surely an embedded system would be programmed with a cross compiler,
> so the locals stuff will be on the host anyway (we're not talking
> about the size of the generated code, since a decent optimiser
> would produce the same code anyway). Also most people find locals
> most useful for interfacing to the host OS so on an embedded system
> w/o an OS are they useful anyway.

I display my lack of knowledge of the embedded programming world. Sorry
about that. Then it is encouraging that this "division" I worried about
should not exist. Thanks for the insight.

-Doug

Stephen Pelc

unread,
Aug 19, 2008, 12:00:08 PM8/19/08
to
On Tue, 19 Aug 2008 10:42:44 -0400, Doug Hoffman
<dhof...@talkamerica.net> wrote:

>> This is also reflected in usage. Almost nobody uses LOCALS| (and the
>> main example I know of probably does not do it to save a few bytes).
>> Either people use { or they don't use locals at all.
>
>Interesting. That would seem to make the adoption of the proposal a
>simpler issue. We need just get the details of implementing { agreed
>to. Sounds good to me.

As I've mentioned before, if you survey the systems that provide
both the LOCALS| and { notations for locals, you will find that the
{ notation is far more widely used. On one (non MPE) system I looked
at, the ratio was over 20:1 in favour of the brace notation.

There must be a reason for this result ...

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

Andrew Haley

unread,
Aug 19, 2008, 12:37:51 PM8/19/08
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Tue, 19 Aug 2008 10:42:44 -0400, Doug Hoffman
> <dhof...@talkamerica.net> wrote:

> >> This is also reflected in usage. Almost nobody uses LOCALS| (and
> >> the main example I know of probably does not do it to save a few
> >> bytes). Either people use { or they don't use locals at all.
> >
> >Interesting. That would seem to make the adoption of the proposal
> >a simpler issue. We need just get the details of implementing {
> >agreed to. Sounds good to me.

> As I've mentioned before, if you survey the systems that provide
> both the LOCALS| and { notations for locals, you will find that the
> { notation is far more widely used. On one (non MPE) system I looked
> at, the ratio was over 20:1 in favour of the brace notation.

> There must be a reason for this result ...

It's less to type. The only downside of using a brace is that doing
so uses up one of the few ASCII characters we have left...

Andrew.

Marcel Hendrix

unread,
Aug 19, 2008, 1:29:03 PM8/19/08
to
steph...@mpeforth.com (Stephen Pelc) writes Re: RfD - Enhanced local variable syntax, v4 (long)

A question from this thread's start:

[..]

> Local types and extensions
> --------------------------
> Some current Forth systems use indicators to define local values
> of sizes other than a cell. It is proposed that any name ending
> in a ':' (colon) be reserved for this use.


> : foo { a b | F: f1 F: f2 -- c }
> ...
> ;

What are the follow-up plans with the brace notation?

: MAENO() ( nb ud -- )
{ nb D: ud -- F: t0 F: t1 F: t2 F: t3 F: t4 F: t5 F: t6 F: t7 -- }
SHHT? 0= IF CR N 0 .R 'x' EMIT N 0 .R ENDIF
...

.. surely will not not be everybody's idea of an easy-to-read notation.

How to signal what is left on the FP stack and data stack when both are
used? Also consider the use of COMPLEX and DOUBLE locals. E.g., how
would one write the following in, say, ANS Forth2020:

: MAENO() ( nb ud -- u ) ( F: -- r )
DLOCAL quack
LOCAL nb
0e 0e 0e 0e
0e 0e 0e 0e FLOCALS| t0 t1 t2 t3 |
0+1i 1+0i ZLOCALS| a c |
... ;

-marcel

Anton Ertl

unread,
Aug 19, 2008, 1:32:32 PM8/19/08
to
m...@iae.nl (Marcel Hendrix) writes:
>steph...@mpeforth.com (Stephen Pelc) writes Re: RfD - Enhanced local variable syntax, v4 (long)
>
>A question from this thread's start:
>
>[..]
>
>> Local types and extensions
>> --------------------------
>> Some current Forth systems use indicators to define local values
>> of sizes other than a cell. It is proposed that any name ending
>> in a ':' (colon) be reserved for this use.
>
>
>> : foo { a b | F: f1 F: f2 -- c }
>> ...
>> ;
>
>What are the follow-up plans with the brace notation?
>
>: MAENO() ( nb ud -- )
> { nb D: ud -- F: t0 F: t1 F: t2 F: t3 F: t4 F: t5 F: t6 F: t7 -- }
> SHHT? 0= IF CR N 0 .R 'x' EMIT N 0 .R ENDIF
> ...
>
>.. surely will not not be everybody's idea of an easy-to-read notation.

Obviously not. I have no idea what that's supposed to mean with the
two occurences of "--".

But given your additional stack effect comment, maybe you meant:

: MAENO { nb D: ud | F: t0 F: t1 F: t2 F: t3 F: t4 F: t5 F: t6 F: t7 -- }

Yes, that demonstrates how a possible future extension could be used.
I prefer to define temporary locals at the place where they would be
initialized, though.

>How to signal what is left on the FP stack and data stack when both are
>used?

You mean in the part behind the "--"? You could also do it with F:,
or you could use the Fortran way (that's also often used in Forth) of
using the start of the stack item name as an indicator (e.g., if it
starts with "r", it's an FP value). Or you could use one locals
definition for each stack, a style you seem to prefer.

> Also consider the use of COMPLEX and DOUBLE locals. E.g., how
>would one write the following in, say, ANS Forth2020:
>
>: MAENO() ( nb ud -- u ) ( F: -- r )
> DLOCAL quack
> LOCAL nb
> 0e 0e 0e 0e
> 0e 0e 0e 0e FLOCALS| t0 t1 t2 t3 |
> 0+1i 1+0i ZLOCALS| a c |
> ... ;

I would write it like this:

: maeno() { nb d: ud -- u r }
0e 0e 0e 0e
0e 0e 0e 0e { f: t3 f: t2 f: t1 f: t0 }
0+1i 1+0i { z: c z: a }

That works in Gforth now, with the following exception: complex
literals and "Z:" are not supported (yet).

Of course the advantage of this notation is not obvious in the FP and
complex part of this example, where the FP and the complex numbers are
nicely separated and all the t variables get the same value; in real
code it's probably rarely as nice, except if you pre-define locals
that get their real values later.

But a few advantages are obvious:

1) only one mentioning of NB in this fragment.

2) The double local gets the name it has in the stack comment and not
QUACK.

3) The locals definitions of NB and UD are not reversed compared to
the stack comment.

4) Two lines less.

Marcel Hendrix

unread,
Aug 20, 2008, 1:08:44 PM8/20/08
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]

> I would write it like this:

> : maeno() { nb d: ud -- u r }
> 0e 0e 0e 0e
> 0e 0e 0e 0e { f: t3 f: t2 f: t1 f: t0 }
> 0+1i 1+0i { z: c z: a }

[..]

OK, not too bad. ( I guess you meant : maeno() { nb d: ud -- u f: r } )

Would maintainers of unified stack systems welcome this proposal?

-marcel

Anton Ertl

unread,
Aug 20, 2008, 1:18:53 PM8/20/08
to
m...@iae.nl (Marcel Hendrix) writes:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: RfD - Enhanced local variable syntax, v4 (long)
>[..]
>> I would write it like this:
>
>> : maeno() { nb d: ud -- u r }
...

>( I guess you meant : maeno() { nb d: ud -- u f: r } )

One can write it like this to keep consistency with the locals
definition part, but I would probably leave the additional "f:" away,
because the "r" name already makes it clear that it is an FP value.
However, if ther is consensus that we should put the "f:" there, I
would comply with that convention.

Bernd Paysan

unread,
Aug 20, 2008, 4:52:28 PM8/20/08
to
Bernd Paysan wrote:
> Thanks. My comment:
>
> bigFORTH provides scoped local declarations. Unlike Gforth's scoping,
> bigFORTH's is explicit (bigFORTH's syntax is older). The syntax for scoped
> locals is
>
> { local .. local | code using the locals }
>
> so that would conflict with the proposal

More on this: I'm currently porting MINOS to VFX, and MINOS is one of the
rare places where nested locals are used (typical issue of interfacing C
function calls). VFX limits locals to one { } block (like ANS LOCALS| |),
and therefore, in all those cases where I have several scoped locals, I end
up having one block with a bunch of uninitialized locals.

It seems to me that this limitation (one declaration block only) should go
away, and then the need for uninitialized locals is significantly reduced.
I find it also more readable to have something like

{ x y w h |
(code using x y w h to calculate e.g. the center)
x w + y h +
{ cx cy |
(code using all of the above)
}
}

instead of - as proposed

{ x y w h | cx cy }
(code using x y w h to calculate e.g. the center)
x w + y h +
to cy to cx
(code using all of the above)

Problem: Order of cx/cy reverted; in this case, rearranging might be useful,
but often subroutines that deliver multiple values are used.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/

Celime

unread,
Aug 21, 2008, 7:38:23 AM8/21/08
to

"Marcel Hendrix" <m...@iae.nl> a écrit dans le message de news:
2026363...@frunobulax.edu...

> steph...@mpeforth.com (Stephen Pelc) writes Re: RfD - Enhanced local
> variable syntax, v4 (long)
>
> A question from this thread's start:
>
> [..]
>
>> Local types and extensions
>> --------------------------
[..]

> How to signal what is left on the FP stack and data stack when both
> are
> used? Also consider the use of COMPLEX and DOUBLE locals. E.g., how
> would one write the following in, say, ANS Forth2020:
>
> : MAENO() ( nb ud -- u ) ( F: -- r )
> DLOCAL quack
> LOCAL nb
> 0e 0e 0e 0e
> 0e 0e 0e 0e FLOCALS| t0 t1 t2 t3 |
> 0+1i 1+0i ZLOCALS| a c |
> ... ;
>
> -marcel
>

Just to signal a trick tu use LOCALS| with floats addresses:

here 100 floats allot value fsp

: flocs ( S: n -- n*x )( F: n*f -- )
fsp over floats +to fsp fsp ! \ prepare release
fsp 1 floats +to fsp \ adjust extern frames
over 0 ?do 1 floats - dup f! loop \ reverse store floats
swap 0 ?do dup 1 floats + loop drop ; \ pushes n*x addresses

: release-flocs ( -- ) \ possible to automate at exit...
fsp 1 floats - @ to fsp ;


: foo ( S: a b --)( F: x y -- )
2 flocs locals| 'y 'x b a |
a b + s>f
'x f@ f+
'y f@ f+
f.
'x f@ f.
release-flocs ;

1 2 3e 4e foo \ display 10e 3e

Doug Hoffman

unread,
Aug 21, 2008, 12:50:51 PM8/21/08
to
Bernd Paysan wrote:

> It seems to me that this limitation (one declaration block only) should go
> away, and then the need for uninitialized locals is significantly reduced.
> I find it also more readable to have something like
>
> { x y w h |
> (code using x y w h to calculate e.g. the center)
> x w + y h +
> { cx cy |
> (code using all of the above)
> }
> }

How would you handle stack effect output comments with this?

-Doug

Doug Hoffman

unread,
Aug 21, 2008, 1:33:23 PM8/21/08
to
Marcel Hendrix wrote:

> How to signal what is left on the FP stack and data stack when both are
> used? Also consider the use of COMPLEX and DOUBLE locals. E.g., how
> would one write the following in, say, ANS Forth2020:
>
> : MAENO() ( nb ud -- u ) ( F: -- r )
> DLOCAL quack
> LOCAL nb
> 0e 0e 0e 0e
> 0e 0e 0e 0e FLOCALS| t0 t1 t2 t3 |
> 0+1i 1+0i ZLOCALS| a c |
> ... ;

Since there are two separate stacks, perhaps incorporating the
"conventional" stack notation would work? In other words, have one
locals declaration per stack. For example (stack effects are always on
the first line):

: MAENO() { nb d: quack -- u } ( F: -- r )
0e 0e 0e 0e f{ t0 t1 t2 t3 -- r }
0+1i 1+0i f{ z: a z: c }
...
;

No type declaration within { ... } or { ... | ... -- ... } defaults to
one cell.
No type declaration within f{ ... } or f{ ... | ... -- ... } defaults to
one float cell.

If floats are also input parameters, then for consistency use something
like:

: foo { a b -- c } f{ d e -- f }
a b +
d e f+ ;

1 2 3e 4e foo . f.
3 7.000000 ok


I find it helps to keep the stack activity straight by separating the
stack effect comments for each stack. So in following the notion that
we like having locals declarations do double duty as stack effect
comments, this might be an approach to consider.

I also like having any "uninitialized" locals default to zero. So we
could optionally write MAENO() like this:

: MAENO() { nb d: quack -- u } f{ | t0 t1 t2 t3 -- r }
0+1i 1+0i f{ z: a z: c }
...
;

-Doug

Anton Ertl

unread,
Aug 21, 2008, 2:55:55 PM8/21/08
to
Bernd Paysan <bernd....@gmx.de> writes:
>Bernd Paysan wrote:
>> Thanks. My comment:
>>
>> bigFORTH provides scoped local declarations. Unlike Gforth's scoping,
>> bigFORTH's is explicit (bigFORTH's syntax is older). The syntax for scoped
>> locals is
>>
>> { local .. local | code using the locals }

That conflicts with VFX and possibly other systems (John Hayes wrote
about the VFX-style meaning of the "|" already in SigForth Newsletter
4(2), Fall '92) and, more importantly, with programs written for these
systems, so there is no chance that your scoping syntax is going to be
standardized.

If you want to limit the scope, Gforth has SCOPE ... ENDSCOPE, and
this probably causes fewer conflicts, if any.

>It seems to me that this limitation (one declaration block only) should go
>away, and then the need for uninitialized locals is significantly reduced.

I agree.

Anton Ertl

unread,
Aug 21, 2008, 3:02:50 PM8/21/08
to
Doug Hoffman <dhof...@talkamerica.net> writes:
[FP locals]

>Since there are two separate stacks, perhaps incorporating the
>"conventional" stack notation would work? In other words, have one
>locals declaration per stack. For example (stack effects are always on
>the first line):
>
>: MAENO() { nb d: quack -- u } ( F: -- r )
> 0e 0e 0e 0e f{ t0 t1 t2 t3 -- r }
> 0+1i 1+0i f{ z: a z: c }

Note that you got the order of the Z: locals wrong, because you stuck
to the wrong order from the ZLOCALS| notation.

> ...
> ;
>
>No type declaration within { ... } or { ... | ... -- ... } defaults to
>one cell.
>No type declaration within f{ ... } or f{ ... | ... -- ... } defaults to
>one float cell.

That would be an alternative for people who prefer to write down each
stack separately, or as a shortcut in cases where all or nearly all
locals are FP locals. For the latter usage, one could just as well
write "{ z: c z: a }", though.

But if it's used in the first way, the program becomes specific to
systems with separate stacks, whereas if one writes in a unified
definitions, one can relatively easily write the program such that it
works on both unified-stack (with any FP stack item size) and
separate-stack systems. Indeed, I believe that only FP locals make
this idea practically workable.

Being a separate-stack person myself, I don't think that this is a big
benefit of the unified stack declarations, but others might think
differently.

>If floats are also input parameters, then for consistency use something
>like:
>
>: foo { a b -- c } f{ d e -- f }
> a b +
> d e f+ ;
>
>1 2 3e 4e foo . f.
>3 7.000000 ok
>
>
>I find it helps to keep the stack activity straight by separating the
>stack effect comments for each stack.

I don't think so. Showing 4 items in two stack effect comments or
locals definitions is just as bad as showing 4 items in one.

We have used the unified notation on a separate-stack system for 15
years or so, and in my experience it works nicely.

>So in following the notion that
>we like having locals declarations do double duty as stack effect
>comments, this might be an approach to consider.

Well, I also write stack comments in unified notation.

But yes, if people feel strongly about using the separate notation,
one could offer "F{" in addition to the type specifier "F:".

>I also like having any "uninitialized" locals default to zero.

Alternatively, one could also initialize FP locals to signaling NaNs,
so the first usage of an uninitialized FP local would immediately show
up.

Bruce McFarling

unread,
Aug 21, 2008, 4:34:21 PM8/21/08
to
On Aug 21, 1:33 pm, Doug Hoffman <dhoff...@talkamerica.net> wrote:
> Since there are two separate stacks, perhaps incorporating the
> "conventional" stack notation would work? In other words, have one
> locals declaration per stack. For example (stack effects are always on
> the first line):
>
> : MAENO() { nb d: quack -- u } ( F: -- r )
> 0e 0e 0e 0e f{ t0 t1 t2 t3 -- r }
> 0+1i 1+0i f{ z: a z: c }
> ...
> ;

This will get confusing if used with arrays ... better to make it a
specialization of the generic "d:", "f:"?

... { nb d: quack -- u }

Doug Hoffman

unread,
Aug 21, 2008, 6:50:59 PM8/21/08
to
Anton Ertl wrote:
> Doug Hoffman <dhof...@talkamerica.net> writes:
> [FP locals]
>> Since there are two separate stacks, perhaps incorporating the
>> "conventional" stack notation would work? In other words, have one
>> locals declaration per stack. For example (stack effects are always on
>> the first line):
>>
>> : MAENO() { nb d: quack -- u } ( F: -- r )
>> 0e 0e 0e 0e f{ t0 t1 t2 t3 -- r }
>> 0+1i 1+0i f{ z: a z: c }
>
> Note that you got the order of the Z: locals wrong, because you stuck
> to the wrong order from the ZLOCALS| notation.

Right you are! All the more reason to get on with the new standard,
IMHO. :-)

I also didn't mean to include the stack output on the second line. I
meant to write it like this:

: MAENO() { nb d: quack -- u } ( F: -- r )
0e 0e 0e 0e f{ t0 t1 t2 t3 }

>> No type declaration within { ... } or { ... | ... -- ... } defaults to
>> one cell.
>> No type declaration within f{ ... } or f{ ... | ... -- ... } defaults to
>> one float cell.
>
> That would be an alternative for people who prefer to write down each
> stack separately, or as a shortcut in cases where all or nearly all
> locals are FP locals.

That would be me for both cases. But I shouldn't assume what others do.
I'm not feeling strongly one way or the other.

For the latter usage, one could just as well
> write "{ z: c z: a }", though.
>
> But if it's used in the first way, the program becomes specific to
> systems with separate stacks, whereas if one writes in a unified
> definitions, one can relatively easily write the program such that it
> works on both unified-stack (with any FP stack item size) and
> separate-stack systems. Indeed, I believe that only FP locals make
> this idea practically workable.
>
> Being a separate-stack person myself, I don't think that this is a big
> benefit of the unified stack declarations, but others might think
> differently.
>
>> If floats are also input parameters, then for consistency use something
>> like:
>>
>> : foo { a b -- c } f{ d e -- f }
>> a b +
>> d e f+ ;
>>
>> 1 2 3e 4e foo . f.
>> 3 7.000000 ok
>>
>>
>> I find it helps to keep the stack activity straight by separating the
>> stack effect comments for each stack.
>
> I don't think so. Showing 4 items in two stack effect comments or
> locals definitions is just as bad as showing 4 items in one.
>
> We have used the unified notation on a separate-stack system for 15
> years or so, and in my experience it works nicely.

The unified what? I just did a Google search on "forth unified stack
notation" and only four of the first 20 hits seemed to relate. One was
Marcel's post from 2 days ago, two were from Gforth's documentation, and
one was a post made by you in 1996. I just did a search on "unified" in
the Forth 200x / 07.2r PDF file and got no hits. I guess I am really
out of touch with this. The only commercial Forth I own lists the stack
effect for >FLOAT as:

c-addr u -- true|false FP: -- r


Looking in the Forth 200x / 07.2r PDF I find the following:

12.6.1.0558
>FLOAT ( c-addr u - true | false ) ( F: - r | ) or ( c-addr u - r
true | false )


I am definitely confused. I apologize for being ignorant about the
unified notation. I will study it.

-Doug

Bernd Paysan

unread,
Aug 22, 2008, 3:34:22 AM8/22/08
to
Doug Hoffman wrote:

I write something like

{ x y w h | ( --> cx cy ) x w + y h + }

Bernd Paysan

unread,
Aug 22, 2008, 4:13:55 AM8/22/08
to
Anton Ertl wrote:
> That conflicts with VFX and possibly other systems (John Hayes wrote
> about the VFX-style meaning of the "|" already in SigForth Newsletter
> 4(2), Fall '92) and, more importantly, with programs written for these
> systems, so there is no chance that your scoping syntax is going to be
> standardized.

My syntax is from spring 1992, so it predates John Hayes. I posted this on
clf on February 24th, 1992:

http://groups.google.com/group/comp.lang.forth/msg/86b24664a4c2afd9?dmode=source

I did put it into Gforth back then, as well, but then you wrote the better
(but more complex) automatic scoping package (my locals.fs is still there).
I prefer the automatic scoping, too, but won't recommend it for a standard
(too complex to implement).

> If you want to limit the scope, Gforth has SCOPE ... ENDSCOPE, and
> this probably causes fewer conflicts, if any.

Indeed.

After having ported a number of my scoped locals constructs to VFX, my
opinion is now quite strong: I definitely want at least explicit scope (can
be with SCOPE ... ENDSCOPE), and one declaration of locals per scope. I
don't see the point of uninitialized locals, they are only necessary due to
this limitation. I oppose the use of | as separator, breaks my syntax
(published first).

Marcel Hendrix

unread,
Aug 22, 2008, 1:18:30 PM8/22/08
to
Bruce McFarling <agi...@netscape.net> writes Re: RfD - Enhanced local variable syntax, v4 (long)

[..]


> This will get confusing if used with arrays ... better to make it a
> specialization of the generic "d:", "f:"?

> ... { nb d: quack -- u }
> ( F: -- r )
> 0e 0e 0e 0e {f: t0 t1 t2 t3 -- r }
> 0+1i 1+0i {f: z: a z: c }

or, even simpler:

... { s: nb -- u }
{ d: quack -- }

0e 0e 0e 0e { f: t0 t1 t2 t3 -- r }

0+1i 1+0i { z: a c }

-marcel


Ed

unread,
Aug 22, 2008, 2:22:39 PM8/22/08
to

"Doug Hoffman" <dhof...@talkamerica.net> wrote in message
news:1f363$48aa5e27$c4b37ce$26...@DIALUPUSA.NET...

Faster and fewer errors than what? Surely not LOCALS| .

There were posts from two (apparently long term) locals users who prefer
LOCAL - which is a single item variant of LOCALS| . They didn't mention
it being slow or error-prone. Forth Inc. has only LOCALS| .

LOCALS| is less error-prone *because* it follows forth convention by
pulling the topmost item off the stack first. A user who had any doubts
as to order can apply the same logic he uses for any other forth function.
It's that simple.

It is the introduction of functions that have their own specific rules and
contrary conventions that ultimately create confusion.

Yes, smaller is better. Not only will functions consume less resources
and run faster, it automatically results in a syntax that is 100% compatible
with forth. Why *wouldn't* anyone want that ... even in 2008.


Anton Ertl

unread,
Aug 22, 2008, 2:22:03 PM8/22/08
to

Not a good idea. You already made one additional mistake (in addition
to the reversal of a and c) above:

Doubles are on the same stack as singles, so you would have to write

... { d: quack } { s: nb }

In general, this brings back the LOCALS| nightmare. It only works
with separate FP locals definitions because they are on a separate
stack (and it does not work for FP locals if they are on a shared
stack).

Anton Ertl

unread,
Aug 22, 2008, 2:28:39 PM8/22/08
to
Doug Hoffman <dhof...@talkamerica.net> writes:

>Anton Ertl wrote:
>> We have used the unified notation on a separate-stack system for 15
>> years or so, and in my experience it works nicely.
>
>The unified what? I just did a Google search on "forth unified stack
>notation" and only four of the first 20 hits seemed to relate.

"Shared stack" may get more hits, but probably not more on stack
effect notation.

>Looking in the Forth 200x / 07.2r PDF I find the following:
>
>12.6.1.0558
> >FLOAT ( c-addr u - true | false ) ( F: - r | ) or ( c-addr u - r
>true | false )

Yes, the latter is the unified notation. The standards document uses
it only for specifying the stack effect for shared-stack systems, but
it works equally well for specifying the stack effect for
separate-stack systems:

If you want to see what happens on the data stack, you ignore the FP
values, and if you want to see what happens on the FP stack, you
ignore the data-stack values; I don't think that way when reading the
notation, though.

Bruce McFarling

unread,
Aug 22, 2008, 5:28:08 PM8/22/08
to
On Aug 22, 1:18 pm, m...@iae.nl (Marcel Hendrix) wrote:
> or, even simpler:
>
> ... { s: nb -- u }
> { d: quack -- }
> 0e 0e 0e 0e { f: t0 t1 t2 t3 -- r }
> 0+1i 1+0i { z: a c }

Actually, I did not like the type-at-a-time syntax, but as switches
rather than one-shots ...

{ nb d: quack f: t0 t1 t2 t3 z: a c -- u f: r }

... is a lot less busy. I guess s: would be the switch back to the
default single cell.

Doug Hoffman

unread,
Aug 23, 2008, 12:47:23 AM8/23/08
to
Anton Ertl wrote:
> Doug Hoffman <dhof...@talkamerica.net> writes:
>> Anton Ertl wrote:
>>> We have used the unified notation on a separate-stack system for 15
>>> years or so, and in my experience it works nicely.
>> The unified what? I just did a Google search on "forth unified stack
>> notation" and only four of the first 20 hits seemed to relate.
>
> "Shared stack" may get more hits, but probably not more on stack
> effect notation.

OK. I think I get it. For whatever reason I wasn't familiar with the
"unified" term.

>> Looking in the Forth 200x / 07.2r PDF I find the following:
>>
>> 12.6.1.0558
>> >FLOAT ( c-addr u - true | false ) ( F: - r | ) or ( c-addr u - r
>> true | false )
>
> Yes, the latter is the unified notation. The standards document uses
> it only for specifying the stack effect for shared-stack systems, but
> it works equally well for specifying the stack effect for
> separate-stack systems:

If the unified notation works equally well for separate or shared-stack,
it makes me wonder why the standards document shows both.


> If you want to see what happens on the data stack, you ignore the FP
> values, and if you want to see what happens on the FP stack, you
> ignore the data-stack values; I don't think that way when reading the
> notation, though.

I guess I'll have to spend some time using the unified stack notation.

-Doug

Doug Hoffman

unread,
Aug 23, 2008, 12:47:30 AM8/23/08
to
Ed wrote:
> "Doug Hoffman" <dhof...@talkamerica.net> wrote in message

>> Now one could always say that "smaller is better no matter what". That


>> may have been true a decade or two ago. But this is 2008. Things have
>> changed. I would gladly give up a few bytes for a tool that lets me get
>> the job done faster and with fewer errors along the way.
>
> Faster and fewer errors than what? Surely not LOCALS| .

I suppose it depends on which syntax one prefers. Clearly you and I
have different preferences.


> LOCALS| is less error-prone *because* it follows forth convention by
> pulling the topmost item off the stack first. A user who had any doubts
> as to order can apply the same logic he uses for any other forth function.
> It's that simple.
>
> It is the introduction of functions that have their own specific rules and
> contrary conventions that ultimately create confusion.
>
> Yes, smaller is better. Not only will functions consume less resources
> and run faster, it automatically results in a syntax that is 100% compatible
> with forth. Why *wouldn't* anyone want that ... even in 2008.

Given that, it seems difficult to explain the existence of the other
syntax in so many other Forths for so many years, and now the existence
of an RfD for the same.

I think this is an issue of preference, not an issue of what is more
Forth-like. Deciding what is or isn't Forth-like is a slippery slope.

-Doug

Doug Hoffman

unread,
Aug 23, 2008, 12:47:35 AM8/23/08
to
Bernd Paysan wrote:
> Doug Hoffman wrote:
>
>> Bernd Paysan wrote:
>>
>>> It seems to me that this limitation (one declaration block only) should
>>> go away, and then the need for uninitialized locals is significantly
>>> reduced. I find it also more readable to have something like
>>>
>>> { x y w h |
>>> (code using x y w h to calculate e.g. the center)
>>> x w + y h +
>>> { cx cy |
>>> (code using all of the above)
>>> }
>>> }
>> How would you handle stack effect output comments with this?
>
> I write something like
>
> { x y w h | ( --> cx cy ) x w + y h + }

Ouch. That is one very busy-looking line. But in time and with use I
suppose one could get accustomed to it.

-Doug

Marcel Hendrix

unread,
Aug 23, 2008, 2:46:12 AM8/23/08
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: RfD - Enhanced local variable syntax, v4 (long)

>m...@iae.nl (Marcel Hendrix) writes:
>>Bruce McFarling <agi...@netscape.net> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]
>>> This will get confusing if used with arrays ... better to make it a
>>> specialization of the generic "d:", "f:"?

>>> ... { nb d: quack -- u }
>>> ( F: -- r )
>>> 0e 0e 0e 0e {f: t0 t1 t2 t3 -- r }
>>> 0+1i 1+0i {f: z: a z: c }

>>or, even simpler:

>>... { s: nb -- u }
>> { d: quack -- }
>> 0e 0e 0e 0e { f: t0 t1 t2 t3 -- r }
>> 0+1i 1+0i { z: a c }

> Not a good idea. You already made one additional mistake (in addition
> to the reversal of a and c) above:

What a terribly condescending and suggestive remark (again). As you seem
to be encouraged in continuing this line of discussion when the opponent
tries to ignore your style, allow me a c+s-r of my own.

I count 0 uses of d: and 1 use of f: in the entire gforth 0.6.2 distribution
(excluding the two files that define locals). There seem to be no uses of
flocal and no uses of dlocal.

In bigforth (as far as needed for Minos/Theseus) I'm counting 59 occurences
of f: and no use of d:, dlocal or flocal.

In iForth I count (only in the examples directory) 1061 uses of
flocals| / flocal and 141 uses of dlocals| / dlocal. Apparently, in real use,
the "problems" of having to use a "wrong" stack order, or, FWIW, of making
errors with details of the existing standard locals (1305 uses) are not that
important. Unless I am some sort of language-masochist, I would have switched
to the "much easier" { notation already 15 years ago, or would have selected
it for the d/flocals extensions.

Of course, for this discussion it is only important what the many thousands
of users of gforth, bigforth and iForth are doing with locals. The only thing
I can contribute here is that I have never received a complaint in this direction,
and no requests to implement the "{" syntax natively. In fact, I never see any
support questions wrt locals at all.

> Doubles are on the same stack as singles, so you would have to write

> ... { d: quack } { s: nb }

Or the currently valid ... { d: quack } { nb }

> In general, this brings back the LOCALS| nightmare. It only works
> with separate FP locals definitions because they are on a separate
> stack (and it does not work for FP locals if they are on a shared
> stack).

It does not "bring it back," it's the only thing you can rely on *now*.

I guess it is now very convenient that unified stack systems exist :-)

-marcel

Bernd Paysan

unread,
Aug 23, 2008, 8:58:33 AM8/23/08
to
Doug Hoffman wrote:
>> I write something like
>>
>> { x y w h | ( --> cx cy ) x w + y h + }
>
> Ouch. That is one very busy-looking line. But in time and with use I
> suppose one could get accustomed to it.

Actually, I wouldn't write such a short line with locals. It's probably that
the first line looks like

{ x y w h | ( --> cx cy )

and then a bunch of more complex OS calls follows, and finally there's a

} ;

at the end of the definition.

Anton Ertl

unread,
Aug 23, 2008, 8:42:54 AM8/23/08
to
m...@iae.nl (Marcel Hendrix) writes:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: RfD - Enhanced local variable syntax, v4 (long)
>
>>m...@iae.nl (Marcel Hendrix) writes:
>>>Bruce McFarling <agi...@netscape.net> writes Re: RfD - Enhanced local variable syntax, v4 (long)
>[..]
>>>> This will get confusing if used with arrays ... better to make it a
>>>> specialization of the generic "d:", "f:"?
>
>>>> ... { nb d: quack -- u }
>>>> ( F: -- r )
>>>> 0e 0e 0e 0e {f: t0 t1 t2 t3 -- r }
>>>> 0+1i 1+0i {f: z: a z: c }
>
>>>or, even simpler:
>
>>>... { s: nb -- u }
>>> { d: quack -- }
>>> 0e 0e 0e 0e { f: t0 t1 t2 t3 -- r }
>>> 0+1i 1+0i { z: a c }
>
>> Not a good idea. You already made one additional mistake (in addition
>> to the reversal of a and c) above:
...

>I count 0 uses of d: and 1 use of f: in the entire gforth 0.6.2 distribution
>(excluding the two files that define locals).

Data, good! Some updated data from the latest CVS:

Number of occurences of '{' as likely locals definition:

grep '{ ' *.fs */*.fs |grep -v ^test/|wc -l
273

Number of occurences of 'F:':

grep '{ ' *.fs */*.fs |grep -v ^test/|grep -i F:|wc -l
3
grep '{ ' *.fs */*.fs |grep -v ^test/|grep -i D:|wc -l
21

> There seem to be no uses of
>flocal and no uses of dlocal.

Of course not; there are no such words in Gforth.

>In iForth I count (only in the examples directory) 1061 uses of
>flocals| / flocal and 141 uses of dlocals| / dlocal. Apparently, in real use,
>the "problems" of having to use a "wrong" stack order, or, FWIW, of making
>errors with details of the existing standard locals (1305 uses) are not that
>important.

Apparently not for you; for me they are, and looking at this thread, I
am not the only one.

>> Doubles are on the same stack as singles, so you would have to write
>
>> ... { d: quack } { s: nb }
>
>Or the currently valid ... { d: quack } { nb }
>
>> In general, this brings back the LOCALS| nightmare. It only works
>> with separate FP locals definitions because they are on a separate
>> stack (and it does not work for FP locals if they are on a shared
>> stack).
>
>It does not "bring it back," it's the only thing you can rely on *now*.

AFAIK there is no system that implements double and FP locals the way
that Bruce McFarling proposed, so nobody can rely on it; nor can
anyone rely on FLOCALS| or DLOCALS|, unless they want to restrict
themselves to iForth. And anyone who uses F: and D: restricts
themselves to Gforth or bigForth.

Concerning {, it's just as portable as LOCALS| thanks to
<http://www.complang.tuwien.ac.at/forth/anslocal.fs>. It even works
on iForth:

[c8:~/pub/forth:17183] iforth "include anslocal.fs"
...
iForth version 2.1.2541, generated 00:39:42, January 28, 2007.
i6 binary, native floating-point, double precision.
Copyright 1996 - 2007 Marcel Hendrix.

FORTH> : swap { a b -- b a } b a ;
Redefining swap ok
FORTH> 1 2 swap . . 1 2 ok

Anton Ertl

unread,
Aug 23, 2008, 9:23:04 AM8/23/08
to
Bruce McFarling <agi...@netscape.net> writes:
>On Aug 22, 1:18 pm, m...@iae.nl (Marcel Hendrix) wrote:
>> or, even simpler:
>>
>> ... { s: nb -- u }
>> { d: quack -- }
>> 0e 0e 0e 0e { f: t0 t1 t2 t3 -- r }
>> 0+1i 1+0i { z: a c }
>
>Actually, I did not like the type-at-a-time syntax, but as switches
>rather than one-shots ...
>
>{ nb d: quack f: t0 t1 t2 t3 z: a c -- u f: r }

That's much better, because it does not incur the reversal issue.
Unfortunately, it conflicts with current practice in Gforth and
bigForth (as does the earlier example, but not 'F{' or '{F:').

Also, looking at the code in Gforth, your suggestion is just as likely
to increase the number of type specifyers as to reduce them. Here are
all occurence of F: or D: in the current CVS:

ans-report.fs:: standardword { D: wordname D: wordset -- }
ds2texi.fs: name { D: wordname }
ds2texi.fs: name { D: wordset }
ds2texi.fs: name { D: pronounciation }
glocals.fs:\ : CX* { F: Ar F: Ai F: Br F: Bi -- Cr Ci }
libcc.fs:: gen-wrapped-call { d: pars d: c-name fp-change1 sp-change1 -- }
libcc.fs: count { r-type } count { d: pars }
libcc.fs: pars + count { d: c-name }
libcc.fs: s" gforth_c_" { d: prefix }
libcc.fs: count { ret } count 2dup { d: pars } chars + count { d: c-name }
libcc.fs: { d: filename }
libcc.fs: cff cff-rtype wrapper-function-name { d: wrapper-name }
libcc.fs: parse-name { d: c-name }
locals-test.fs:{ c: a b c: c d: d }
prims2x.fs: name { d: stack-name }
prims2x.fs: name { d: stack-pointer }
prims2x.fs: name { d: stack-type }
prims2x.fs: name { d: reg-name }
prims2x.fs: name { d: reg-type }
prof-inline.fs: { d: ud-dyn-callee d: ud-dyn-caller u-stat u-exec-callees u-callees }
prof-inline.fs: ud-dyn-callee p profile-count 2@ 2dup { d: de } d+
prof-inline.fs: ud-dyn-caller calls count-dyncalls 2dup { d: dr } d+
stuff.fs: { F: r } 1- compile-fliterals
stuff.fs:: f>buf-rdp-try { f: rf c-addr ur nd up um1 -- um2 }

Among these, there are only a few cases where there would be a change
at all, and it's not always a reduction: It would change the following
6 cases, leading to a reduction in 2 cases, the same number of type
specifiers in 2 cases, and an increase in 2 cases.

ans-report.fs:: standardword { D: wordname D: wordset -- }
-> ans-report.fs:: standardword { D: wordname wordset -- }

glocals.fs:\ : CX* { F: Ar F: Ai F: Br F: Bi -- Cr Ci }
-> glocals.fs:\ : CX* { F: Ar Ai Br Bi -- Cr Ci }

libcc.fs:: gen-wrapped-call { d: pars d: c-name fp-change1 sp-change1 -- }
-> libcc.fs:: gen-wrapped-call { d: pars c-name s: fp-change1 sp-change1 -- }

locals-test.fs:{ c: a b c: c d: d }
-> locals-test.fs:{ c: a s: b c: c d: d }

prof-inline.fs: { d: ud-dyn-callee d: ud-dyn-caller u-stat u-exec-callees u-callees }
-> prof-inline.fs: { d: ud-dyn-callee ud-dyn-caller s: u-stat u-exec-callees u-callees }

stuff.fs:: f>buf-rdp-try { f: rf c-addr ur nd up um1 -- um2 }
-> stuff.fs:: f>buf-rdp-try { f: rf s: c-addr ur nd up um1 -- um2 }

>... is a lot less busy. I guess s: would be the switch back to the
>default single cell.

Actually the type specifier for a single-cell local in Gforth is 'W:',
but I used 'S:' in the examples above, to keep with your usage.

Anton Ertl

unread,
Aug 23, 2008, 9:41:22 AM8/23/08
to
Doug Hoffman <dhof...@talkamerica.net> writes:
>Anton Ertl wrote:
>> Doug Hoffman <dhof...@talkamerica.net> writes:
>>> 12.6.1.0558
>>> >FLOAT ( c-addr u - true | false ) ( F: - r | ) or ( c-addr u - r
>>> true | false )
>>
>> Yes, the latter is the unified notation. The standards document uses
>> it only for specifying the stack effect for shared-stack systems, but
>> it works equally well for specifying the stack effect for
>> separate-stack systems:
>
>If the unified notation works equally well for separate or shared-stack,
>it makes me wonder why the standards document shows both.

Maybe someone on the standards committee still remembers the reason?

Doug Hoffman

unread,
Aug 23, 2008, 11:46:47 AM8/23/08
to
Anton Ertl wrote:
> Doug Hoffman <dhof...@talkamerica.net> writes:

>> If the unified notation works equally well for separate or shared-stack,
>> it makes me wonder why the standards document shows both.
>
> Maybe someone on the standards committee still remembers the reason?

After digging deeper into the standard document I find what appears to
be the reason:

----------------------
12.2.2.2 Stack notation

Floating-point stack notation when the floating-point stack is separate
from the data stack is:

( F: before - after )
-----------------------

The way I read that is separate stack effect notation is to be used when
there are separate integer and FP stacks. If the Forth uses unified
stacks, then the unified notation is to be used. Seems logical.

-Doug

Bernd Paysan

unread,
Aug 23, 2008, 4:59:55 PM8/23/08
to
Anton Ertl wrote:
> That's much better, because it does not incur the reversal issue.
> Unfortunately, it conflicts with current practice in Gforth and
> bigForth (as does the earlier example, but not 'F{' or '{F:').

Looking at bigFORTH's sources, F{ could be useful. To be more precise: a F{
that changes the default defining words of the locals to float, and still
has the same prefixes.

{ f: ri f: rm f: ro f: h n }

becomes

f{ ri rm ro h w: n }

bigFORTH's SVN repository locals.fs now also has SCOPE and ENDSCOPE (like
Gforth), and F{. bigFORTH already implemented --, but will not implement |
in the way suggested here.

Doug Hoffman

unread,
Aug 24, 2008, 12:26:31 PM8/24/08
to
Bernd Paysan wrote:
> Anton Ertl wrote:
>> That's much better, because it does not incur the reversal issue.
>> Unfortunately, it conflicts with current practice in Gforth and
>> bigForth (as does the earlier example, but not 'F{' or '{F:').
>
> Looking at bigFORTH's sources, F{ could be useful. To be more precise: a F{
> that changes the default defining words of the locals to float, and still
> has the same prefixes.
>
> { f: ri f: rm f: ro f: h n }
>
> becomes
>
> f{ ri rm ro h w: n }

I like having both { and f{ as well. The first defaults to integer, the
second defaults to float. A side benefit, and not an insignificant one,
would be more easily matching the standards documentation for showing
stack effects with separate stacks. Forths with unified stacks or
simply at the user's preference could use only { ... } with f: type
prefixes.

-Doug

Bruce McFarling

unread,
Aug 24, 2008, 2:00:24 PM8/24/08
to
On Aug 23, 8:42 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> AFAIK there is no system that implements double and FP locals the way that Bruce McFarling proposed, so nobody can rely on it;

That would be strictly impossible, since I did not propose any double
or FP locals implementation ... I just remarked on the visual (and
possible dictionary) confusion of f{ with an array and suggested an
alternate *name* for that word ...

... as an aside, its the placement of the brace at the beginning of
the name of the word that prevents the visual confusion with an array,
so "{f" would resolve that equally well ...

, and the fact that the

... f: name1 name2 name3 ...

... that appeared in a comment is less cluttered than the cumbersome

... f: name1 f: name2 f: name3 ...

If not f: because the "f:" name is already in use in the cumbersome
approach in gforth-beta and other places, then ...

... f:: name1 name2 name3 ...

... would be fine.

Ed

unread,
Aug 25, 2008, 12:55:41 AM8/25/08
to

"Doug Hoffman" <dhof...@talkamerica.net> wrote in message
news:d29a4$48af9661$c4b2db6$19...@DIALUPUSA.NET...

> Ed wrote:
> > "Doug Hoffman" <dhof...@talkamerica.net> wrote in message
>
> >> Now one could always say that "smaller is better no matter what". That
> >> may have been true a decade or two ago. But this is 2008. Things have
> >> changed. I would gladly give up a few bytes for a tool that lets me get
> >> the job done faster and with fewer errors along the way.
> >
> > Faster and fewer errors than what? Surely not LOCALS| .
>
> I suppose it depends on which syntax one prefers. Clearly you and I
> have different preferences.
>
>
> > LOCALS| is less error-prone *because* it follows forth convention by
> > pulling the topmost item off the stack first. A user who had any doubts
> > as to order can apply the same logic he uses for any other forth function.
> > It's that simple.
> >
> > It is the introduction of functions that have their own specific rules and
> > contrary conventions that ultimately create confusion.
> >
> > Yes, smaller is better. Not only will functions consume less resources
> > and run faster, it automatically results in a syntax that is 100% compatible
> > with forth. Why *wouldn't* anyone want that ... even in 2008.
>
> Given that, it seems difficult to explain the existence of the other
> syntax in so many other Forths for so many years, and now the existence
> of an RfD for the same.

Not so hard to explain. Most grow up with computer languages
that use infix notation. Infix abounds everywhere, including maths.
It's easy to slip back into familiar or preferred territory.

{ is an infix function with infix parameter ordering, disguised as
a stack comment.

> I think this is an issue of preference, not an issue of what is more
> Forth-like. Deciding what is or isn't Forth-like is a slippery slope.

Forth is a stack-based machine. The best functions, therefore,
are those which use the stack most efficiently. That's it.

Anton Ertl

unread,
Aug 27, 2008, 3:14:15 PM8/27/08
to
Bernd Paysan <bernd....@gmx.de> writes:
>Anton Ertl wrote:
>> That conflicts with VFX and possibly other systems (John Hayes wrote
>> about the VFX-style meaning of the "|" already in SigForth Newsletter
>> 4(2), Fall '92) and, more importantly, with programs written for these
>> systems, so there is no chance that your scoping syntax is going to be
>> standardized.
>
>My syntax is from spring 1992, so it predates John Hayes.

Currently I have no access to the paper, but IIRC he wrote that (then)
existing systems support this syntax.

But anyway, the question is not about priority, but about how to
resolve this conflict. I see the following options:

1) "|" is standardized as proposed by Stephen.

a) You (and possibly other bigForth users) rewrite the programs
that use the old bigForth "|" to use a different syntax, e.g.,
SCOPE...ENDSCOPE.

b) bigForth supports both syntaxes, based on a switch; e.g., by
default it supports the old bigForth syntax, and after an
extension query for X:locals (or somesuch), it supports the
standard meaning.

2) "|" is not standardized.

a) Stephen selects a different separator. According to the RfD "\"
has some existing practice, but OTOH has a conflict with "\" as
a comment-starting character that can also be used in locals
definitions (e.g., in Gforth).

b) There was a b), but I forgot what it was:-).

>I did put it into Gforth back then, as well, but then you wrote the better
>(but more complex) automatic scoping package (my locals.fs is still there).
>I prefer the automatic scoping, too, but won't recommend it for a standard
>(too complex to implement).

I also don't think that it is standardizable in its current form.
There are too many implementation artifacts there.

A simpler form would be that locals are visible at least up to the
next word that accesses a control-flow stack item below the current
depth of the control-flow stack; i.e., the locals would not be visible
across control-flow words, except across complete control structures.
Some restrictions on programs would be necessary to allow systems that
have longer scopes (like Gforth).

In terms of implementation this would probably be hardly more effort
than SCOPE...ENDSCOPE, but probably more invasive. So it's probably
not going to fly as a proposal.

>After having ported a number of my scoped locals constructs to VFX, my
>opinion is now quite strong: I definitely want at least explicit scope (can
>be with SCOPE ... ENDSCOPE), and one declaration of locals per scope.

I would prefer multiple declarations of locals per scope, otherwise I
would need to write a lot of SCOPE...ENDSCOPE wrappers.

>I
>don't see the point of uninitialized locals, they are only necessary due to
>this limitation. I oppose the use of | as separator, breaks my syntax
>(published first).

Do you have any idea how many programs were written that use that
syntax?

Anton Ertl

unread,
Aug 27, 2008, 3:39:08 PM8/27/08
to

Maybe it seems, but it isn't. The unified notation contains the
complete information. The separate notation can be generated
automatically from it, so specifying it is redundant.

However, having a separated notation in those cases where the stacks
are separate is consistent with the separate notation for the other
logically or physically separate stacks, e.g., the control-flow stack
or the return stack.

Anton Ertl

unread,
Aug 27, 2008, 3:44:51 PM8/27/08
to
"Ed" <nos...@invalid.com> writes:
>
>"Doug Hoffman" <dhof...@talkamerica.net> wrote in message
>news:d29a4$48af9661$c4b2db6$19...@DIALUPUSA.NET...
>> Given that, it seems difficult to explain the existence of the other
>> syntax in so many other Forths for so many years, and now the existence
>> of an RfD for the same.
>
>Not so hard to explain. Most grow up with computer languages
>that use infix notation. Infix abounds everywhere, including maths.
>It's easy to slip back into familiar or preferred territory.
>
>{ is an infix function with infix parameter ordering, disguised as
>a stack comment.

If { is infix, so is LOCALS|, which is in the same position.

If the order of the names in {...} is an infix order, then the infix
poison has been injected in Forth with the invention of stack effect
comments, which use the same ordering.

>Forth is a stack-based machine. The best functions, therefore,
>are those which use the stack most efficiently. That's it.

Face it: Locals are a way to avoid dealing with stacks. If you want
to be a stack purist, better eschew them completely. Pretending that
writing the names in the wrong order somehow preserves the use of the
stack is self-delusion.

Ed

unread,
Aug 28, 2008, 3:17:38 AM8/28/08
to

"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
news:2008Aug2...@mips.complang.tuwien.ac.at...

> "Ed" <nos...@invalid.com> writes:
> >
> >"Doug Hoffman" <dhof...@talkamerica.net> wrote in message
> >news:d29a4$48af9661$c4b2db6$19...@DIALUPUSA.NET...
> >> Given that, it seems difficult to explain the existence of the other
> >> syntax in so many other Forths for so many years, and now the existence
> >> of an RfD for the same.
> >
> >Not so hard to explain. Most grow up with computer languages
> >that use infix notation. Infix abounds everywhere, including maths.
> >It's easy to slip back into familiar or preferred territory.
> >
> >{ is an infix function with infix parameter ordering, disguised as
> >a stack comment.
>
> If { is infix, so is LOCALS|, which is in the same position.
>

LOCALS| is a simple iteration of the definer (LOCAL).
The syntax of LOCALS| is thus determined by (LOCAL).

In contrast { has a parameter list where each item can have
it's own meaning, rules, and ordering as determined by the
creator. The objects in the list may be expanded to include
almost anything.

No, they are quite different.

> If the order of the names in {...} is an infix order, then the infix
> poison has been injected in Forth with the invention of stack effect
> comments, which use the same ordering.
>
> >Forth is a stack-based machine. The best functions, therefore,
> >are those which use the stack most efficiently. That's it.
>
> Face it: Locals are a way to avoid dealing with stacks. If you want
> to be a stack purist, better eschew them completely. Pretending that
> writing the names in the wrong order somehow preserves the use of the
> stack is self-delusion.

I'll use whatever is most sensible for the task at hand. Should I
elect to use locals, I see no necessity to abandon forth convention
particularly as it produces consistent syntax. I like the idea that if
I use either global or local values that the name order ends up
the same.

LOCALS| has the correct ordering for a forth function. It's not a
stack comment, and doesn't pretend to be one. Forth already has
a mechanism for handling stack comments.

David N. Williams

unread,
Aug 28, 2008, 9:19:35 AM8/28/08
to
Ed wrote:
> [...]

>
> LOCALS| is a simple iteration of the definer (LOCAL).
> The syntax of LOCALS| is thus determined by (LOCAL).
>
> In contrast { has a parameter list where each item can have
> it's own meaning, rules, and ordering as determined by the
> creator. The objects in the list may be expanded to include
> almost anything.
>
> No, they are quite different.

I must say that when I use locals, it's always LOCALS|...|.
That's because I care about portability, maybe sometimes
obsessively.

I don't at all have a problem remembering that it's the wrong
order or keeping track when initializing locals.

But I would really, really prefer that standard locals use stack
comment order.* :-)

> [...]


>
> I'll use whatever is most sensible for the task at hand. Should I
> elect to use locals, I see no necessity to abandon forth convention
> particularly as it produces consistent syntax. I like the idea that if
> I use either global or local values that the name order ends up
> the same.
>
> LOCALS| has the correct ordering for a forth function. It's not a
> stack comment, and doesn't pretend to be one. Forth already has
> a mechanism for handling stack comments.

I'm not sure what's the natural meaning of "forth function". In
any case, whether or not LOCALS|...| was or should have been
intended to be like a stack comment, it seems that {...} *does*
aim to be like one, in a pretty interesting way.

-- David

*That's the order implemented for dynamic string arguments.

Bernd Paysan

unread,
Aug 28, 2008, 11:57:27 AM8/28/08
to
Anton Ertl wrote:
> But anyway, the question is not about priority, but about how to
> resolve this conflict. I see the following options:
>
> 1) "|" is standardized as proposed by Stephen.
>
> a) You (and possibly other bigForth users) rewrite the programs
> that use the old bigForth "|" to use a different syntax, e.g.,
> SCOPE...ENDSCOPE.
>
> b) bigForth supports both syntaxes, based on a switch; e.g., by
> default it supports the old bigForth syntax, and after an
> extension query for X:locals (or somesuch), it supports the
> standard meaning.

b) is the more likely option. And there probably will be a flag to be set
and cleared depending on which sources you load - like the legacy flag for
C bindings.

> 2) "|" is not standardized.
>
> a) Stephen selects a different separator. According to the RfD "\"
> has some existing practice, but OTOH has a conflict with "\" as
> a comment-starting character that can also be used in locals
> definitions (e.g., in Gforth).

My suggestion: '+' or '++'. As local name, '+' is very useless.

{ a b + c d -- e f }
{ a b ++ c d -- e f }

means "take a and b from the stack plus define c and d uninitialized". From
the look of it, I like ++ more.

> b) There was a b), but I forgot what it was:-).

Allow multiple declarations of locals, and the "problem" '|' tries to
address in the proposal goes away. I've rewritten parts of MINOS to use
only one place for local definitions, and the result was that for the first
time in my life I needed an uninitialized local ;-). Since bigFORTH doesn't
have those, I "emulate" them by putting zeros on the stack.

> I would prefer multiple declarations of locals per scope, otherwise I
> would need to write a lot of SCOPE...ENDSCOPE wrappers.

That's why I've chosen a one-letter syntax. You declare { locals | code }
and it's far less obtrusive than SCOPE { locals } code ENDSCOPE. From an
implementation point of view, having all closing structure words check if
there's an open scope seems to be trivial for me (they do something
like ?pairs or so to check if there's a valid CS-entry, anyway, just hook
it there; it will close all local scopes until it finds the CS-entry it
looks for), so a simpler version of Gforth's automatic scoping seems to be
feasible, too.

> Do you have any idea how many programs were written that use that
> syntax?

No. My own usage of locals is pretty limited, mostly MINOS and examples. And
half of that is now least-common-denominator due to the VFX-MINOS porting
effort.

Marcel Hendrix

unread,
Aug 28, 2008, 3:20:05 PM8/28/08
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: RfD - Enhanced local variable syntax, v4 (long)

>m...@iae.nl (Marcel Hendrix) writes:
>>Bruce McFarling <agi...@netscape.net> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]
>>> This will get confusing if used with arrays ... better to make it a
>>> specialization of the generic "d:", "f:"?

>>> ... { nb d: quack -- u }
>>> ( F: -- r )

>>> 0e 0e 0e 0e {f: t0 t1 t2 t3 -- r }

>>> 0+1i 1+0i {f: z: a z: c }

>>or, even simpler:

>>... { s: nb -- u }
>> { d: quack -- }
>> 0e 0e 0e 0e { f: t0 t1 t2 t3 -- r }
>> 0+1i 1+0i { z: a c }

> Not a good idea. You already made one additional mistake (in addition


> to the reversal of a and c) above:

What a terribly condescending and suggestive remark (again). As you seem


to be encouraged in continuing this line of discussion when the opponent
tries to ignore your style, allow me a c+s-r of my own.

I count 0 uses of d: and 1 use of f: in the entire gforth 0.6.2 distribution
(excluding the two files that define locals). There seem to be no uses of

flocal and no uses of dlocal.

In bigforth (as far as needed for Minos/Theseus) I'm counting 59 occurences

of f: and no use of d:, dlocal or flocal.

In iForth I count (only in the examples directory) 1061 uses of

flocals| / flocal and 141 uses of dlocals| / dlocal. Apparently, in real use,
the "problems" of having to use a "wrong" stack order, or, FWIW, of making
errors with details of the existing standard locals (1305 uses) are not that

important. Unless I am some sort of language-masochist, I would have switched
to the "much easier" { notation already 15 years ago, or would have selected
it for the d/flocals extensions.

Of course, for this discussion it is only important what the many thousands
of users of gforth, bigforth and iForth are doing with locals. The only thing
I can contribute here is that I have never received a complaint in this direction,
and no requests to implement the "{" syntax natively. In fact, I never see any
support questions wrt locals at all.

> Doubles are on the same stack as singles, so you would have to write

> ... { d: quack } { s: nb }

Or the currently valid ... { d: quack } { nb }

> In general, this brings back the LOCALS| nightmare. It only works
> with separate FP locals definitions because they are on a separate
> stack (and it does not work for FP locals if they are on a shared
> stack).

It does not "bring it back," it's the only thing you can rely on *now*.

I guess it is now very convenient that unified stack systems exist :-)

-marcel

Marcel Hendrix

unread,
Aug 28, 2008, 3:20:12 PM8/28/08
to
"Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
[..]

> LOCALS| is a simple iteration of the definer (LOCAL).
> The syntax of LOCALS| is thus determined by (LOCAL).
[.. etc. ..]

You formulate my thoughts (or should I say tastes) exactly.
I wholeheartedly agree with your arguments in this matter (in
the current and especially in your previous post).

For me, it would suffice when (FLOCAL) and (DLOCAL) were added,
or alternatively and even better, when the sizing factor of (LOCAL)
and the method table of TO were to be exposed. All the rest can be
defined in compatibility files at startup.

If an extended form of { comes through, I would applaud it if the
newly invented embellishments can be made to look like Forth
comments easily. And if the syntax replaces the now standard stack
comments, I hope the committee chooses a format that tells me what
to expect on which stack unambiguously.

-marcel

Peter Fälth

unread,
Aug 28, 2008, 4:20:28 PM8/28/08
to
On Aug 28, 9:20 pm, m...@iae.nl (Marcel Hendrix) wrote:
> "Ed" <nos...@invalid.com> writes Re: RfD - Enhanced local variable syntax, v4 (long)
> [..]> LOCALS|  is a simple iteration of the definer  (LOCAL).
> > The syntax of  LOCALS|  is thus determined by  (LOCAL).
>
> [.. etc. ..]
>
> You formulate my thoughts (or should I say tastes) exactly.
> I wholeheartedly agree with your arguments in this matter (in
> the current and especially in your previous post).

This is also my view

> For me, it would suffice when (FLOCAL) and (DLOCAL) were added,
> or alternatively and even better, when the sizing factor of (LOCAL)
> and the method table of TO were to be exposed. All the rest can be
> defined in compatibility files at startup.

I agree to this also. I would also like to see a (LBUFFER) to define a
local buffer.

> If an extended form of { comes through, I would applaud it if the
> newly invented embellishments can be made to look like Forth
> comments easily. And if the syntax replaces the now standard stack
> comments, I hope the committee chooses a format that tells me what
> to expect on which stack unambiguously.

Mixing stack comment and locals make no sense to me. As proposed in
the buffer extension I would have to write

{ | [ 1024 ] BUF1 [ 2 cells ] BUF2 }

to declare 2 local buffers. What does this have to do with a stack
comment?

Peter Falth

> -marcel

David N. Williams

unread,
Aug 28, 2008, 8:36:11 PM8/28/08
to
David N. Williams wrote:
> [...]

>
> But I would really, really prefer that standard locals use stack
> comment order.* :-)

Josh Grams sent me a private email wondering why, since I yearn
for standard locals with stack comment order, I don't just use
the gforth standard implementation:

http://www.complang.tuwien.ac.at/forth/anslocal.fs

That inspired me to revisit an old modification which worked
across lines. FWIW, a new version is posted below.

It uses NEXT-INSTREAM-NAME, which is the parsing.fs library name
for Wil Baden's across line word NEXT-WORD, and
|S|-SEEK-INSTREAM, the parsing.fs word for seeking past a
whitespace delimited string across lines.

It also uses the dynamic string (dstring) word >$S-COPY, which
copies an ANS Forth string (fstring) into string space and
pushes it onto the string stack, as well as $S>, which pops a
dstring from the string stack and pushes it onto the data stack
as an fstring.

This works with gforth. It fails with pfe, as does anslocal.fs.
It's suspicious to me that pfe's (LOCAL) is immediate, but
changing only the immediacy doesn't help.

-- David


( Title: Stack-comment ordered locals across lines
File: aelocals-xl.fs
Author: David N. Williams
License: Public Domain
Version: 0.5.0
Revised: August 28, 2008
)

s" parsing.fs" required
s" dstrings.fs" required

(*
http://www-personal.umich.edu/~williams/archive/forth/strings/parsing.fs
http://www-personal.umich.edu/~williams/archive/forth/strings/dstrings.fs

This code modifies Anton Ertl's anslocal.fs to work across lines.

Notation:
<ws> whitespace characters or line ends
<ws0> optional <ws>
<_--_text0> optional whitespace delimited "--" and text across lines
_}_ whitespace delimited "}"
*)


: get-locals ( "<ws0><name_1><ws>...<name_n><_--_text0>_}_" -- )
next-instream-name 2dup s" --" compare 0=
IF
2drop s" }" |s|-seek-instream
0= ABORT" ***locals } terminator not found" EXIT
ELSE
2dup s" }" compare 0= IF 2drop EXIT THEN
THEN
>$s-copy RECURSE $s> (LOCAL)
;


: { ( "<ws0><name_1><ws>...<name_n><_--_text0>_}_" -- ) \ compile
( p_1 ... p_n -- ) \ run
get-locals 0 0 (LOCAL)
; immediate


0 [IF]
\ broken-line version of Anton Ertl's test word
: test1-swap {


a
b
-- b a
}

." xxx" b a ;

cr 1 2 test1-swap . . .s cr

\ version without "--"
: test2-swap { a
b }
." xxx" b a ;

1 2 test2-swap . . .s cr
[THEN]

Anton Ertl

unread,
Aug 29, 2008, 6:08:56 AM8/29/08
to
"David N. Williams" <will...@umich.edu> writes:
>It fails with pfe, as does anslocal.fs.
>It's suspicious to me that pfe's (LOCAL) is immediate, but
>changing only the immediacy doesn't help.

Yes, I defined

: (local) postpone (local) ;

to get rid of the immediacy, but that does not help. I also tried the
definition of LOCALS| given in section A.13 of the standard, and that
does not work on PFE, either. I guess that PFE's (LOCAL) is broken in
more ways.

It is loading more messages.
0 new messages