Hans Bezemer <
the.beez.speaks@gmail.com> writes:
On 16-04-2025 23:26, Anton Ertl wrote:
OTOH, Forth is worse suited to deal with dial-your-language-version
options: C uses separate compilation, so if the main program uses some
version of the standard, and a library uses a different version,
that's typically no problem, because they are both compiled with
different compiler calls (which may have different options).
Forth, OTOH, compiles all the sources in one compilation run, and any
choices you dial at one point tend to affect all the rest of the
compilation, even if it compiles some independently developed library.
One could dream up ways to deal with that problem, but given past
experience, I doubt such ideas would find enough support; some would
call that "WIBNI"s, while others would point out that Chuck Moore did
not bring these ideas down from the mountain.
- anton
>
I don't think so. Using K&R prototypes is significantly different from
ANSI prototypes. That must have broken quite some code - unless specific
measures were taken to allow "old format" codes as well.
They certainly were, and still are. E.g, for the following function
definition in pre-C89 style:
foo(x)
int x;
{
return bar(x);
}
gcc-12 produces some warnings:
xxx.c:1:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
1 | foo(x)
| ^~~
xxx.c: In function ‘foo’:
xxx.c:4:10: warning: implicit declaration of function ‘bar’ [-Wimplicit-function-declaration]
4 | return bar(x);
| ^~~
but it compiles the code. In the old times the calling conventions
were designed to work for undeclared functions, so the compiled code
also worked. Things like the I32LP64 mistake and newer calling
conventions were designed for programs with fully-blown prototypes, so
on newer platforms some of the old code does not work (in particular,
when passing a double or an undeclared pointer), but that's the choice
of the implementors, not due to the C standard introducing an
incompatible requirement.
restrict,
nullptr, inline, bool - the list of added keywords is endless.
The number of keywords is finite (to be exact, C23 has 59 keywords,
including 5 obsolescent keywords), which means that the number of
added keywords is finite, too.
BTW, so
is the list of deprecated keywords, like "_Bool" with was replaced by
the far less ugly "bool" in 2023.
The number of obsolescent keywords in C23 is 5. Endless?
And I don't think the argument that "Forth compiles in one go" holds up
as an argument to avoid cleaning up historical clutter. The different
versions of a "keyword" could be created as their names, followed by a
postfix of the standard, e.g. DO_79, DO_82, DO_94. Let's call 'em
"version words".
There are no keywords in Forth, which makes changes less problematic
than in C. And names can be redefined in Forth, which also makes
changes less problematic.
As for introducing changes that are so disruptive that you would then
need dial-your-standard features to provide backwards compatibility
(e.g., stuff like the Forth-83 disruptions to Forth-79, e.g., the
changes to NOT and PICK), yes, one could propose technical workarounds
for that. It's just that the Forth community and the Forth-200x will
not find a consensus for taking such measures.
E.g., consider requiring the text interpreter of Forth systems to
treat 1.0 as FP value; currently this is not standardized, but common
practice (gforth, iForth, lxf, SwiftForth, VFX) is to treat it as
equivalent to 10., i.e., a double-cell integer.
One way to keep backwards compatibility with the current common
practice would be to require having a word FORTH-2030-FP-SYNTAX (or
maybe just FORTH-2030) in every file that uses the new FP syntax
before the use of that syntax. If that word does not appear in that
file, "1.0" would still be non-standardized.
Next: "1.". If we had such declarations, we could even support "1."
(standardized as double-cell in Forth-94 and Forth-2012) as FP number.
The alternative would be to treat "1." as double-cell and 1.0 as FP
value, which IMO is even worse than requiring an "e" in every FP
value.
But back to the dial-a-standard things: I have never seen such a
proposal that limits the dialing to one file. Instead, the proposals
and existing practice is to dial for the rest of text interpretation
(or until somthing else is dialed). That would mean that previously
working files might no longer work when included after dialing the new
FP syntax. E.g., all versions of the recognizer proposal have been
along these lines, and Bernd Paysan has actually proposed allowing to
treat "1." as FP value by swapping the integer and FP recognizer in
the recognizer order, which would have exactly this effect. And Bernd
Paysan is not the only one: Among other dialing features that all are
not limited to the file, VFX supports disabling the recognition of
"1." as double, which then leads to its recognition as FP number; but
that disabling is not limited to a file, but extends to the rest of
the text interpretation.
Here's the example for VFX:
',' dp-char 1+ c! ok
1. ok F:-1
f. 1. ok
So you could try to propose a word like FORTH-2030-FP-SYNTAX, but I
expect that the reactions would be along the following lines (in the
community and in the standardization committee):
1) A number of people consider this completely unnecessary, and
actually heretical, because Chuck Moore came down from the mountain
with doubles, not floats, so that's the way it was always meant to
be. Some would argue that treating "1.0" or "1." as FP number is
proposed just to cater to C programmers, and that Forthers should
take pride in deviating from the beaten path.
2) A number of people would argue against the limitation to a specific
file because of "complexity" (meaning implementation complexity),
"WIBNI", or because Chuck Moore came down from the mountain without
that idea, and that Chuck Moore has argued against libraries, that
he has argued against saving and restoring state, and instead has
argued for always setting it. And that the common practice (e.g.,
in VFX) is to just set the state, and never
3) And if you changed your proposal to just affect the rest of text
interpretation (and include another word FORTH-2012-FP-SYNTAX or
somesuch to switch back), some people (including me) would argue
that this variant of FORTH-2030-FP-SYNTAX would break existing
code, and that introducing FORTH-2012-FP-SYNTAX is a poor and
error-prone substitute for defining FORTH-2030-FP-SYNTAX properly.
Word counters would dislike this variant because it introduces an
additional word, and the people who argue 1) would also dislike the
proposal.
The bottom line is that the proposal would probably not find a
consensus and would not be accepted by the committee. The bottom line
is:
One could dream up ways to deal with that problem, but given past
experience, I doubt such ideas would find enough support
And the bottom line of that is that proposals for incompatible changes
have little chance of being accepted.
There could be special words like [FORTH78], [ANSFORTH] - which would no
nothing but:
- Either hiding words in the dictionary that should be disabled;
- Activating words that are part of this standard;
Interestingly, Forth-79 includes a word 79-STANDARD, and Forth-83
includes a word FORTH-83, but Forth-94 and Forth-2012 do not include
such words. We had a discussion whether we should have Forth-94 and
Forth-2012 versions of environmental queries for wordsets in
Forth-2012, but the committee decided against that.
In any case, if you want to support including libraries written for a
different standard, the effect of such words should be limited to a
specific file. If the standards are incompatible and you want
libraries, and you do not provide this kind of dialing, you can take a
look at the Python 3 transition pain (or worse, what happened with
Perl6) to see what happens. The Python community has learned from
that experience not to introduce such incompatible changes again.
- Assigning the proper "version" words to trampolines or DEFERs.
That's exactly the wrong thing to do. You want to statically bind the
name to the word with the right version. E.g. if you have a Forth-83 program
forth-83
100 load ( includes a library written in Forth-79)
: foo ( ... -- ... )
... not ... ;
and the library contains
79-standard
: bar ( ... -- ... )
... not ... ;
you want the use of NOT in FOO to be statically bound to (what
Forth-94 calls) INVERT and the NOT in BAR to be statically bound to
0=; you usually don't want BAR or FOO to change its behaviour
depending on which standard is selected.
But I think maybe, just maybe the same effect could be achieved by using
wordsets.
I assume you mean wordlists. Yes, the effect of switching between the
Forth-83 NOT and the Forth-79 NOT can be achieved by having a wordlist
containing the Forth-79 words and a wordlist containing the Forth-83
words, and putting it in the search order.
So, if we compile an external library using a mix of Forth-79, ANS Forth
and Forth 2012, it could be as simple as:
>
INCLUDE a.fs
INCLUDE b.fs
[FORTH2012]
>
a.fs:
[FORTH79]
...
>
b.fs:
[ANSFORTH]
...
There is 79-STANDARD, but there is no word equivalent to [FORTH2012]
or [ANSFORTH]. So a program that contains "[FORTH2012]" without first
defining it is not Forth-2012-compliant. And a program that contains
[ANSFORTH] without first defining it is not Forth-94 compliant.
That's much like setting the radix.
BASE is one of the misfeatures of Forth, and demonstrates the
disadvantage of having a state for the rest of the text
interpretation, and the Chuck Moore approach to . Do you start every
file with DECIMAL or HEX? Looking at SwiftForth (where one might
expect the most Chuck Moore influence), I see 26 occurences of DECIMAL
and 16 occurences of HEX, and usually not before the first occurence
of an integer with several digits. As an example, the file that
contains the definition
: DECIMAL ( -- ) 10 BASE ! ;
does not contain an invocation of DECIMAL before this use of "10".
So - why couldn't this work?
As mentioned, there is no [FORTH2012] and no [ANSFORTH].
Moreover, this general approach does not work for BASE: If the next
standard required that systems start out in, say, octal, I am sure
that a lot of the existing source files would fail unless you invoked
DECIMAL before the INCLUDE. BASE only works (and only so-so) because
every sane system defaults to DECIMAL, and that does not change
between standard versions.
- anton
-- M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.htmlcomp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html New standard: https://forth-standard.org/EuroForth 2023 proceedings: http://www.euroforth.org/ef23/papers/EuroForth 2024 proceedings:
http://www.euroforth.org/ef24/papers/