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

RfD: Enhanced local variable syntax (v6)

4 views
Skip to first unread message

Peter Knaggs

unread,
Aug 31, 2010, 1:26:10 PM8/31/10
to
RfD - Enhanced local variable syntax, v6
====================================
Stephen Pelc - 26 March 2010

20100325 Wordsmithing at Rostock meeting
Moved to BNF description
Added rationale
Converted Testing to new harness
20091022 Discussion about { and {:.
"Should" to "shall".
20090830 Tidied.
20090325 Updated with some renaming.
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) 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 locals is proposed. The sequence:

{: arg1 arg2 ... | lv1 lv2 ... -- o1 o2 ... :}

declares local arguments, local values, and dummy outputs.

Local arguments and local values both behave as locals, they differ
only in respect to their initialisation.

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 local declaration to be read as a stack comment.

The items between {: and | are locals initialised from the data stack.
The items between | and -- are uninitialised locals.
The items between -- and :} are outputs for formal comments only.

The -- to :} section is optional, i.e. | or {: direct to :} is
permitted.

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

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

In the example below, a and b are local arguments, and c and
d are local values.

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

Local types and extensions
--------------------------
Although out of the scope of this proposal, it should be noted
that some current Forth systems use indicators to define local
values of sizes other than a cell. To avoid issues when porting
code to such systems, names ending in a ':' (colon) should be
avoided.

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

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


Discussion
==========
The phrase { ... } rather than {: ... :} has been used by systems
for over 15 years. However, it conflicts with existing practise in
other Forth systems. Choosing the new name allows both practises
to coexist.

The '|' (ASCII $7C) character is widely used as the separator
between local arguments and local values. Other characters
accepted in current Forth implementations are '\' (ASCII $5C) and
'¦' ($A6). Since the ANS standard is defined in terms of 7-bit
ASCII, and with regard to internationalisation, we propose only to
consider the '|' and '\' characters further. Only recognition of
the '|' separator is mandatory.

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.


Proposal
========

