Discussion:
History of CREATE...DOES> ?
(too old to reply)
dxf
2024-07-25 15:20:28 UTC
Permalink
fig-Forth has <BUILDS...DOES> (and the associated implementation with
an extra cell that points to the threaded code behind DOES>).
Forth-79 standarizes CREATE...DOES>; and a popular implementation of
that is to trampoline through the place behind DOES> to the actual
code address. Where did that implementation and CREATE..DOES> in
general come from?
My guess is that it did not come from Forth, Inc.: At the time of
Forth-79 AFAIK Forth, Inc.'s Forths were miniForth and microForth.
And given that fig-Forth started out as a port of microForth to the
6502, I doubt that Forth, Inc. used CREATE..DOES>. Also, Forth,
Inc. ignored Forth-79 (IIRC Elizabeth Rather described it as
inconsistent or some other statement that she would not have made if
Forth, Inc. had actually accepted and implemented Forth-79).
At least dxf is very well versed in historic Forth developments.
Maybe he or somebody else can answer my question: Where did the
implementation described above and CREATE..DOES> in general come from?
There's a detailed description of the origins of these in Chuck's
address "FORTH: The Last Ten Years ..." (FD V1N6. p72). They all
came from Forth Inc but mostly not Chuck. He needed help!
Anton Ertl
2024-07-26 07:13:03 UTC
Permalink
Post by dxf
There's a detailed description of the origins of these in Chuck's
address "FORTH: The Last Ten Years ..." (FD V1N6. p72).
Thanks. So Forth, Inc. did have CREATE..DOES> by 1980 (when this
article was published). My family tree says about polyForth:

\I FORTH, Inc.'s PC offering
\U http://www.forth.com/resources/evolution/evolve_3.html#3.2
1982 Implementation polyFORTH
miniFORTH begot polyFORTH \ FORTH, Inc., approx. 1980

Not sure where I have the 1982 and 1980 numbers from. According to
"The Evolution of Forth", the first edition of Starting Forth (1981)
was mostly written for polyForth, so the 1980 number looks more
plausible now.

So maybe this new CREATE..DOES> first appeared in polyForth, or maybe
in later versions of miniForth.

But CREATE...DOES> also made it into Forth-79, so it must have been
more widespread by then. In particular, Chuck Moore's description in
the article above does not seem clear enough to me for developing
something compatible independently, if you start with fig-Forth (where
CREATE was best fit as a factor of CODE, not VARIABLE). Of course,
once you know how CREATE and DOES> are defined in Forth-79, working
out an implementation is not that difficult, but how come they were
defined in Forth-79 in that way?
Post by dxf
They all came from Forth Inc but mostly not Chuck. He needed help!
I am not sure whether he needed it, but he certainly got it. The name
I read again and again is Dean Sanderson, wo seems to have had quite a
lot of influence on the evolution of Forth.

There is an ariticle about RISC-V which identifies what instruction
comes from where. As a complement to the family tree, it would be
great if someone documented the history of certain words and features
of Forth. But who would do that?

BTW, my family tree contains Elizabeth Rather's verdict about
Forth-79:

\ from Elizabeth Rather
\ As far as standards conformance is concerned, Forth-79 was such an
\ incomplete and contradictory "standard" that I doubt anyone can fully claim
\ conformance to it. polyFORTH was very close to Forth-83, and had an
\ optional compatibility suite for the non-conforming bits. This unhappy
\ state of affairs came about because Forth-83 was done in two meetings; the
\ design of pF was finalized between the first and second, and conformed to
\ all the "firm decisions" taken in the first meeting. But some of those were
\ reversed in the 2nd meeting, and that created too many incompatibilities for
\ us to follow. SwiftForth conforms to ANS Forth.

Ok, that explains the 1982 date given above. But OTOH Elizabeth
Rather was a co-author of "The Evolution of Forth", which claims that
Starting Forth was mostly written for polyForth.