In order to facilitate the use of BNF in the {: definition it is
necessary to move the BNF definition added to 2.2.1 Numeric notation
by the X:number-prefix proposal to a more general description in
section 2.2 Notation.

The following notation is used to define the syntax of the
various elements within the document:

- Each component of the element is defined with a rule consisting
of the name of the component (italicized in angle-brackets,
e.g., </decdigit/>), the characters := and a concatenation of
tokens and metacharacters;

- Tokens may be literal characters (in bold face, e.g., "E") or
rule names in angle brackets (e.g., </decdigit/>);

- The metacharacter * is used to specify zero or more occurrences
of the preceding token (e.g., </decdigit/>*);

- Tokens enclosed with [ and ] are optional (e.g., ["-"]);

- Vertical bars separate choices from a list of tokens enclosed
with braces (e.g., { "0" | "1" }).

See: 3.4.1.3 Text interpreter input number conversion,
12.3.7 Text interpreter input number conversion,
12.6.1.0558 >FLOAT, 12.6.2.1613 FS and 13.6.2.xxxx {: .


13.3.3.2 Syntax restrictions

Replace item f)

A program that declares more than eight locals in a single
definition has an environmental dependency;

with

A program that declares more than sixteen locals in a single
definition has an environmental dependency;


13.6.2.xxxx {: brace-colon LOCAL EXT

Interpretation: Interpretation semantics for this word are undefined.

Compilation: ( i*x "<spaces>:}" -- )

Parse space delimited names according to the following syntax:

"{:" <arg>* ["|" <val>*] ["--" <out>*] ":}"

where <arg>, <val> and <out> are names, and i is the number of
<arg> names given.

The following ambiguous conditions exist when:
- a local name ends in ":", "[", or "^";
- a local name is "\" or "|";
- the text between {: and :} extends over more than one line;
- {: ... :} is used more than once in a word.

Append the run-time semantics below.

run-time: ( x1 ... xn -- )
Create locals for <arg>s and <val>s. <out>s are ignored.

<arg> names are initialise from the data stack, with the top of
the stack being assigned to the right most <arg> name.

<val> names are uninitialised.

<val> names and <arg> names have the execution semantics given
below.

/name/ Execution: ( -- x )
Place the value currently assigned to /name/ on the stack.
An ambiguous condition exists when local is executed while in
interpretation state.

TO /name/ Run-time: ( x -- )
Assign the value x to /name/.

See: 2.2 Notation, 6.2.2405 VALUE, 6.2.2295 TO and A.13.6.2.xxxx {:

A.13.6.2.xxxx {:
In A.13 The optional Locals word set ANS Forth '94 the TC identifies
the significant difficulties experienced when addressing the issue
of locals. Since the Technical Committee was unable identify any
common practice they provided a way to define locals 13.6.1.0086
(LOCAL)) and a method of parsing them (13.6.2.1795 LOCALS|). In the
hope that a common practice will emerge.

Common practice has since emerged. Most implementations that
provide (LOCAL) and LOCALS| also provide some form of the { ... }
notation; however, the phrase { ... } conflicts with other systems.
The {: ... :} notation is a compromise to avoid name conflicts.

The notation provides for different classes: locals that are
initialised from the data stack at run-time; uninitialised locals
and outputs. Initialised locals are separated from uninitialised
locals by '|'. The definition of locals is terminated by '--' or
':}'.

All text between '--' and ':}' is ignored. This eases documentation
by allowing a complete stack comment in the locals definition.

The '|' (ASCII $7C) character is widely used as the separator
between local arguments and local values. Some implementations have
used '\' (ASCII $5C) or '¦' ($A6). Systems are free to continue to
provide these alternative separators. However, only the recognition
of the '|' separator is mandatory. Therefor portable programs must
use the '|' separator.

A number of systems extend the locals notation in various ways.
Some of these extensions may emerge as common practise. This
standard has reserved the notation used by these extensions to avoid
difficulties when porting code to these systems. In particular
local names ending in ':' (colon), '[' (open bracket), or '^'
(carat) are reserved, as is using '\' (back slash) or '|' (bar) as
a local name.


Reference implementation
=========================

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 and values, each of
which is a definition name, that only have execution semantics
within the scope of that definition's source.

Note that it is often useful to accumulate and store the size of
locals storage (0=none), so that compilers for EXIT can easily
determine if locals clean up code is required.
[then]

VARIABLE #LVS \ -- addr
\ Holds size of locals storage required.

: BUILDLV \ c-addr u +n mode --
\ Dummy for testing
OVER #LVS +!
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
;

: {: \ --
\ Parse the locals declaration up to the closing ":}".
0 #LVS ! \ indicate no locals yet
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
CELL 2
THEN
BUILDLV
THEN
REPEAT
BEGIN
S" :}" COMPARE
WHILE
TOKEN
REPEAT
0 0 0 0 BUILDLV
R> DROP
; IMMEDIATE


Tests
=====

: LT1 {: a b | c -- f :}
CR ." Hello1 " CR a ;
T{ 3 4 LT1 -> 3 }T \ Outputs Hello1

: LT2 {: a | b c e :}
CR ." Hello2 " CR ;
T{ 3 LT2 -> }T \ Outputs Hello2

: LT3 {: a b c -- :}
CR ." Hello3 " CR ;
T{ 3 4 5 LT3 -> }T \ Outputs Hello3

: LT4 {: a b c :}
CR ." Hello4 " CR ;
T{ 3 4 5 LT4 -> }T \ Outputs Hello4

: LT5 {: a | b c d -- e f g :}
CR ." Hello5 " CR
a 2* to b b 2* to c c 2* to d
b c d ;
T{ 3 LT5 -> 6 12 24 }T \ Outputs Hello5


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

Alex McDonald

unread,
Aug 31, 2010, 5:05:33 PM8/31/10
to
On 31 Aug, 18:26, "Peter Knaggs" <p...@bcs.org.uk> wrote:
> RfD - Enhanced local variable syntax, v6

<snipped>

> The following syntax for locals is proposed. The sequence:
>
>    {: arg1 arg2 ... | lv1 lv2 ... -- o1 o2 ... :}
>
> declares local arguments, local values, and dummy outputs.

Was {| ... |} or somesuch considered as a token? Neon based compilers
use colons to indicate methods, as in <method: object>.

>
> Local arguments and local values both behave as locals, they differ
> only in respect to their initialisation.
>

Again, as there is the opportunity for change, can the restriction
that only values be declared be relaxed? In particular, variables
(accessed via @ !) would be useful, particularly for Forths that
interface with the underlying OS, where local variables allow much
more flexible solutions. I see possible support for an <x>: syntax; is
it anticipated that something along the lines of var: ?

<snipped>

> The '|' (ASCII $7C) character is widely used as the separator
> between local arguments and local values. Other characters
> accepted in current Forth implementations are '\' (ASCII $5C) and
> '¦' ($A6). Since the ANS standard is defined in terms of 7-bit
> ASCII, and with regard to internationalisation, we propose only to
> consider the '|' and '\' characters further. Only recognition of
> the '|' separator is mandatory.

\ should be eliminated in the new syntax, especially when the
reference implementation suggests that locals may span more than one
line; the following

{: a b c \ d
e f :}

is (at least by a human reader) ambiguously parsed as {: a b c \ e
f :} due to the overloading of the comment word \.

Stephen Pelc

unread,
Aug 31, 2010, 5:48:57 PM8/31/10
to
On Tue, 31 Aug 2010 14:05:33 -0700 (PDT), Alex McDonald
<bl...@rivadpm.com> wrote:

>\ should be eliminated in the new syntax, especially when the
>reference implementation suggests that locals may span more than one
>line; the following
>
> {: a b c \ d
> e f :}
>
>is (at least by a human reader) ambiguously parsed as {: a b c \ e
>f :} due to the overloading of the comment word \.

I'm happy to remove the use of \ as it only affects Win32Forth. The
wording is intended to reserve \ for Win32Forth and to promote |
as the standard way without disenfranchising Win32Forth. However,
if you want to be disenfranchised, who am I to argue?

Stephen


--
Stephen Pelc, steph...@mpeforth.com

George Hubert

unread,
Aug 31, 2010, 7:12:59 PM8/31/10
to
On Aug 31, 10:48 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Tue, 31 Aug 2010 14:05:33 -0700 (PDT), Alex McDonald
>
> <b...@rivadpm.com> wrote:
> >\ should be eliminated in the new syntax, especially when the
> >reference implementation suggests that locals may span more than one
> >line; the following
>
> >  {: a b c \ d
> >  e f :}
>
> >is (at least by a human reader) ambiguously parsed as {: a b c \ e
> >f :} due to the overloading of the comment word \.
>
> I'm happy to remove the use of \ as it only affects Win32Forth. The
> wording is intended to reserve \ for Win32Forth and to promote |
> as the standard way without disenfranchising Win32Forth. However,
> if you want to be disenfranchised, who am I to argue?
>
> Stephen
>
> --
> Stephen Pelc, stephen...@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

\ is actually quite a lot in the w32f source files (especially
in applications rather than the system itself, so I think it
should be reserved (and | encouraged for portability although
w32f has supported | for 7 yrs and \ is still used). Also
having a local called \ is plain stupid: it means you can't
use it for comments in the word and is just confusing, so
not allowing it doesn't really do any harm.

George Hubert

Peter Knaggs

unread,
Aug 31, 2010, 7:25:28 PM8/31/10
to
Alex McDonald wrote:

>
> Peter Knaggs wrote:
>>
>> The following syntax for locals is proposed. The sequence:
>>
>> {: arg1 arg2 ... | lv1 lv2 ... -- o1 o2 ... :}
>>
>> declares local arguments, local values, and dummy outputs.
>
> Was {| ... |} or somesuch considered as a token? Neon based compilers
> use colons to indicate methods, as in <method: object>.

The notation was thrashed out at the Exeter meeting last year, although
the proposal was not rewritten until the Rostock workshop. I do not
recall other sequences being discussed, except for [: ... :], more of
which below. It should be noted that the trailing colon is used in many
packages for defining words (buffer: for example). While I would be
willing to review the notation if suitable alternatives can be agreed, I
am, however, a little weary of | due to the character code ($7C or $A6)
problem.

>> Local arguments and local values both behave as locals, they differ
>> only in respect to their initialisation.
>
> Again, as there is the opportunity for change, can the restriction
> that only values be declared be relaxed? In particular, variables
> (accessed via @ !) would be useful, particularly for Forths that
> interface with the underlying OS, where local variables allow much
> more flexible solutions. I see possible support for an <x>: syntax; is
> it anticipated that something along the lines of var: ?

A number of people would like something like this, especially for
interaction with a host operating system. An additional notation was
proposed for local scope specific definitions [: ... :]. Where any
definition within the environment is restricted to the current colon
definition.

I note that although this was suggested at the same time as the {: ... :}
notation, no proposal has been forthcoming.

--
Peter Knaggs

Anton Ertl

unread,
Sep 1, 2010, 8:59:46 AM9/1/10
to
"Peter Knaggs" <p...@bcs.org.uk> writes:
>I
>am, however, a little weary of | due to the character code ($7C or $A6)
>problem.

There is no problem: $A6 is no ASCII character, so it's obviously $7C.
But maybe you want to write that explicitly in the proposal.

- 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 2010: http://www.euroforth.org/ef10/

Anton Ertl

unread,
Sep 1, 2010, 9:03:01 AM9/1/10
to
Alex McDonald <bl...@rivadpm.com> writes:
>Again, as there is the opportunity for change, can the restriction
>that only values be declared be relaxed? In particular, variables
>(accessed via @ !) would be useful, particularly for Forths that
>interface with the underlying OS, where local variables allow much
>more flexible solutions. I see possible support for an <x>: syntax; is
>it anticipated that something along the lines of var: ?

No, the : is for (value-flavoured) types: F: for floats, D: for
doubles. E.g.: {: n1 F: r1 n2 -- F: r3 :}.

There are (at least) two existing approaches that give you locals with
an address:

1) Gforth's variable-flavoured locals, which are indicated with a type
word ending in a "^": W^ for cells, F^ for floats, etc. This feature
has been in Gforth for 16 years, but I have used it only once or so,
and I am not aware of other users. So I am not at all convinced that
we need to standardize such a feature.

2) MPE's Forth systems support local buffers of arbitrary size, for
which you get the address. This subsumes Gforth's feature: E.g., if
you want a variable-flavoured cell-sized local, you can ask for a
cell-sized local buffer. Stephen originally proposed this for
standardization, but the proposed syntax drew too much fire, so he
retracted that part.

>\ should be eliminated in the new syntax

It's not proposed for standardization, only reserved so you can keep
it for your legacy users.

Alex McDonald

unread,
Sep 1, 2010, 5:15:20 PM9/1/10
to
On 1 Sep, 00:12, George Hubert <georgeahub...@yahoo.co.uk> wrote:
> On Aug 31, 10:48 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
>
>
>
> > On Tue, 31 Aug 2010 14:05:33 -0700 (PDT), Alex McDonald
>
> > <b...@rivadpm.com> wrote:
> > >\ should be eliminated in the new syntax, especially when the
> > >reference implementation suggests that locals may span more than one
> > >line; the following
>
> > >  {: a b c \ d
> > >  e f :}
>
> > >is (at least by a human reader) ambiguously parsed as {: a b c \ e
> > >f :} due to the overloading of the comment word \.
>
> > I'm happy to remove the use of \ as it only affects Win32Forth. The
> > wording is intended to reserve \ for Win32Forth and to promote |
> > as the standard way without disenfranchising Win32Forth. However,
> > if you want to be disenfranchised, who am I to argue?

No disenfranchise required, as {: is not { .

>
> > Stephen
>
> > --
> > Stephen Pelc, stephen...@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


>
> \ is actually quite a lot in the w32f source files (especially
> in applications rather than the system itself, so I think it
> should be reserved (and | encouraged for portability although
> w32f has supported | for 7 yrs and \ is still used). Also
> having a local called \ is plain stupid: it means you can't
> use it for comments in the word and is just confusing, so
> not allowing it doesn't really do any harm.
>
> George Hubert

As {: is a new word, there is no impact by not allowing \ as a
delimiter between initialised and uninitialised locals; current \
usage can continue to be supported with a bare { . I would prefer to
see it dropped for {: with the other restrictions ( endings of : [ ^
and local names of \ | ) maintained.

Alex McDonald

unread,
Sep 1, 2010, 5:22:45 PM9/1/10
to
On 1 Sep, 00:25, "Peter Knaggs" <p...@bcs.org.uk> wrote:
> Alex McDonald wrote:
>
> > Peter Knaggs wrote:
>
> >> The following syntax for locals is proposed. The sequence:
>
> >>    {: arg1 arg2 ... | lv1 lv2 ... -- o1 o2 ... :}
>
> >> declares local arguments, local values, and dummy outputs.
>
> > Was {| ... |} or somesuch considered as a token? Neon based compilers
> > use colons to indicate methods, as in <method: object>.
>
> The notation was thrashed out at the Exeter meeting last year, although  
> the proposal was not rewritten until the Rostock workshop.  I do not  
> recall other sequences being discussed, except for [: ... :], more of  
> which below.  It should be noted that the trailing colon is used in many  
> packages for defining words (buffer: for example).  While I would be  
> willing to review the notation if suitable alternatives can be agreed, I  
> am, however, a little weary of | due to the character code ($7C or $A6)  
> problem.

I would prefer not using the colon, given its wide use elsewhere. As
the older syntax is LOCALS| | , perhaps {| and |} could be considered?
Also see Anton's note on the non-ASCIIness of $A6.


Alex McDonald

unread,
Sep 1, 2010, 5:31:55 PM9/1/10
to
On 1 Sep, 14:03, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:

> Alex McDonald <b...@rivadpm.com> writes:
> >Again, as there is the opportunity for change, can the restriction
> >that only values be declared be relaxed? In particular, variables
> >(accessed via @ !) would be useful, particularly for Forths that
> >interface with the underlying OS, where local variables allow much
> >more flexible solutions. I see possible support for an <x>: syntax; is
> >it anticipated that something along the lines of var: ?
>
> No, the : is for (value-flavoured) types: F: for floats, D: for
> doubles.  E.g.: {: n1  F: r1  n2 -- F: r3 :}.
>
> There are (at least) two existing approaches that give you locals with
> an address:
>
> 1) Gforth's variable-flavoured locals, which are indicated with a type
> word ending in a "^": W^ for cells, F^ for floats, etc.  This feature
> has been in Gforth for 16 years, but I have used it only once or so,
> and I am not aware of other users.  So I am not at all convinced that
> we need to standardize such a feature.

Noted, and a decent alternative. In general, it's only required for
some (not all) Windows calls where pointers to values -- and lots of
parameters -- are made a lot clearer by using locals.

>
> 2) MPE's Forth systems support local buffers of arbitrary size, for
> which you get the address.  This subsumes Gforth's feature: E.g., if
> you want a variable-flavoured cell-sized local, you can ask for a
> cell-sized local buffer.  Stephen originally proposed this for
> standardization, but the proposed syntax drew too much fire, so he
> retracted that part.

As does Win32Forth with

{ | buff } cell localalloc: buff

Messy.

>
> >\ should be eliminated in the new syntax
>
> It's not proposed for standardization, only reserved so you can keep
> it for your legacy users.

See my note to George Hubert. It doesn't need to be supported, and I
would rather see it eliminated.

Alex McDonald

unread,
Sep 1, 2010, 5:55:07 PM9/1/10
to
On 1 Sep, 22:15, Alex McDonald <b...@rivadpm.com> wrote:
> On 1 Sep, 00:12, George Hubert <georgeahub...@yahoo.co.uk> wrote:
>
>
>
> > On Aug 31, 10:48 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
>
> > > On Tue, 31 Aug 2010 14:05:33 -0700 (PDT), Alex McDonald
>
> > > <b...@rivadpm.com> wrote:
> > > >\ should be eliminated in the new syntax, especially when the
> > > >reference implementation suggests that locals may span more than one
> > > >line; the following
>
> > > >  {: a b c \ d
> > > >  e f :}
>
> > > >is (at least by a human reader) ambiguously parsed as {: a b c \ e
> > > >f :} due to the overloading of the comment word \.
>
> > > I'm happy to remove the use of \ as it only affects Win32Forth. The
> > > wording is intended to reserve \ for Win32Forth and to promote |
> > > as the standard way without disenfranchising Win32Forth. However,
> > > if you want to be disenfranchised, who am I to argue?
>
> No disenfranchise required, as {: is not { .
>
>
>
>
>
> > > Stephen
>
> > > --
> > > Stephen Pelc, stephen...@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-freeVFX Forth downloads

>
> > \ is actually quite a lot in the w32f source files (especially
> > in applications rather than the system itself, so I think it
> > should be reserved (and | encouraged for portability although
> > w32f has supported | for 7 yrs and \ is still used). Also
> > having a local called \ is plain stupid: it means you can't
> > use it for comments in the word and is just confusing, so
> > not allowing it doesn't really do any harm.
>
> > George Hubert
>
> As {: is a new word, there is no impact by not allowing \ as a
> delimiter between initialised and uninitialised locals; current \
> usage can continue to be supported with a bare { . I would prefer to
> see it dropped for {: with the other restrictions ( endings of : [ ^
> and local names of \ | ) maintained.

Given that endings : [ ^ are disallowed, can the specification also be
updated to clearly state that : [ ^ as bare characters for local names
are either allowed or disallowed?

Brad

unread,
Sep 2, 2010, 11:04:03 AM9/2/10
to
On Sep 1, 6:03 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

>
> No, the : is for (value-flavoured) types: F: for floats, D: for
> doubles.  E.g.: {: n1  F: r1  n2 -- F: r3 :}.

I like it. How many Forths support typed locals like this?

-Brad

Andreas

unread,
Sep 2, 2010, 12:12:18 PM9/2/10
to
schrieb Brad:

If personal tastes are of concern, then I may throw in that I detest the
proposal altogether, regardless of minor variants. However "it's a free
country" and I do not try to convince anybody.

The reason is the completely unusual and confusing (to many newcomers)
mix of commands and notations within one seemingly homogenous
syntactical block. In
{: i1 i2 | t1 t2 -- o1 o2 o3 :}
everything is discarded between -- and :}. Humph!

No output locals o1 to o3 will be created and thus cannot be used to
assign values to them as in:
i1 t1 * to o1
Humph again.

And any 'normal' human would expect that the program itself would care
for arranging o1 o2 o3 automatically on the stack when the word is
finished. But no. Humph again.

However 'old school Forthers' seem to be so used to it, that they do not
see the 'ugliness' anymore.

Andreas


Andrew Haley

unread,
Sep 2, 2010, 1:13:19 PM9/2/10
to
Andreas <a....@nospam.org> wrote:
> schrieb Brad:
>> On Sep 1, 6:03 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
>> wrote:
>>>
>>> No, the : is for (value-flavoured) types: F: for floats, D: for
>>> doubles. E.g.: {: n1 F: r1 n2 -- F: r3 :}.
>>
>> I like it. How many Forths support typed locals like this?
>
> If personal tastes are of concern, then I may throw in that I detest the
> proposal altogether, regardless of minor variants. However "it's a free
> country" and I do not try to convince anybody.
>
> The reason is the completely unusual and confusing (to many newcomers)
> mix of commands and notations within one seemingly homogenous
> syntactical block. In
> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
> everything is discarded between -- and :}. Humph!

Yes, you are absolutely right, and others have complained about this,
long and loud. It doesn't fit with Forth at all well.

> However 'old school Forthers' seem to be so used to it, that they do
> not see the 'ugliness' anymore.

That's true, to some extent. There's a lot of existing code that uses
this horrible notation. That's the only excuse for it, but it is
quite a good excuse: people have been using it for a long while with
success.

Andrew.

Andreas

unread,
Sep 2, 2010, 2:10:52 PM9/2/10
to

Many many more have _not_ used it.

Doug Hoffman

unread,
Sep 2, 2010, 2:26:50 PM9/2/10
to
On 9/2/10 12:12 PM, Andreas wrote:
> schrieb Brad:
>> On Sep 1, 6:03 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
>> wrote:
>>>
>>> No, the : is for (value-flavoured) types: F: for floats, D: for
>>> doubles. E.g.: {: n1 F: r1 n2 -- F: r3 :}.
>>
>> I like it. How many Forths support typed locals like this?
>>
>> -Brad
>
> If personal tastes are of concern, then I may throw in that I detest the
> proposal altogether, regardless of minor variants. However "it's a free
> country" and I do not try to convince anybody.
>
> The reason is the completely unusual and confusing (to many newcomers)
> mix of commands and notations within one seemingly homogenous
> syntactical block. In
> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
> everything is discarded between -- and :}. Humph!

Perhaps it would help to think about it differently.

Consider the stack diagram for the word foo below:

: foo ( i1 i2 -- o1 o2 o3 )
...
;

The entire stack diagram is discarded.

Now change it slightly:

: foo' { i1 i2 -- o1 o2 o3 }
...
;

In foo' all we have done is add the named input parameters i1 and i2.
Further, we keep the familiar stack diagram notation.

Yes, the | separator is the most different. But with some use it
quickly becomes familiar and a very convenient way to declare local
variables.

> No output locals o1 to o3 will be created and thus cannot be used to
> assign values to them as in:
> i1 t1 * to o1
> Humph again.

It's just a stack comment as in foo. As in foo, we don't want it to
create anything.

> And any 'normal' human would expect that the program itself would care
> for arranging o1 o2 o3 automatically on the stack when the word is
> finished. But no. Humph again.

Ouch. That would be far too much automation for my tastes.

> However 'old school Forthers' seem to be so used to it, that they do not
> see the 'ugliness' anymore.

I thought old school Forthers preferred LOCALS| ... | or better yet no
locals at all! :-)

-Doug

Marcel Hendrix

unread,
Sep 2, 2010, 3:11:25 PM9/2/10
to
Brad <hwf...@gmail.com> writes Re: RfD: Enhanced local variable syntax (v6)

In iForth:
LOCALS| or LOCAL ( cell )
DLOCALS| or DLOCAL ( double cell )
FLOCALS| or FLOCAL ( 80 bit float )
DFLOCALS| or DFLOCAL ( 64 bit float )
ZLOCALS| or ZLOCAL ( complex double float )

You are allowed to take the address of any local ( 'OF local ), which allows
you to treat any LOCAL or VALUE as a VARIABLE :
3 VALUE ape
: test 'OF ape LOCAL a 2 a ! ;
ape .
test ape .

Other commands for locals are the usual TO +TO -TO 0TO CLEAR SIZEOF /OF

-marcel

Anton Ertl

unread,
Sep 3, 2010, 3:07:03 AM9/3/10
to
Doug Hoffman <glid...@gmail.com> writes:
>Yes, the | separator is the most different. But with some use it
>quickly becomes familiar and a very convenient way to declare local
>variables.

That part is mostly implemented to cover up the missing support for
more than one locals definition in a colon definition. Example:

: store-single { item -- }
item item-stack @ { stack }
store-optimization @ in-part @ 0= and item same-as-in? and
item item-in-index stack state-in stack-reg \ in reg/mem
item item-out-index stack state-out stack-reg = and \ out reg/mem
0= if
item really-store-single cr
endif ;

Here two locals are defined, ITEM and STACK, each in a separate
definition. Now, if a Forth system does not support multiple local
definitions, a way to get the same result is to write this as follows:

: store-single { item | stack -- }
item item-stack @ to stack
store-optimization @ in-part @ 0= and item same-as-in? and
item item-in-index stack state-in stack-reg \ in reg/mem
item item-out-index stack state-out stack-reg = and \ out reg/mem
0= if
item really-store-single cr
endif ;

Since Gforth supports multiple locals definitions, there has never
been the need to implement the | part of this proposal.

Anton Ertl

unread,
Sep 3, 2010, 3:52:03 AM9/3/10
to
Andreas <a....@nospam.org> writes:
>The reason is the completely unusual and confusing (to many newcomers)
>mix of commands and notations within one seemingly homogenous
>syntactical block. In
>{: i1 i2 | t1 t2 -- o1 o2 o3 :}
>everything is discarded between -- and :}. Humph!
>
>No output locals o1 to o3 will be created and thus cannot be used to
>assign values to them as in:
>i1 t1 * to o1
>Humph again.

That's the same complaint.

>And any 'normal' human would expect that the program itself would care
>for arranging o1 o2 o3 automatically on the stack when the word is
>finished. But no. Humph again.

And the same complaint again.

So you would prefer it if instead of

: unused-stack-items { stack -- n-in n-out }
\ n-in are the stack items in state-in not used by prim
\ n-out are the stack items in state-out not written by prim
stack state-in stack-state-items stack stack-in @ - 0 max
stack state-out stack-state-items stack stack-out @ - 0 max ;

I would have to write:

: unused-stack-items { stack -- n-in n-out }
\ n-in are the stack items in state-in not used by prim
\ n-out are the stack items in state-out not written by prim
stack state-in stack-state-items stack stack-in @ - 0 max to n-in
stack state-out stack-state-items stack stack-out @ - 0 max to n-out ;

This is just an example, but in my experience, if locals worked as you
prefer, in most colon defs that produce on-stack results the code
would just become longer and harder to read and write.

Given how much Forth systems are prone to variations, it is remarkable
that the variant you prefer is not implemented in any system (that I
know of). Maybe there's a technical reason for that.

Stephen Pelc

unread,
Sep 3, 2010, 5:04:54 AM9/3/10
to
On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}

>There's a lot of existing code that uses


>this horrible notation. That's the only excuse for it, but it is
>quite a good excuse: people have been using it for a long while with
>success.

In Forth shops that *demand* a stack comment for every word,
the benefit of this notation should be obvious. The notation
was designed to be convenient, even if some form of purity
was sacrificed.

Yes, there's some complexity in the parsing. Yes, it requires
care in the code generation. Yes, it's pragmatic. In every
Forth system that provides this horrible notation and the
LOCALS| notation, this horrible notation is used far more
than LOCALS|.

Application programmers like this horrible notation.
Beauty is in the eye of the beholder.
Elegance is for tailors.

Stephen

--
Stephen Pelc, steph...@mpeforth.com

Andrew Haley

unread,
Sep 3, 2010, 5:32:48 AM9/3/10
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
> <andr...@littlepinkcloud.invalid> wrote:
>
>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>
>>There's a lot of existing code that uses this horrible notation.
>>That's the only excuse for it, but it is quite a good excuse: people
>>have been using it for a long while with success.
>
> In Forth shops that *demand* a stack comment for every word,
> the benefit of this notation should be obvious.

Well, I dunno. All my professional Forth experience was in shops that
demand a stack comment for every word, and it's not obvious to me.
The problem here, surely, is that the declaration of locals is being
forced to do something it shouldn't do: act as a stack comment. And
also, if you want one local then this form encourages you to put other
arguments in locals too.

> The notation was designed to be convenient, even if some form of
> purity was sacrificed.

Is this your design, then?

> Yes, there's some complexity in the parsing. Yes, it requires
> care in the code generation. Yes, it's pragmatic. In every
> Forth system that provides this horrible notation and the
> LOCALS| notation, this horrible notation is used far more
> than LOCALS|.

No doubt, if that's the only choice you get.

> Application programmers like this horrible notation.

Some do. I don't think you can claim more than that.

Andrew.

Doug Hoffman

unread,
Sep 3, 2010, 5:46:46 AM9/3/10
to
On 9/3/10 3:07 AM, Anton Ertl wrote:
> Doug Hoffman<glid...@gmail.com> writes:
>> Yes, the | separator is the most different. But with some use it
>> quickly becomes familiar and a very convenient way to declare local
>> variables.
>
> That part is mostly implemented to cover up the missing support for
> more than one locals definition in a colon definition. Example:
>
> : store-single { item -- }
> item item-stack @ { stack }
> store-optimization @ in-part @ 0= and item same-as-in? and
> item item-in-index stack state-in stack-reg \ in reg/mem
> item item-out-index stack state-out stack-reg = and \ out reg/mem
> 0= if
> item really-store-single cr
> endif ;
>
> Here two locals are defined, ITEM and STACK, each in a separate
> definition.

I like that for two reasons: 1) The stack comment becomes more
conventional looking. 2) The local variable STACK is declared and
initialized in one step whereas with | STACK is not initialized when
declared ( not even to zero, it is unknown until explicitly initialized
with TO ).

Some may contend that all locals should be declared in one place and at
the beginning of the colon definition. But I would have no problem with
multiple definitions as in Gforth.

-Doug

Alex McDonald

unread,
Sep 3, 2010, 5:57:49 AM9/3/10
to
On 3 Sep, 08:07, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:

> Doug Hoffman <glide...@gmail.com> writes:
> >Yes, the | separator is the most different.  But with some use it
> >quickly becomes familiar and a very convenient way to declare local
> >variables.
>
> That part is mostly implemented to cover up the missing support for
> more than one locals definition in a colon definition.  Example:
>
> : store-single { item -- }
>     item item-stack @ { stack }
>     store-optimization @ in-part @ 0= and item same-as-in? and
>     item item-in-index  stack state-in  stack-reg       \  in reg/mem
>     item item-out-index stack state-out stack-reg = and \ out reg/mem
>     0= if
>         item really-store-single cr
>     endif ;
>

That would suggest

item item-stack @ value stack

would be better localised inside a colon definition by a local word;

: ... item item-stack local stack ... ;

It has the benefit of consistency with value, variable and so on; and
it doesn't have the inconsistent parsing required by the {: syntax.
Inconsistent from the simplicity of the rest of the compiler, that is,
where a token is either a number or it's compiled/executed and, as in
the case of value, does its own one token parsing. It would lend
itself to variants such as flocal, localvar and so on without the need
for an X: or Y^ type decoration for a local name. I do recognize that

: ... local x local y ... ;

initialises the locals in the order so disliked by those that use
{ over LOCALS|. There may be other issues. What are they?

This is not intended as a criticism of the proposal, but as a
discussion point, btw.

Alex McDonald

unread,
Sep 3, 2010, 5:59:27 AM9/3/10
to
On 3 Sep, 10:57, Alex McDonald <b...@rivadpm.com> wrote:
> On 3 Sep, 08:07, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:
>
>
>
> > Doug Hoffman <glide...@gmail.com> writes:
> > >Yes, the | separator is the most different.  But with some use it
> > >quickly becomes familiar and a very convenient way to declare local
> > >variables.
>
> > That part is mostly implemented to cover up the missing support for
> > more than one locals definition in a colon definition.  Example:
>
> > : store-single { item -- }
> >     item item-stack @ { stack }
> >     store-optimization @ in-part @ 0= and item same-as-in? and
> >     item item-in-index  stack state-in  stack-reg       \  in reg/mem
> >     item item-out-index stack state-out stack-reg = and \ out reg/mem
> >     0= if
> >         item really-store-single cr
> >     endif ;
>
> That would suggest
>
> item item-stack @ value stack
>
> would be better localised inside a colon definition by a local word;
>
> : ... item item-stack local stack ... ;

Missing @, please assume it.

Doug Hoffman

unread,
Sep 3, 2010, 6:12:12 AM9/3/10
to
On 9/3/10 5:32 AM, Andrew Haley wrote:
> Stephen Pelc<steph...@mpeforth.com> wrote:
>> On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
>> <andr...@littlepinkcloud.invalid> wrote:
>>
>>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>>
>>> There's a lot of existing code that uses this horrible notation.
>>> That's the only excuse for it, but it is quite a good excuse: people
>>> have been using it for a long while with success.
>>
>> In Forth shops that *demand* a stack comment for every word,
>> the benefit of this notation should be obvious.
>
> Well, I dunno. All my professional Forth experience was in shops that
> demand a stack comment for every word, and it's not obvious to me.
> The problem here, surely, is that the declaration of locals is being
> forced to do something it shouldn't do: act as a stack comment.

Nothing about the proposal forces {: ... :} to be a stack comment. One
is free to write it differently if desired. For example:

: bar ( i1 i2 -- o1 o2 o3 )
{: i1 i2 | t1 t2 :}
...


> And
> also, if you want one local then this form encourages you to put other
> arguments in locals too.

That's debatable. Just use the form as in bar and only pull off the
number of locals you want. Really not much different from LOCALS| in
that respect.


>> The notation was designed to be convenient, even if some form of
>> purity was sacrificed.
>
> Is this your design, then?

I believe Charles Duff was the first to use it. In Neon in 1984. He
used the form { a1 a2 \ l1 l2 -- o1 o2 }.

-Doug

Andrew Haley

unread,
Sep 3, 2010, 7:33:06 AM9/3/10
to
Doug Hoffman <glid...@gmail.com> wrote:
> On 9/3/10 5:32 AM, Andrew Haley wrote:
>> Stephen Pelc<steph...@mpeforth.com> wrote:
>>> On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
>>> <andr...@littlepinkcloud.invalid> wrote:
>>>
>>>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>>>
>>>> There's a lot of existing code that uses this horrible notation.
>>>> That's the only excuse for it, but it is quite a good excuse: people
>>>> have been using it for a long while with success.
>>>
>>> In Forth shops that *demand* a stack comment for every word,
>>> the benefit of this notation should be obvious.
>>
>> Well, I dunno. All my professional Forth experience was in shops that
>> demand a stack comment for every word, and it's not obvious to me.
>> The problem here, surely, is that the declaration of locals is being
>> forced to do something it shouldn't do: act as a stack comment.
>
> Nothing about the proposal forces {: ... :} to be a stack comment.

Well alright, but the form at least strongly encourages it.

> One is free to write it differently if desired. For example:
>
> : bar ( i1 i2 -- o1 o2 o3 )
> {: i1 i2 | t1 t2 :}
> ...
>
>
>> And also, if you want one local then this form encourages you to
>> put other arguments in locals too.
>
> That's debatable. Just use the form as in bar and only pull off the
> number of locals you want.

Of course, someone with good taste can ignore it, but that's not the
point. The "-- a b" strongly encourages the use of the declaration as
a stack comment, and that strongly encourages people to put all the
args in locals instead of using the stack.

> Really not much different from LOCALS| in that respect.

Yes it is, because LOCALS| cannot act as a stack comment.

>>> The notation was designed to be convenient, even if some form of
>>> purity was sacrificed.
>>
>> Is this your design, then?
>
> I believe Charles Duff was the first to use it. In Neon in 1984. He
> used the form { a1 a2 \ l1 l2 -- o1 o2 }.

Interesting. I was wondering why Steve was so strongly defending it.

Andrew.

Anton Ertl

unread,
Sep 3, 2010, 8:19:38 AM9/3/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Stephen Pelc <steph...@mpeforth.com> wrote:
>> On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
>> <andr...@littlepinkcloud.invalid> wrote:
>>
>>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>>
>>>There's a lot of existing code that uses this horrible notation.
>>>That's the only excuse for it, but it is quite a good excuse: people
>>>have been using it for a long while with success.
>>
>> In Forth shops that *demand* a stack comment for every word,
>> the benefit of this notation should be obvious.
>
>Well, I dunno. All my professional Forth experience was in shops that
>demand a stack comment for every word, and it's not obvious to me.
>The problem here, surely, is that the declaration of locals is being
>forced to do something it shouldn't do: act as a stack comment.

No, it is not forced to do that, it is used to do that. If you as a
programmer prefer to write

: foo ( i1 i2 -- o1 o2 o3 )
{: i1 i2 | t1 t2 :}
... ;

instead of

: foo {: i1 i2 | t1 t2 -- o1 o2 o3 :}

the notation supports that usage just fine.

>And
>also, if you want one local then this form encourages you to put other
>arguments in locals too.

Yes. But you can use the other form if you want to avoid that.

However, in my experience, mixing words that define the inputs as
locals with words that don't is already confusing enough. Defining
only some inputs as local might be even worse; or maybe not: I did not
find extra local definitions confusing, so maybe a separate input
local definition is ok, too.

>> The notation was designed to be convenient, even if some form of
>> purity was sacrificed.
>
>Is this your design, then?

The {: ... :} instead of { ... } came out of a discussion between
Stephen Pelc And Leon Wagner. The rest has already been described in

@Article{hayes92,
author = "John R. Hayes",
title = "User-Defined Local Variable Syntax with {ANS Forth}",
journal = sigforth,
year = "1992",
volume = "4",
number = "2",
OPTpages = "19, 20, 26",
annote = "Shows how to define a nice locals syntax using the ANS
Forth locals wordset."
}

IIRC Hayes did not refer to one of MPE's systems as the source of this
notation.

Anton Ertl

unread,
Sep 3, 2010, 8:39:51 AM9/3/10
to
Alex McDonald <bl...@rivadpm.com> writes:
>On 3 Sep, 08:07, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:
>> Doug Hoffman <glide...@gmail.com> writes:
>> >Yes, the | separator is the most different. =A0But with some use it

>> >quickly becomes familiar and a very convenient way to declare local
>> >variables.
>>
>> That part is mostly implemented to cover up the missing support for
>> more than one locals definition in a colon definition. =A0Example:

[Here's the original definition again instead of the mangled version
posted by Alex:]


: store-single { item -- }
item item-stack @ { stack }
store-optimization @ in-part @ 0= and item same-as-in? and
item item-in-index stack state-in stack-reg \ in reg/mem
item item-out-index stack state-out stack-reg = and \ out reg/mem
0= if
item really-store-single cr
endif ;

>That would suggest
>
>item item-stack @ value stack
>
>would be better localised inside a colon definition by a local word;
>
>: ... item item-stack local stack ... ;

You mean, you would prefer

: store-single { item -- }
item item-stack @ local stack


store-optimization @ in-part @ 0= and item same-as-in? and
item item-in-index stack state-in stack-reg \ in reg/mem
item item-out-index stack state-out stack-reg = and \ out reg/mem
0= if
item really-store-single cr
endif ;

?

>I do recognize that
>
>: ... local x local y ... ;
>
>initialises the locals in the order so disliked by those that use
>{ over LOCALS|. There may be other issues. What are they?

1) In Gforth on a 32-bit system, { x y } requires 8 bytes on the
locals stack, whereas { y } { x } (and, if we implemented it, LOCAL Y
LOCAL X) requires 16 bytes (the locals stack is always kept maximally
aligned). This could be fixed, but costs additional compiler
complexity.

2) I find the former form easier to read than the latter form: It's
easier to find the definition of the local.

Andrew Haley

unread,
Sep 3, 2010, 9:41:16 AM9/3/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Stephen Pelc <steph...@mpeforth.com> wrote:
>>> On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
>>> <andr...@littlepinkcloud.invalid> wrote:
>>>
>>>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>>>
>>>>There's a lot of existing code that uses this horrible notation.
>>>>That's the only excuse for it, but it is quite a good excuse: people
>>>>have been using it for a long while with success.
>>>
>>> In Forth shops that *demand* a stack comment for every word,
>>> the benefit of this notation should be obvious.
>>
>>Well, I dunno. All my professional Forth experience was in shops that
>>demand a stack comment for every word, and it's not obvious to me.
>>The problem here, surely, is that the declaration of locals is being
>>forced to do something it shouldn't do: act as a stack comment.
>
> No, it is not forced to do that, it is used to do that.

That's really a distinction without a difference. If you've got a
notation that looks crap if you don't use it in some particuar way,
then that notation is effectively forced to be used in that way.

And it really does look crap:

> : foo ( i1 i2 -- o1 o2 o3 )
> {: i1 i2 | t1 t2 :}

IMO, YMMV, etc, etc.

Andrew.

Anton Ertl

unread,
Sep 3, 2010, 10:28:21 AM9/3/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>>Stephen Pelc <steph...@mpeforth.com> wrote:
>>>> On Thu, 02 Sep 2010 12:13:19 -0500, Andrew Haley
>>>> <andr...@littlepinkcloud.invalid> wrote:
>>>>
>>>>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
...

>That's really a distinction without a difference. If you've got a
>notation that looks crap if you don't use it in some particuar way,
>then that notation is effectively forced to be used in that way.
>
>And it really does look crap:
>
>> : foo ( i1 i2 -- o1 o2 o3 )
>> {: i1 i2 | t1 t2 :}
>
>IMO, YMMV, etc, etc.

Obviously. I prefer the first notation, because I don't like
redundancy, so any notation that separates the locals definition(s)
will be unsatisfactory. The other two approaches that have been
suggested would look as follows:

: foo ( i1 i2 -- o1 o2 o3 )

0 0 locals| t2 t1 i2 i1 |

and

: foo ( i1 i2 -- o1 o2 o3 )

local i2 local i1 0 local t2 0 local t1

These look much worse.

Finally, there's also the option of not using locals.

Alex McDonald

unread,
Sep 3, 2010, 10:42:15 AM9/3/10
to
On 3 Sep, 13:39, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:

: store-single
local item

Stephen Pelc

unread,
Sep 3, 2010, 11:21:52 AM9/3/10
to
On Fri, 03 Sep 2010 04:32:48 -0500, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>> The notation was designed to be convenient, even if some form of
>> purity was sacrificed.
>
>Is this your design, then?

No, we just implemented in back in the 1980s and have used it ever
since.

>> Yes, there's some complexity in the parsing. Yes, it requires
>> care in the code generation. Yes, it's pragmatic. In every
>> Forth system that provides this horrible notation and the
>> LOCALS| notation, this horrible notation is used far more
>> than LOCALS|.
>
>No doubt, if that's the only choice you get.

As I pointed out, I was talking about systems with *both*
LOCALS| and the proposed notation.

Andrew Haley

unread,
Sep 3, 2010, 12:25:17 PM9/3/10
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Fri, 03 Sep 2010 04:32:48 -0500, Andrew Haley
> <andr...@littlepinkcloud.invalid> wrote:
>
>>> The notation was designed to be convenient, even if some form of
>>> purity was sacrificed.
>>
>>Is this your design, then?
>
> No, we just implemented in back in the 1980s and have used it ever
> since.
>
>>> Yes, there's some complexity in the parsing. Yes, it requires
>>> care in the code generation. Yes, it's pragmatic. In every
>>> Forth system that provides this horrible notation and the
>>> LOCALS| notation, this horrible notation is used far more
>>> than LOCALS|.
>>
>>No doubt, if that's the only choice you get.
>
> As I pointed out, I was talking about systems with *both*
> LOCALS| and the proposed notation.

That was clear. I agree that if the only choice you get is between
the proposed notation and LOCALS| , then the proposed notation is more
likely to be used. But being better than LOCALS| is not a very high
bar.

Andrew.

Andreas

unread,
Sep 3, 2010, 12:46:00 PM9/3/10
to
Anton Ertl wrote:
> Andreas<a....@nospam.org> writes:
>> The reason is the completely unusual and confusing (to many newcomers)
>> mix of commands and notations within one seemingly homogenous
>> syntactical block. In
>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>> everything is discarded between -- and :}. Humph!
>>
>> No output locals o1 to o3 will be created and thus cannot be used to
>> assign values to them as in:
>> i1 t1 * to o1
>> Humph again.
>
> That's the same complaint.

I do not complain. It would mean I had expectations for some progress in
Forth, but I don't. I just like hand axes, that't all. :-)


> Given how much Forth systems are prone to variations, it is remarkable
> that the variant you prefer is not implemented in any system (that I
> know of). Maybe there's a technical reason for that.

I belong to those rare un-Forthy guys who believe that a compiler should
serve the human, not the other way round.

Stephen Pelc

unread,
Sep 3, 2010, 12:57:41 PM9/3/10
to

Sure. But there has been no notation (other than the current proposal)
that has gained any traction amongst users and systems.

I understand the view that locals are intrinsically a "bad thing" in
Forth. I come from a perspective that I would prefer not to use them,
but that for certain types of programming, locals make life much
easier (faster to program or faster/shorter code).

When I do use locals, I like the proposed notation better than
anything else I've seen. Since the proposed notation has in excess
of 25 years practice and several systems support it, it's a good
candidate for standardisation.

Andrew Haley

unread,
Sep 3, 2010, 1:17:32 PM9/3/10
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Fri, 03 Sep 2010 11:25:17 -0500, Andrew Haley
> <andr...@littlepinkcloud.invalid> wrote:
>
>>That was clear. I agree that if the only choice you get is between
>>the proposed notation and LOCALS| , then the proposed notation is more
>>likely to be used. But being better than LOCALS| is not a very high
>>bar.
>
> Sure. But there has been no notation (other than the current proposal)
> that has gained any traction amongst users and systems.
>
> I understand the view that locals are intrinsically a "bad thing" in
> Forth. I come from a perspective that I would prefer not to use them,
> but that for certain types of programming, locals make life much
> easier (faster to program or faster/shorter code).
>
> When I do use locals, I like the proposed notation better than
> anything else I've seen. Since the proposed notation has in excess
> of 25 years practice and several systems support it, it's a good
> candidate for standardisation.

I agree, it is. However, I was responding not to whether it should be
standardized, but to Andreas' point that -- paraphrasing --it's a
mess.

This is an RFD. "People have been using it for years" is not a slam-
dunk reply to criticism of the utter awfulness of this syntax.

Using this form will certainly lead to people using more locals,
because if you need one single local, the only thing you can do
(that's not really ugly) is mechanically replace the stack comment
with a locals declaration. Then all your args are in locals.

And, dammit, I wasn't going to reply to this because we've been around
the argument before, but Andreas raised the point, and I agree with
him.

Andrew.

Anton Ertl

unread,
Sep 3, 2010, 1:50:46 PM9/3/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>And, dammit, I wasn't going to reply to this because we've been around
>the argument before, but Andreas raised the point, and I agree with
>him.

I don't think you do, even though the first part of what he wrote
sounded like an argument from you.

If I understand him correctly, he wants this kind of locals definition
to also define the outputs (as uninitialized value-flavoured locals);
then the programmer would have to put values into these locals, and at
the end of the definition, these locals would be pushed on the stack.

Do you really agree with him?

Andrew Haley

unread,
Sep 3, 2010, 2:05:29 PM9/3/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>And, dammit, I wasn't going to reply to this because we've been around
>>the argument before, but Andreas raised the point, and I agree with
>>him.
>
> I don't think you do, even though the first part of what he wrote
> sounded like an argument from you.
>
> If I understand him correctly, he wants this kind of locals
> definition to also define the outputs (as uninitialized
> value-flavoured locals); then the programmer would have to put
> values into these locals, and at the end of the definition, these
> locals would be pushed on the stack.

I agreed with the part I quoted:

Andreas <a....@nospam.org> wrote:

> The reason is the completely unusual and confusing (to many newcomers)
> mix of commands and notations within one seemingly homogenous
> syntactical block. In

> {: i1 i2 | t1 t2 -- o1 o2 o3 :}

> everything is discarded between -- and :}. Humph!

Andrew.

Andreas

unread,
Sep 4, 2010, 2:31:58 AM9/4/10
to
Anton Ertl wrote:
> Andrew Haley<andr...@littlepinkcloud.invalid> writes:
>> And, dammit, I wasn't going to reply to this because we've been around
>> the argument before, but Andreas raised the point, and I agree with
>> him.
>
> I don't think you do, even though the first part of what he wrote
> sounded like an argument from you.
>
> If I understand him correctly, he wants this kind of locals definition
> to also define the outputs (as uninitialized value-flavoured locals);
> then the programmer would have to put values into these locals, and at
> the end of the definition, these locals would be pushed on the stack.

I did not say that.

Just that 'one' would expect to have locals also really available when
you declare them, including output locals.

And any halfway decent compiler would generate more efficient code than
you are suggesting, eg. by using processor registers and direct stack
cell addressing.

Andreas

Andreas

unread,
Sep 4, 2010, 11:24:46 AM9/4/10
to

Post scriptum:

: ROT ( for fun but no joke )
{: a b c -- b c a :} ;

This sort of halfwit intelligent compiler is not hard to write (even I
did it long time ago, and I do not consider myself a professional).
Postprocessed by modern optimizers like in MPE's VFX Forth, the
resulting opcode should be comparable to handcrafted assembler.

Andreas

Doug Hoffman

unread,
Sep 5, 2010, 7:43:52 AM9/5/10
to

: bar1 ( ... )
... locals| a |
...
;

: bar2 ( ... )
... { a }
...
;

-Doug

Andrew Haley

unread,
Sep 5, 2010, 9:00:48 AM9/5/10
to

What point are you trying to make?

Andrew.

m_l_g3

unread,
Sep 5, 2010, 5:51:30 PM9/5/10
to
Doug Hoffman wrote:
> On 9/2/10 12:12 PM, Andreas wrote:
> > schrieb Brad:
> >> On Sep 1, 6:03 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
> >> wrote:
> >>>
> >>> No, the : is for (value-flavoured) types: F: for floats, D: for
> >>> doubles. E.g.: {: n1 F: r1 n2 -- F: r3 :}.
> >>
> >> I like it. How many Forths support typed locals like this?
> >>
> >> -Brad
> >
> > If personal tastes are of concern, then I may throw in that I detest the
> > proposal altogether, regardless of minor variants. However "it's a free
> > country" and I do not try to convince anybody.

> >
> > The reason is the completely unusual and confusing (to many newcomers)
> > mix of commands and notations within one seemingly homogenous
> > syntactical block. In
> > {: i1 i2 | t1 t2 -- o1 o2 o3 :}
> > everything is discarded between -- and :}. Humph!

What I really dislike is that the proposed syntax implicitly
requires one to assign *all* input parameters to locals.

For example,

: udup { x } dup x ;

Something like

: udup { x -- y y x } dup x ;

would be really confusing.

> > And any 'normal' human would expect that the program itself would care
> > for arranging o1 o2 o3 automatically on the stack when the word is
> > finished. But no. Humph again.

If we required that the locals list consumes *all* arguments passed
to a word, we could require also that at least the number of output
values is matched with the number of items after -- .
Unfortunately, given existence of the type ( x1 .. xn n ),
requiring something like that is problematic.

> Ouch. That would be far too much automation for my tastes.
>
> > However 'old school Forthers' seem to be so used to it, that they do not
> > see the 'ugliness' anymore.
>
> I thought old school Forthers preferred LOCALS| ... | or better yet no
> locals at all! :-)

Local variables are evil. We should be using the term "named values".
Assignment may be expressed in terms of playing with the scope:
in : tt { x } x 1+ { x } x ; there are two x'es, each one created by
the
corresponding { x } --- at least, from the theoretical viewpoint.


---
And the rest of the world lives in the world of reusable components...


Doug Hoffman

unread,
Sep 6, 2010, 5:44:55 AM9/6/10
to
On 9/5/10 9:00 AM, Andrew Haley wrote:
> Doug Hoffman<glid...@gmail.com> wrote:
>> On 9/3/10 7:33 AM, Andrew Haley wrote:
>>> Doug Hoffman<glid...@gmail.com> wrote:
>
>>>>> And also, if you want one local then this form encourages you to
>>>>> put other arguments in locals too.

>>>>


>>>> That's debatable. Just use the form as in bar and only pull off the
>>>> number of locals you want.
>>>
>>> Of course, someone with good taste can ignore it, but that's not the
>>> point. The "-- a b" strongly encourages the use of the declaration as
>>> a stack comment, and that strongly encourages people to put all the
>>> args in locals instead of using the stack.
>>>
>>>> Really not much different from LOCALS| in that respect.
>>>
>>> Yes it is, because LOCALS| cannot act as a stack comment.
>>
>> : bar1 ( ... )
>> ... locals| a |
>> ...
>> ;
>>
>> : bar2 ( ... )
>> ... { a }
>> ...
>> ;
>
> What point are you trying to make?

That if you want one (or more) locals, using the new form is really not
much different from LOCALS| in that respect because you need not pull
everything from the stack, and the new form need not be used as a stack
comment.

-Doug

Doug Hoffman

unread,
Sep 6, 2010, 6:01:23 AM9/6/10
to
On 9/5/10 5:51 PM, m_l_g3 wrote:
> Doug Hoffman wrote:
>> On 9/2/10 12:12 PM, Andreas wrote:
>>> schrieb Brad:
>>>> On Sep 1, 6:03 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
>>>> wrote:
>>>>>
>>>>> No, the : is for (value-flavoured) types: F: for floats, D: for
>>>>> doubles. E.g.: {: n1 F: r1 n2 -- F: r3 :}.
>>>>
>>>> I like it. How many Forths support typed locals like this?
>>>>
>>>> -Brad
>>>
>>> If personal tastes are of concern, then I may throw in that I detest the
>>> proposal altogether, regardless of minor variants. However "it's a free
>>> country" and I do not try to convince anybody.
>>>
>>> The reason is the completely unusual and confusing (to many newcomers)
>>> mix of commands and notations within one seemingly homogenous
>>> syntactical block. In
>>> {: i1 i2 | t1 t2 -- o1 o2 o3 :}
>>> everything is discarded between -- and :}. Humph!
>
> What I really dislike is that the proposed syntax implicitly
> requires one to assign *all* input parameters to locals.

It does not require that all input parameters be assigned, implicitly or
otherwise.

> For example,
>
> : udup { x } dup x ;
>
> Something like
>
> : udup { x -- y y x } dup x ;
>
> would be really confusing.

The following would be better.

: udup ( y x -- y y x )
{ x } dup x ;

functionally identical to:

: udup ( y x -- y y x )
locals| x | dup x ;


>>> And any 'normal' human would expect that the program itself would care
>>> for arranging o1 o2 o3 automatically on the stack when the word is
>>> finished. But no. Humph again.
>
> If we required that the locals list consumes *all* arguments passed
> to a word, we could require also that at least the number of output
> values is matched with the number of items after -- .
> Unfortunately, given existence of the type ( x1 .. xn n ),
> requiring something like that is problematic.
>
>> Ouch. That would be far too much automation for my tastes.
>>
>>> However 'old school Forthers' seem to be so used to it, that they do not
>>> see the 'ugliness' anymore.
>>
>> I thought old school Forthers preferred LOCALS| ... | or better yet no
>> locals at all! :-)
>
> Local variables are evil. We should be using the term "named values".

The proposal uses local arguments and local values. That's pretty clear
and descriptive, IMO.

> Assignment may be expressed in terms of playing with the scope:
> in : tt { x } x 1+ { x } x ; there are two x'es, each one created by
> the
> corresponding { x } --- at least, from the theoretical viewpoint.

Is that a proposal to modify the Enhanced local variable syntax, v6 ?

-Doug

Andrew Haley

unread,
Sep 6, 2010, 6:12:53 AM9/6/10
to

Oh, sure, but I never disputed that, so I didn't understand why you
made that posting. To be clear: there's the germ of a good idea in
here, a simple syntax that doesn't amount to much more than LOCALS| in
the right order. Get rid of the uninitialized locals part and the
comment part and it's just fine. There never was anything wrong with

{ a b c }

I don't think arguments of the form "You won't use it, so why do you
care?" are valid. Forth is a small and simple (but still very useful)
language, and that's still its most significant contribution to the
art. Every addition to the language has to make a very significant
contribution to its usefulness.

Andrew.

Doug Hoffman

unread,
Sep 6, 2010, 6:28:34 AM9/6/10
to
On 9/6/10 6:12 AM, Andrew Haley wrote:

> To be clear: there's the germ of a good idea in
> here, a simple syntax that doesn't amount to much more than LOCALS| in
> the right order. Get rid of the uninitialized locals part and the
> comment part and it's just fine. There never was anything wrong with
>
> { a b c }
>
> I don't think arguments of the form "You won't use it, so why do you
> care?" are valid.

Frequently the locals declaration *can* do double duty as a stack
comment. Frequently enough that many use it that way as well. Why
limit its usefulness to others when there is no harm and Andrew Haley
will not have to use its stack comment capability?

> Forth is a small and simple (but still very useful)
> language, and that's still its most significant contribution to the
> art. Every addition to the language has to make a very significant
> contribution to its usefulness.

Useful, simple, significant. All subjective words. The "new form"
actually isn't new at all. It has decades of use in multiple Forths.

-Doug

m_l_g3

unread,
Sep 6, 2010, 7:50:53 AM9/6/10
to
On Sep 6, 2:12 pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> Doug Hoffman <glide...@gmail.com> wrote:
> > On 9/5/10 9:00 AM, Andrew Haley wrote:
> >> Doug Hoffman<glide...@gmail.com>  wrote:

> >>> On 9/3/10 7:33 AM, Andrew Haley wrote:
> >>>> Doug Hoffman<glide...@gmail.com>   wrote:
[..]

>  To be clear: there's the germ of a good idea in
> here, a simple syntax that doesn't amount to much more than LOCALS| in
> the right order.  Get rid of the uninitialized locals part and the
> comment part and it's just fine.  There never was anything wrong with
>
>  { a b c }
>

The items below may look as questions, but they are proposals:

1.
Why don't we make { x y } work as an assignment operator?

{ x y } .... x y { y x }

2.
Why :} ?
What's wrong with just

{: x y }

and then

: { postpone {: ; immediate

for whoever wants it?

3.
The -- part inside { } is not necessary:

: SWAP { x y } -- y x
0 0 { z t }
y x ;

The only required thing is -- as a comment sign.

4.
I would propose to require that the whole { stuff }
thing fits onto a single line.

> I don't think arguments of the form "You won't use it, so why do you
> care?" are valid.  Forth is a small and simple (but still very useful)
> language, and that's still its most significant contribution to the
> art.  Every addition to the language has to make a very significant
> contribution to its usefulness.
>
> Andrew.

---
and the rest of the world lives in the world of reusable components...

Andrew Haley

unread,
Sep 6, 2010, 8:54:00 AM9/6/10
to
Doug Hoffman <glid...@gmail.com> wrote:
> On 9/6/10 6:12 AM, Andrew Haley wrote:
>
>> To be clear: there's the germ of a good idea in
>> here, a simple syntax that doesn't amount to much more than LOCALS| in
>> the right order. Get rid of the uninitialized locals part and the
>> comment part and it's just fine. There never was anything wrong with
>>
>> { a b c }
>>
>> I don't think arguments of the form "You won't use it, so why do you
>> care?" are valid.
>
> Frequently the locals declaration *can* do double duty as a stack
> comment. Frequently enough that many use it that way as well. Why
> limit its usefulness to others when there is no harm and Andrew Haley
> will not have to use its stack comment capability?

I think that one has already been asked and answered. It's bad
because it encourages people to put more things into locals, and it's
bad because it is a notation that is neither one thing nor the other:
half code and half comment. Forth doesn't much do content-free
syntax, and this is a way in which it is different from other
languages. Vive la difference.

>> Forth is a small and simple (but still very useful)
>> language, and that's still its most significant contribution to the
>> art. Every addition to the language has to make a very significant
>> contribution to its usefulness.
>
> Useful, simple, significant. All subjective words.

This entire argument is subjective, on both sides.

> The "new form" actually isn't new at all. It has decades of use in
> multiple Forths.

Yes, I know, which is why it will probably be standardized. I doubt
very much that it would be accepted if it were new.

Andrew.

Anton Ertl

unread,
Sep 6, 2010, 7:59:16 AM9/6/10
to
m_l_g3 <m_l...@yahoo.com> writes:
>What I really dislike is that the proposed syntax implicitly
>requires one to assign *all* input parameters to locals.
>
>For example,
>
>: udup { x } dup x ;
>
>Something like
>
>: udup { x -- y y x } dup x ;
>
>would be really confusing.

Sure, that would be a bad idea. The alternatives are:

: udup {: y x -- y y x :}
y y x ;

and

: udup ( y x -- y y x }
{: x :} dup x ;

and of course:

: udup ( y x -- y y x }
>r dup r> ;

: udup ( y x -- y y x }
swap dup rot ;

So, the proposed syntax does not require you to have locals for all
inputs. That's just one option.

>Assignment may be expressed in terms of playing with the scope:
>in : tt { x } x 1+ { x } x ; there are two x'es, each one created by
>the
>corresponding { x } --- at least, from the theoretical viewpoint.

That works with Gforth. But in some cases this approach is worse than
using TO, though. Consider:

: foo
... { x }
... if
... TO x
...
endif
... x ... ;

If we wanted to eliminate the TO here, we would have:

: foo
... { x0 }
... if
... { x1 }
... x1
else
x0
endif { x2 }
... x2 ... ;

[Here all the x variants have different names, to make it clearer what
refers to what x. You could also use the same name.]

I don't think that this is preferable to the variant using TO.

Anton Ertl

unread,
Sep 6, 2010, 11:22:04 AM9/6/10
to
m_l_g3 <m_l...@yahoo.com> writes:
>On Sep 6, 2:12=A0pm, Andrew Haley <andre...@littlepinkcloud.invalid>

>wrote:
>> Doug Hoffman <glide...@gmail.com> wrote:
>> > On 9/5/10 9:00 AM, Andrew Haley wrote:
>> >> Doug Hoffman<glide...@gmail.com> =A0wrote:

>> >>> On 9/3/10 7:33 AM, Andrew Haley wrote:
>> >>>> Doug Hoffman<glide...@gmail.com> =A0 wrote:
>[..]
>> =A0To be clear: there's the germ of a good idea in

>> here, a simple syntax that doesn't amount to much more than LOCALS| in
>> the right order. =A0Get rid of the uninitialized locals part and the
>> comment part and it's just fine. =A0There never was anything wrong with
>>
>> =A0{ a b c }

>>
>
>The items below may look as questions, but they are proposals:
>
>1.
>Why don't we make { x y } work as an assignment operator?
>
> { x y } .... x y { y x }

a) { x y } has been used for local definitions, and for comments, so a
conflicting use has no chance of being adopted.

b) If you mean that {: x y :} should define locals, but assign to x if
x has been defined already, that's contrary to the usual conventions
in Forth: e.g., "VALUE FOO" does not assign to FOO if FOO has been
defined already.

>2.
>Why :} ?
>What's wrong with just
>
> {: x y }

I guess the proponents liked a symmetric syntax (looks better to me,
too). It don't see a technical reason.

That being said, the reserved local names should include "}".

>4.
>I would propose to require that the whole { stuff }
>thing fits onto a single line.

Apparently you missed the following lines:

| The following ambiguous conditions exist when:
| [...]
| - the text between {: and :} extends over more than one line;

0 new messages