I see in https://www.computerhistory.org/collections/catalog/102640347
that the "polyForth II -- Reference manual" is from 1982, so maybe
that explains it: polyForth in 1980, polyForth II compatible with the
first draft of Forth-83 from 1982.

In any case, the question remains how CREATE..DOES> came into
Forth-79.

- 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: https://forth-standard.org/
EuroForth 2024: https://euro.theforth.net
dxf
2024-07-26 12:13:34 UTC
Permalink
Post by Anton Ertl
...
But CREATE...DOES> also made it into Forth-79, so it must have been
more widespread by then.
Not necessarily. What systems had 'multiple WHILE' before ANS introduced
it? Brodie mentions it in 'Thinking FORTH' (1984) but without details or
endorsement by a Standard who would risk it? I don't know what was in
Forth-78 but Forth-77 only offered ;: and ;CODE as definer words.
I can imagine FST-79 tossing up the available options - the latest of
which was CREATE DOES> from Forth Inc.
Anton Ertl
2024-08-01 13:48:46 UTC
Permalink
Post by dxf
Post by Anton Ertl
...
But CREATE...DOES> also made it into Forth-79, so it must have been
more widespread by then.
Not necessarily. What systems had 'multiple WHILE' before ANS introduced
it?
cmForth
<https://raw.githubusercontent.com/ForthHub/cmFORTH/combined/cmforth.fth>:

: WHILE ( a - a a) \ IF SWAP ;
: REPEAT ( a a) \ AGAIN \ THEN ;

where "\" is [COMPILE]. AFAIK the SWAP in the WHILE was relatively
late and while the SWAP was still in REPEAT, you had to implement
multiple-exit BEGIN loops differently, but up until fig-Forth (where
"compiler security" was a headline feature) such things were certainly
possible. It's interesting that "compiler security" discouraged such
usage, which made it easier to specify in Forth-94 that the CS-SwAP
happens in WHILE, not in REPEAT (because there was little existing
practice for such things at the time).
Post by dxf
Brodie mentions it in 'Thinking FORTH' (1984) but without details or
endorsement by a Standard who would risk it?
Apparently not that many, or they had switched to the newer WHILE
already, otherwise standardizing it in Forth-94 would not have flown.
--
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: https://forth-standard.org/
EuroForth 2024: https://euro.theforth.net
dxf
2024-08-02 04:18:20 UTC
Permalink
Post by Anton Ertl
Post by dxf
Post by Anton Ertl
...
But CREATE...DOES> also made it into Forth-79, so it must have been
more widespread by then.
Not necessarily. What systems had 'multiple WHILE' before ANS introduced
it?
cmForth
: WHILE ( a - a a) \ IF SWAP ;
: REPEAT ( a a) \ AGAIN \ THEN ;
where "\" is [COMPILE]. AFAIK the SWAP in the WHILE was relatively
late and while the SWAP was still in REPEAT, you had to implement
multiple-exit BEGIN loops differently, but up until fig-Forth (where
"compiler security" was a headline feature) such things were certainly
possible. It's interesting that "compiler security" discouraged such
usage, which made it easier to specify in Forth-94 that the CS-SwAP
happens in WHILE, not in REPEAT (because there was little existing
practice for such things at the time).
Post by dxf
Brodie mentions it in 'Thinking FORTH' (1984) but without details or
endorsement by a Standard who would risk it?
Apparently not that many, or they had switched to the newer WHILE
already, otherwise standardizing it in Forth-94 would not have flown.
It's often been left to Standards to bring in new developments. It
helped when the one introducing it was Forth Inc and it happened to
be well designed and tested. There are also examples where the TC
botched it - things invented on the fly. To this day nobody knows
how PRECISION applies to F. Long story short F. prints differently
from one implementation to the next thanks to the unintelligible spec.
minforth
2024-08-02 06:27:48 UTC
Permalink
Really? With

SET-PRECISION / PRECISION ...
Return the number of significant digits currently used
by F.

and with

F. ...
Display, with a trailing space, the top number on the
floating-point stack using fixed-point notation:
[-] ⟨digits⟩.⟨digits0⟩

i.e. digits+digits0 = number of significant digits

and with

⟨sign⟩ := { + | - }
⟨digits⟩ := ⟨digit⟩⟨digits0⟩
⟨digits0⟩ := ⟨digit⟩*
⟨digit⟩ := { 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 }

F. should be standardized clearly enough.

F.ex.

Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
5 set-precision ok
1.1e-2 f. 0.011 ok <- expected 5 digits i.e. 0.0110
1.1e-40 f. 0.00000000000000000000000000000000000000011 ok

is just an implementation-defined peculiarity.
dxf
2024-08-02 07:11:57 UTC
Permalink
Post by minforth
Really? With
SET-PRECISION / PRECISION ...
Return the number of significant digits currently used
by F.
and with
F. ...
Display, with a trailing space, the top number on the
 [-] ⟨digits⟩.⟨digits0⟩
Fixed-point notation conventionally means decimal places. Here's the spec
from BASIS 17:

12.1.0084 (F.) "Paren-f-dot-paren"

( -- c-addr u )( F: r -- ) or ( r -- c-addr u )

Convert the top number on the floating-point stack to its character
string representation using fixed point notation:

[-] <digit>.<digits0>

The number of digits after the decimal point is determined by PLACES.

That clearly tells how many decimal places to print. There is no equivalent
to PLACES in ANS.

Here's the example ANS gave:

A.12.6.1.1427 F.
For example, 1E3 F. displays 1000.

Let's try it on several forths:

SwiftForth i386-Win32 3.11.9-RC1 01-Sep-2022
3 set-precision ok
1e3 f. 1000. ok
10 set-precision ok
1e3 f. 1000.000000 ok

Gforth 0.7.9_20200709
3 set-precision ok
1e3 f. 1000. ok
10 set-precision ok
1e3 f. 1000. ok

MinForth V3.4.8 - 32 bit
# 3 set-precision ok
# 1e3 f. 1.E3 ok
# 10 set-precision ok
# 1e3 f. 1000. ok

Arguably MinForth isn't compliant as it drops to scientific notation. The
other two, despite displaying differently, are harder to dismiss. I believe
iForth treats PRECISION as decimal places, so that's another variation.
minforth
2024-08-02 07:54:50 UTC
Permalink
There are so many implementation-defined options and ambiguous
conditions in the fp-number standard which altogether leave a
lot of leeway. And f.ex. omission of trailing zeros isn't
specified at all.

So what are you missing? It is a playing field _deliberately_
made with few boundaries.

Theoretically one could argue that a reference Forth system
or a specified set ouf fp output formats would be of help.
But nobody cares. Individual narrow interpretations even less.
So what ..
dxf
2024-08-02 09:44:18 UTC
Permalink
Post by minforth
There are so many implementation-defined options and ambiguous
conditions in the fp-number standard which altogether leave a
lot of leeway. And f.ex. omission of trailing zeros isn't
specified at all.
So what are you missing? It is a playing field _deliberately_
made with few boundaries.
The TC deliberately made the spec ambiguous to allow variations?
Well, they succeeded. Too bad for anyone attempting to write an
app that works similarly across platforms.
Post by minforth
Theoretically one could argue that a reference Forth system
or a specified set ouf fp output formats would be of help.
But nobody cares. Individual narrow interpretations even less.
So what ..
I cared. The bare-bones tick-the-box implementations I saw in the
early 2000's were no use to me - particularly after seeing what
Fortran and C had to offer. The closest to a meaningful set of
functions in Forth at the time was Marcel's. What's regretful is
the BASIS functions (modelled after proven functions from the FVG
FP standard) were near the mark - until the TC chose to ditch it
all for a primitive and PRECISION. I'm not against PRECISION but
it took some time to work out how to apply it to things like F.
Hans Bezemer
2024-08-03 12:49:01 UTC
Permalink
Post by dxf
Not necessarily. What systems had 'multiple WHILE' before ANS introduced
it?
I know I've seen an article on it in FD once, but all I could find now
was the one in V3,72. It's close to the ANS-solution IMHO.

There is also something like an ANDWHILE.

4tH has had multiple WHILEs since around 2005. First I found out I could
consume and resolve WHILE references reliably (4tH uses references)
until I hit a BEGIN reference.

Then I found out, REPEAT and AGAIN were essentially the same (so they
now share the same code). Then I found that UNTIL is nothing but a
BRANCH0 instead of a BRANCH.

I never regretted that design, never needed to revisit it. It's quite
natural, both on the design side as well as the user experience.

I never liked the ANS solution. It's sloppy, lazy and idiosyncratic.
IMHO, of course.

Hans Bezemer

a***@spenarnc.xs4all.nl
2024-07-26 11:56:51 UTC
Permalink
fig-Forth has <BUILDS...DOES> (and the associated implementation with
an extra cell that points to the threaded code behind DOES>).
Forth-79 standarizes CREATE...DOES>; and a popular implementation of
that is to trampoline through the place behind DOES> to the actual
code address. Where did that implementation and CREATE..DOES> in
general come from?
In 2000 I wanted to create a simple Forth in fig-Forth vein,
in fact merely an iso-fication of fig-Forth.
In 1993 for the transputer Forth, I proposed to get rid of
NAME>XT XT>BODY LINK>NAME FORGET>LINK ,what have you, and coined the "dea"
concept that is a token/address/handle to access all the properties
of a word. All words that handle a "word" now uses its dea, and obviously
the dea can serve as an execution token in the sense of iso.
No longer is replacing the execution token behaviour
affecting the identity of a word. No longer is it a problem
if a word has no name. You can unlink a word from its wordlist
and link it elsewhere. Etc.

I arrived at uniform cell wide fields with names
CFA DFA FFA LFA NFA [SFA] [XFA]
CFA pointer to executable code
DFA pointer to DATA
FFA flags
LFA pointer to next dea
NFA pointer to a non-brain-damaged string, i.e. one cell count + chars.
[ options SFA pointer to source code ]
[ XFA optional experimental extra pointer ]

Now it became clear that the iso-requirements of CREATE demand that a
CREATEd words have two part in the DATA field: a pointer to high
level code and the body in the ISO sense. Both fields are modifiable.
Ting came to a similar conclusion implementing a Forth in a c-type
oo language (I remember Java) for a need to two separate fields.

So it is a natural idea following from iso-demands, but maybe
hold back with implementation tricks. Notably a CALL to a the common
code with this CREATE class, immediately followed by the data,
because a pointer to this would be pushed on the stack, saving
an instruction and one byte. Forth has no problems with spaghetti
code, but spaghetti data is equally bad.
The entanglement of the data and code fields in this way,
may no longer advantageous for modern processors.
Moreover the 56 bytes a Forth header takes is no longer a
consideration with Gbyte memories.
My guess is that it did not come from Forth, Inc.: At the time of
Forth-79 AFAIK Forth, Inc.'s Forths were miniForth and microForth.
And given that fig-Forth started out as a port of microForth to the
6502, I doubt that Forth, Inc. used CREATE..DOES>. Also, Forth,
Inc. ignored Forth-79 (IIRC Elizabeth Rather described it as
inconsistent or some other statement that she would not have made if
Forth, Inc. had actually accepted and implemented Forth-79).
At least dxf is very well versed in historic Forth developments.
Maybe he or somebody else can answer my question: Where did the
implementation described above and CREATE..DOES> in general come from?
It is a direct consequence of ISO. It has been independantly
invented (if that is the proper word) at least two times by
TING and me.
- anton
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat purring. - the Wise from Antrim -
Loading...