Gerry
Yes, that would be interesting. Not that someone comes to the idea to
try to develop a Forth20XX...
-Helmar
No. It would probably offer standardization on things that could not be
completed in the first round of standardization, like I18N.
But regular rounds of standardization are part of the ANS-ISO
processes, so how would that be non-ANS.
Compliance with the existing standard involves not using the words it
defines with different semantics ... its normal and expected that words
not in the standard will be defined in a system. So any systems that
have the words defined in ANS Forth 200X are compliant in advance.
At this point, the folks working on 200x have no official (ANSI, ISO, or
IEEE) status as far as I know, so any standard they release would be
whatever they choose to call it as long as it doesn't claim to be one of
those. Of course, if and when they draw near to completion, they could
seek official standing if they wish to.
Whatever they release could be perfectly ANS Forth compliant providing
they don't make any changes to words, semantics, requirements, etc., in
the existing published standard (e.g. if it only contained additional
words or is otherwise a compliant superset of ANS Forth).
Cheers,
Elizabeth
--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310-491-3356
5155 W. Rosecrans Ave. #1018 Fax: +1 310-978-9454
Hawthorne, CA 90250
http://www.forth.com
"Forth-based products and Services for real-time
applications since 1973."
==================================================
I wouldn't mind a step backwards with a standardized "Simple Forth" for
embedded applications. Make it indirect threaded as standard. NEXT can be
inlined or a single routine for trouble shooting, word use counting, etc.
Get rid of PICK and ROLL and the words prefixed with '2' that don't involve
an operation by the number 2. I mean 2* fits the Forthish way. 2DUP doesn't
unless it means
: 2DUP DUP DUP ;
Use D for double length stuff.
A well defined simple linear vocabulary and vocabulary search. Links should
point to links for fast search on modern processors.
I wouldn't mind block I/O on files or devices. It is trivial to use a
DOSonChip part for PC compatible I/O to mass storage. I never need it in
code.
Don't pretend the Forth is meant to make portable code for multiple
platforms, and get rid of CELL.
I don't even know what POSTPONE does.
<BUILDS DOES> or CREATE DOES> are fine with me.
While I'm at it, make VAR and CON standard and save some typing. Everyone I
know redefines to this anyway in the first couple of lines of everything they
write.
Make DLITERAL set the decimal point location. It used to but doesn't now. Is
that right? There was something about ANS that ruined all my best floating
point input.
Floating stack MUST be seperat if used.
Loop stack highly recommended if hardware will support it efficiently.
-- Charlie Springer
Not trying to start a flame war, but would like opinions of embedded
developers.
> I don't even know what POSTPONE does.
Mmm. Please don't take this as a flame, but if you don't even know
what POSTPONE does you really need to spend a bit more time looking at
Standard Forth before making any comments.
Andrew.
...thus leaving out the largest suppliers of Forths for embedded systems
and preventing the most popular optimization strategies?
> Get rid of PICK and ROLL
That I could go for ;-)
> and the words prefixed with '2' that don't involve
> an operation by the number 2. I mean 2* fits the Forthish way. 2DUP doesn't
> unless it means
>
> : 2DUP DUP DUP ;
>
> Use D for double length stuff.
No, no, no. There's an important distinction between the 2- prefix and
the D- prefix. 2xxx words operate on pairs of stack items that may or
may not have any particular relationship to each other. Dxxx words are
specifically for double-length integers, with the high-order part on
top. 2* and 2/ are the exceptions here. Many folks argue for
eliminating them, since optimizing compilers handle that case anyway.
> A well defined simple linear vocabulary and vocabulary search. Links should
> point to links for fast search on modern processors.
What the link points to for optimum search speed is different for
different processors.
> I wouldn't mind block I/O on files or devices. It is trivial to use a
> DOSonChip part for PC compatible I/O to mass storage. I never need it in
> code.
That's one reason why blocks are still in ANS Forth as an option.
> Don't pretend the Forth is meant to make portable code for multiple
> platforms, and get rid of CELL.
Having ported quite a number of substantial applications from 16-bit to
32-bit implementations, I have formed an extremely high regard for the
value of CELL and its relatives.
> I don't even know what POSTPONE does.
See Andrew's post above.
> <BUILDS DOES> or CREATE DOES> are fine with me.
CREATE DOES> is standard. Are you thinking they're somehow connected
with POSTPONE? They aren't.
> While I'm at it, make VAR and CON standard and save some typing. Everyone I
> know redefines to this anyway in the first couple of lines of everything they
> write.
Nobody I know does.
> Make DLITERAL set the decimal point location. It used to but doesn't now. Is
> that right? There was something about ANS that ruined all my best floating
> point input.
ANS Forth standardized floating point for the first time. There were a
lot of divergent versions before it, and most of them had to change
some. We're better off now.
> Floating stack MUST be seperat if used.
That's the most common implementation. If you care, you can choose to
use Forths that do it that way.
> Loop stack highly recommended if hardware will support it efficiently.
It's added complexity. I thought you wanted a simple system?
> -- Charlie Springer
>
> Not trying to start a flame war, but would like opinions of embedded
> developers.
Embedded systems have been our main line of business for over 30 years.
My comments are above.
If you mean a finished standard document: When it's ready (or when we
get tired of working on it). The second "0" indicates that we want to
be finished before 2010.
If you mean when draft versions of the standard document will be
released, that should happen in the next months.
Also, if you are impatient, you can take a look at the CfV results in
http://www.forth200x.org/, which are the source material from which
the changes in the standards are made.
- 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
---[ I'd note that ... ]---
An implementation standard could be established by a working party with
the ability to work on a sufficient variety of embedded equipment to
provide a baseline, and then providing the implementations of that
model for that equipment. And of course the working party could specify
whatever dispute resolution system that they saw fit.
The most straightforward way to agree on the names of words would be to
pick and choose words from the ANS Forth Core, and use not-standardized
wordnames, preferably with a common practice from earlier
implementations, for the balance. This would be partially compatible,
albeit not compliant.
Of course, you run the risk that in a group of 5 willing to pick and
choose from the ANS Forth Core, the whole Core ends up in the list, and
so you run the risk of an ANS Forth compliant implementation model. For
example, someone who has a favorite file of specialised compiler words
written by POSTPONEing standard branching words would want POSTPONE in
the implementation, to avoid forking that file. Someone that wants to
testbed algorithms in a larger Forth will want CELLS, and so the
massive concession of
{\c : CELLS 2* ; \}, {\c : CELL+ 2+ ; \}
is made, assuming your implementation is restricted to 16-bit
controllers. Or else one persons hardware is nybble addressed and
another persons hardware is word addressed, and they would rather work
with actual addresses than "implementation model addresses", because
its far more efficient to work with the actual addresses and use
generic names that provide the actually required conversion to cell
width.
You could of course form the group from those who refuse to consider
compatibility with ANS Forth, but if you get 5 together, without any
commercial consideration for agreeing with each other, you are likely
to end up with 5 mutually incompatible implementation models.
You could just implement fig-Forth in a variety of embedded contexts
that did not exist when it was first distributed.
Maybe the core wordset of ANS Forth had that intention, or could be
used as a basis for that.
>Get rid of PICK and ROLL
Not in the core wordset of ANS Forth.
>Don't pretend the Forth is meant to make portable code for multiple
>platforms, and get rid of CELL.
No need to pretend. Appropriately written Forth code is very portable
across multiple platforms; CELLS (unfortunately no such word as CELL
in ANS Forth) is very useful for that.
>Make DLITERAL set the decimal point location. It used to but doesn't now.
There is no DLITERAL in ANS Forth. So if you use a Forth where
DLITERAL is different from what it used to be, complain to the
implementor of that Forth system.
>Floating stack MUST be seperat if used.
That's one of the things we have been discussing for Forth200x.
Getting 2/ through optimization is not easy, unless the system's / is
floored (or if / is symmetric and the representation of signed numbers
is one's-complement); and while one could imagine that, say a
twos-compolement system with symmetric division could optimize the
appropriate sequence into 2/, nobody would write that sequence:
- The naive user would not write it, because he would not know about
the issue. Or, like me, he would not remember the sequence.
- The guru user would not write it, because it would make the code
slower on systems with floored division (or non-twos-complement
arithmetic).
Adding a signed variant of RSHIFT would be a good idea, though, and
would eliminate the need to use 2/.
BTW, I don't remember anyone arguing for eliminating 2/ with that
rationale (or any other). If the word is so superfluous, I wonder how
it made it into the core wordset in the first place.
The signed variant should be of LSHIFT, not RSHIFT.
--
- Gary Chanson (Windows SDK MVP)
- Abolish Public Schools
> Adding a signed variant of RSHIFT would be a good idea, though, and
> would eliminate the need to use 2/.
>
Well, we've had proposals here before for ARSHIFT and SRSHIFT; which
would you suggest?
--
Regards
Alex McDonald
> "Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
> news:2006Dec...@mips.complang.tuwien.ac.at...
>>
>> Adding a signed variant of RSHIFT would be a good idea, though, and
>> would eliminate the need to use 2/.
>
> The signed variant should be of LSHIFT, not RSHIFT.
In 2's complement there is no difference in unsigned and signed LSHIFT.
Mayby on your 1's complement machine ? Or do you have a still scarser
sign-magnitude cpu ?
--
Coos
CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html
*Sigh* it was argued passionately. 2* and 2/ were even out for a while,
and were reinstated more-or-less at the last minute on the grounds of
common practice.
In those days, virtually all implementations were ITC and optimization
was unknown except for the Forth chips. The feeling was that access to
these optimizations (which are significant on low-end processors with
performance issues already and slow division) was an important entitlement.
> Mmm. Please don't take this as a flame, but if you don't even know
> what POSTPONE does you really need to spend a bit more time looking at
> Standard Forth before making any comments.
It is true, I don't use ANS in embedded. For some reason, I find it awkward
to mold it to the hardware compared to FIG or '79. I use Standard Forth under
Mops. I have implemented POSTPONE in an ARM forth but I don't remember what
process or words it replaced. (Use it or loose it, eh?)
-- Charlie Springer
>> I wouldn't mind a step backwards with a standardized "Simple Forth" for
>> embedded applications. Make it indirect threaded as standard. NEXT can be
>> inlined or a single routine for trouble shooting, word use counting, etc.
>
> ...thus leaving out the largest suppliers of Forths for embedded systems
> and preventing the most popular optimization strategies?
I would draw a distinction between a Forth standard that is apropriate for
compiler company that can put a team (?) together to develope an optimizing
compiler/interpreter and a standard for a Forth appropriate for the
individual designer who needs to get something running on a particular or
unique platform.
>> Get rid of PICK and ROLL
>
> That I could go for ;-)
>
>> and the words prefixed with '2' that don't involve
>> an operation by the number 2. I mean 2* fits the Forthish way. 2DUP
>> doesn't
>> unless it means
>>
>>> 2DUP DUP DUP ;
>>
>> Use D for double length stuff.
>
> No, no, no. There's an important distinction between the 2- prefix and
> the D- prefix. 2xxx words operate on pairs of stack items that may or
> may not have any particular relationship to each other. Dxxx words are
> specifically for double-length integers, with the high-order part on
> top. 2* and 2/ are the exceptions here. Many folks argue for
> eliminating them, since optimizing compilers handle that case anyway.
I could go for that. There used to be endless arguments about 2/ and some
Forths shifted and some divided. The difference showed up with negative
numbers.
I can see where CELL would be popular at Forth, Inc. But why not leave it as
a definition in the application code?
snip
>> While I'm at it, make VAR and CON standard and save some typing. Everyone I
>> know redefines to this anyway in the first couple of lines of everything
>> they
>> write.
>
> Nobody I know does.
They probably know you would kick their ass ;-) The last time I wrote a big
project (a plywood plant veneer moisture thingy) I had a zillion constants
for I/O locations and control. I could put them about six wide on a single
page (OK, less than a zillion) with CON, which made it a lot easier to find a
particular item.
-- Charlie Springer
> You could just implement fig-Forth in a variety of embedded contexts
> that did not exist when it was first distributed.
Kind of a fig-Forth79 with a little polishing? I'm not worried about
commercial considerations in this case. I have in mind, the person who needs
to get a Forth running on an eccentric platform. It may wind up in millions
of cell phones, but to start with there would not be a commercial version
available or appropriate. I have reluctantly used C several times when
setting up a commercial Forth system proved impossible or too time consuming.
Didn't look too good spending the company time and money on it either. I'm
not suggesting that writing a Forth is a good strategy in a tight business
situation, just that there are times when that commercial development system
just won't do.
BTW, your comment is a great example of the evolution or complication of
Forth (and other computer stuff), since fig-Forth dates almost exactly to the
use of "implement" as a verb among programmers. I think back then we would
have severely beaten anyone who referred to a microcomputer as an embedded
context. Maybe you would have to wait till the invention Jolt Cola to get us
out of our chairs ;-)
-- Charlie Springer
That's one of the arguments that Forth94 resolved, by explicitly
defining 2/ as a shift.
> I can see where CELL would be popular at Forth, Inc. But why not leave it as
> a definition in the application code?
As others have noted, it's actually CELLS and CELL+. That's actually
one of the most popular and widely implemented Forth94 innovations.
Hardly anyone can say with absolute certainty that code for a particular
project mightn't be useful in another project with different cell size.
Anyone who's ever been in the position of having to search a large app
for instances of 2+, 2 +, 2 * and 2* and trying to determine if they're
doing address arithmetic or not is grateful for this one.
>>> While I'm at it, make VAR and CON standard and save some typing. Everyone I
>>> know redefines to this anyway in the first couple of lines of everything
>>> they write.
>> Nobody I know does.
>
> They probably know you would kick their ass ;-) The last time I wrote a big
> project (a plywood plant veneer moisture thingy) I had a zillion constants
> for I/O locations and control. I could put them about six wide on a single
> page (OK, less than a zillion) with CON, which made it a lot easier to find a
> particular item.
Actually, for this purpose we usually use EQU, which can have less of a
target footprint than CONSTANT.
So I can boot up a dos laptop with Tomsrtb Linux, mount the FAT
filesystem, compile a utility for a 16-bit Forth on the dos box in
gforth for linux and it runs. Just for an actual example (yeah, sure it
was for Camel running on a CP/M emulator on the dos box, and it
probably originated as a file written for a 32-bit implementation in
the first place, but those are just details).
I mean, I am as far away from the "Forth Inc" setting as it is possible
to be. I've still benefited from it.
Maybe also so something that has been done on one side of a
controller-PC testbed connection can be shifted to the other side.
Maybe also so someone implementing a routine for a nybble addressed
narrow bus uC does not have to rework everything from scratch ... after
all, controllers seem to have more variety of architectures than
desktops microcomputers.
And on POSTPONE ....
I can see not needing POSTPONE on the target if you are not compiling
on the target, but then you don't need IF THEN ELSE either. You'd still
want to have POSTPONE where the compilation is occuring. Why wouldn't
you want ORIF and ANDIF in a control setting?
>> Don't pretend the Forth is meant to make portable code for multiple
>> platforms, and get rid of CELL.
>
> No need to pretend. Appropriately written Forth code is very portable
> across multiple platforms; CELLS (unfortunately no such word as CELL
> in ANS Forth) is very useful for that.
No argument about the possibility of portability. I just don't run into the
need. Embedded projects tend to be so closely embedded that most of it
wouldn't make any sense to move to another platform. The part that is
moveable is high enough level that it doesn't need any changes.
CELLS CELLS CELLS! I'll see if that helps. Care to guess how many times I
have stared at an error message pointing to CELL and I can't figure out what
is wrong?
>> Make DLITERAL set the decimal point location. It used to but doesn't now.
>
> There is no DLITERAL in ANS Forth. So if you use a Forth where
> DLITERAL is different from what it used to be, complain to the
> implementor of that Forth system.
Yes, so make DLITERAL part of the simple Forth. It worked great.
I'll admit, while writing an ANS Forth for the ARM I was bogged down when I
got to the nebulous vocabulary structure and search portion. I finally did a
simple fig/79 variant that isn't compliant. Compared to writing Forths that
were fig or 79, this was a chore instead of a pleasure and it soured me on
the ANS model.
That was years and years ago (I was just lifting something from the listing
last wee. It said 1991. Yipe!) and I see some nice things in the ANS Forths
and the discussions here but I can see a small need for a middle ground. I
would like to see something more inviting to the hobbyist. The compiler
discussion is rather esoteric and has become more like C compiler talk.
Nobody (almost) writes their own C compiler and I don't meet young people who
would write their own Forth from the ANS documents.
-- Charlie Springer
###################################################################
If Chuck would have named it MOORE , he'd be remembered ....
But we know Noble , Brodie , Elizabeth Luddites instead .
The ambitious Luddites lead us astray ,
they did nothing of value , yet we read what they have to say .
Carpet baggers ....
No HLL alows you to improve itself , the door is closed .....
Rewrite Forth yourself , its easy ...
DONT try to stuff an assembler into the Dictionary , it must be
written
in Forth , using first the Prim's , then later de-bloated by
replacing them
with Mid Levels .
No faster way to create S/W .
No need to make it complete , just the essential OpCodes.
Top down , bottom up ....
If you stay too long on the assmbler , trying to create clever
proceedures
you will kick yourself later for you find Mid-Levels that do it better
.
This is the Uniqness of the Forth OpSys .
If you dwell on primatives too long , you will
be applying them "specifically" to assembly ,
but later you will study Mid Levels
and see how to apply Mid Levels to all similar low level
Problems !
The opposite , here , is to create unique sets of Prims for
each low level proc , nothing is same , yet they do similar
work !! Unreadable !!
###### And thus i have disproved the Bottom up theory !
You must NOT code bottom up ,
#### You must code back/Forth back/Forth back/Forth ...
... til the Low is optomised for the MID LEVELS .
All this , because we see better Prims , as we start new
tasks with similar requirements ...
Write clever "entry" points to allow easy rewrite .
Non-reentrant code is poison , learn how ...
Thanks, that's all I wanted to know. I've seen the stuff on
http://www.forth200x.org/.
Gerry
> So I can boot up a dos laptop with Tomsrtb Linux, mount the FAT
> filesystem, compile a utility for a 16-bit Forth on the dos box in
> gforth for linux and it runs. Just for an actual example (yeah, sure it
> was for Camel running on a CP/M emulator on the dos box, and it
> probably originated as a file written for a 32-bit implementation in
> the first place, but those are just details).
>
> I mean, I am as far away from the "Forth Inc" setting as it is possible
> to be. I've still benefited from it.
>
> Maybe also so something that has been done on one side of a
> controller-PC testbed connection can be shifted to the other side.
>
> Maybe also so someone implementing a routine for a nybble addressed
> narrow bus uC does not have to rework everything from scratch ... after
> all, controllers seem to have more variety of architectures than
> desktops microcomputers.
I could come around. Maybe it is just the word. Cells are generally two or
three dimensional things in the real world and I have never taken to the word
to describe an entry in a number line.
> And on POSTPONE ....
>
> I can see not needing POSTPONE on the target if you are not compiling
> on the target, but then you don't need IF THEN ELSE either. You'd still
> want to have POSTPONE where the compilation is occuring. Why wouldn't
> you want ORIF and ANDIF in a control setting?
I was just trying to remember what POSTPONE replaced which is why I said I
don't know what it does. In the sense of what happened before there was
POSTPONE, I don't. I'll have to dig out some listings and compare branching
defining words.
-- Charlie Springer
> If Chuck would have named it MOORE , he'd be remembered ....
>
> But we know Noble , Brodie , Elizabeth Luddites instead .
>
> The ambitious Luddites lead us astray ,
> they did nothing of value , yet we read what they have to say .
>
> Carpet baggers ....
>
>
> No HLL alows you to improve itself , the door is closed .....
See Mops. All added to ANS Forth.
Quit reading that Xtreeme Programming stuff. It is a perversion of good Forth
(and general) techniques and It is rotting your mind! And stay from
fluorescent lights.
-- Charlie Springer
The intent is to describe the size of a unit of memory. The
industry-standard term is 'word', but that's already too overloaded in
Forth. A memory cell is a perfectly understandable concept, quite
unrelated to biological thingies.
>> And on POSTPONE ....
>>
>> I can see not needing POSTPONE on the target if you are not compiling
>> on the target, but then you don't need IF THEN ELSE either. You'd still
>> want to have POSTPONE where the compilation is occuring. Why wouldn't
>> you want ORIF and ANDIF in a control setting?
>
> I was just trying to remember what POSTPONE replaced which is why I said I
> don't know what it does. In the sense of what happened before there was
> POSTPONE, I don't. I'll have to dig out some listings and compare branching
> defining words.
POSTPONE resolves an ambiguity in COMPILE vs. [COMPILE], which required
the programmer to know whether the thing he was trying to compile was
IMMEDIATE or not. POSTPONE doesn't care. It's extremely rarely used in
applications (whether embedded or not), since it's intended for
extending the compiler.
> The intent is to describe the size of a unit of memory. The
> industry-standard term is 'word', but that's already too overloaded in
> Forth. A memory cell is a perfectly understandable concept, quite
> unrelated to biological thingies.
I teach physics and chem and sometimes biology these days. I think of cells
in terms of living cells, phone cells, honey bee wax cells, prison cells,
monastary rooms, cells in foam, etc. But I can get used to it. I suspect that
I had a heck of a time with a new meaning for "word" back in the 70's when I
started using Forth. The biggest hurdle that I can recall was the use of the
word "compile" for immediate actions that extended the dictionary. Having
used only assembly, FORTRAN, and BASIC at that time, it was tough to get a
handle on. I think it took me quite a while to get the hang of it and maybe
only after studying Bill Ragsdale's assembler for the 6502 did it begin to
cognate in the old noggin. Forth Dimensions and phone calls to California
were the only resource. The guys who wrote the Forth and manual for the
AIM-65 (and who I later worked with) provided the most valuable assistance.
>>> And on POSTPONE ....
>>>
>>> I can see not needing POSTPONE on the target if you are not compiling
>>> on the target, but then you don't need IF THEN ELSE either. You'd still
>>> want to have POSTPONE where the compilation is occuring. Why wouldn't
>>> you want ORIF and ANDIF in a control setting?
>>
>> I was just trying to remember what POSTPONE replaced which is why I said I
>> don't know what it does. In the sense of what happened before there was
>> POSTPONE, I don't. I'll have to dig out some listings and compare branching
>> defining words.
>
> POSTPONE resolves an ambiguity in COMPILE vs. [COMPILE], which required
> the programmer to know whether the thing he was trying to compile was
> IMMEDIATE or not. POSTPONE doesn't care. It's extremely rarely used in
> applications (whether embedded or not), since it's intended for
> extending the compiler.
I'm rather fond of words that define words that define words. I would have to
dig out an old example and try it in ANS to see if I explicitly need POSTPONE
to say, define the actions of a bunch of push button switches or a couple
dozen moisture sensing brushes. I think I built a plotter font that way once.
-- Charlie Springer
> ...
> Get rid of PICK and ROLL
PICK and ROLL have been around for ages and are part of 'classic'
Forth. They are probably more recognizable than NIP and TUCK.
Getting rid of words which have not been directly replaced by others
is a dubious benefit. I'd rather have PICK or ROLL available on the
occasions I needed them than having to work around.
> and the words prefixed with '2' that don't involve
> an operation by the number 2. I mean 2* fits the Forthish way. 2DUP doesn't
> unless it means
>
> : 2DUP DUP DUP ;
Most '2' operators are there to handle 'pairs' of numbers. Very handy
when you need them. As it happens, storing number pairs is the same
as storing double-length numbers. Thus the '2' operators double as
'D' operators.
> Floating stack MUST be seperat if used.
No-one is currently forced to write f/p code for a common stack.
How does preventing those that do help in any way?
>> ...
>> Get rid of PICK and ROLL
>
> PICK and ROLL have been around for ages and are part of 'classic'
> Forth. They are probably more recognizable than NIP and TUCK.
>
> Getting rid of words which have not been directly replaced by others
> is a dubious benefit. I'd rather have PICK or ROLL available on the
> occasions I needed them than having to work around.
People used to define them in some systems. Generally very inefficient and
lead to stacking up too much junk. I figure if I need them then I have not
worked hard enough. In a simple Forth, I would not bother with them.
I have never used NIP or TUCK. They are too sneaky.
>> and the words prefixed with '2' that don't involve
>> an operation by the number 2. I mean 2* fits the Forthish way. 2DUP doesn't
>> unless it means
>>
>>> 2DUP DUP DUP ;
>
> Most '2' operators are there to handle 'pairs' of numbers. Very handy
> when you need them. As it happens, storing number pairs is the same
> as storing double-length numbers. Thus the '2' operators double as
> 'D' operators.
>
True enough, but there is nothing like D* that means multiply by D.
>> Floating stack MUST be seperat if used.
>
> No-one is currently forced to write f/p code for a common stack.
> How does preventing those that do help in any way?
If you want a standard, use the best methods. Mixed stacks are a nightmare.
-- Charlie Springer
> No-one is currently forced to write f/p code for a common stack.
> How does preventing those that do help in any way?
This was one of the RfD/CfV issues, previously referred to in this
thread. Maybe that was overlooked because the itemised list was a click
away.
So for reference, CfV's.
fp stack: http://www.forth200x.org/fp-stack.html
ekeys return values: http://www.forth200x.org/ekeys.html
One time file loading: http://www.forth200x.org/required.html
PARSE-NAME: http://www.forth200x.org/parse-name.html
extension queries: http://www.forth200x.org/extension-query.html
DEFER: http://www.forth200x.org/deferred.html
RfD's without CfV's are at the original
http://www.forth200x.org/rfds.html involving Directories, 2VALUE,
Enhanced local variable syntax, THROW codes and iors, Escape strings,
structures, SYNONYM, FVALUE, and the XCHAR wordset.
No. The difference is the sign of the count input parameter. The sign
should be positive for left shift.
> "Charlie Springer" <R...@regnirps.com> wrote in message news:0001HW.C19F9ADA...@news.nw.centurytel.net...
>> Floating stack MUST be seperat if used.
> No-one is currently forced to write f/p code for a common stack.
> How does preventing those that do help in any way?
It raises the bar for implementors, forcing them to produce a better
Forth system. I'm with Charlie all the way on this one.
Andrew.
You mean this:
: RSHIFT NEGATE ( or ABS ) LSHIFT ;
I sure can live with that. Perhaps LSHIFT can be renamed to SHIFT then.
I don't know of a CPU that has one instruction for both shifts. So either
the compiler or the developer has to be smart if she wants to use warp
speed ;-)
> Op Sun, 10 Dec 2006 13:07:41 -0500 schreef Gary Chanson:
>
>> "Coos Haak" <chf...@hccnet.nl> wrote in message
>> news:e1gf5q8rkows$.ktnbun3sz61m$.dlg@40tude.net...
>>> Op Sat, 9 Dec 2006 11:21:44 -0500 schreef Gary Chanson:
>>>
>>>> "Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
>>>> news:2006Dec...@mips.complang.tuwien.ac.at...
>>>>>
>>>>> Adding a signed variant of RSHIFT would be a good idea, though, and
>>>>> would eliminate the need to use 2/.
>>>>
>>>> The signed variant should be of LSHIFT, not RSHIFT.
>>>
>>> In 2's complement there is no difference in unsigned and signed LSHIFT.
>>> Mayby on your 1's complement machine ? Or do you have a still scarser
>>> sign-magnitude cpu ?
>>
>> No. The difference is the sign of the count input parameter. The
>> sign
>> should be positive for left shift.
>
> You mean this:
> : RSHIFT NEGATE ( or ABS ) LSHIFT ;
> I sure can live with that. Perhaps LSHIFT can be renamed to SHIFT then.
Duh. The difference between RSHIFT and a supposed SRSHIFT (signed shift
right) is the following (example with 64 bit, hex):
-20 5 rshift . 7FFFFFFFFFFFFFF
-20 5 srshift . -1
--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/
PDP-10.
I didn't overlook it. I just don't see the issue.
Under Forth-94, separate stack users can continue to write f/p code
and common stack users can continue to write f/p code. Exactly
where is the problem?
I've used both methods and like floored/symmetric integer division
each has it's good/bad points. Forth-94 lets me make the choice
according to the task at hand. Forth200x wants to take the choice
away.
> "Bruce McFarling" <agi...@netscape.net> wrote in message news:1165763520.6...@16g2000cwy.googlegroups.com...
>> Ed wrote:
>> > "Charlie Springer" <R...@regnirps.com> wrote in message
> news:0001HW.C19F9ADA...@news.nw.centurytel.net...
>> > > Floating stack MUST be seperate if used.
>>
>> > No-one is currently forced to write f/p code for a common stack.
>> > How does preventing those that do help in any way?
>>
>> This was one of the RfD/CfV issues, previously referred to in this
>> thread. Maybe that was overlooked because the itemised list was a click
>> away.
>>
>> So for reference, CfV's.
>>
>> fp stack: http://www.forth200x.org/fp-stack.html
> I didn't overlook it. I just don't see the issue.
> Under Forth-94, separate stack users can continue to write f/p code
> and common stack users can continue to write f/p code. Exactly
> where is the problem?
It's a pain to use, mostly because there is no comfortable way
to handle mixed types on the stack.
> I've used both methods and like floored/symmetric integer division
> each has it's good/bad points. Forth-94 lets me make the choice
> according to the task at hand. Forth200x wants to take the choice
> away.
No, it doesn't. A Forth user can still write Forth-94 compatible code
that will run on a mixed stack, and that code will still run on a
Forth200x system with a separate FP stack.
The additional requirement is placed on Forth *implementors*, forcing
them to provide a better Forth, making it easier for people to write
portable FP code, something which is at the present time very hard to
do.
The change is totally compatible for all existing Forth-94 standard
programs.
Andrew.
It is taking away choice. And for no demonstrable benefit.
Until someone can prove that a separate stack model is superior
in every situation, it would be foolish to mandate it.
What's good about the common stack model? If I were
implementing f/p on a small system with minimum resources
and no fpu I might well discover that a mixed stack system
took less space and possibly even ran faster. I don't need a
forth standard that tells me I can't do it!
At least one forth vendor that offers a mixed stack f/p in
addition to separate stack ones. Presumably there was a
need for it.
Forth-94 is looking better all the time...
It's anaother example of what I've been proclaiming all the time: ANS
Forth is trying to make architecture decisions, where it shouldn't. Be
a language standard, not an architecture standard.
Hans Bezemer
I don't believe that, actually. The separate stack model always makes
operands easier to access: there is no case in which an operand on a
separate stack may not be accessible when, on a mixed stack, it would
have been accessible.
> Until someone can prove that a separate stack model is superior in
> every situation, it would be foolish to mandate it.
It's not superior in every situation: there are some simple situations
in which it's no better. For example, if you happen to have a word
that uses exclusively floating-point operands, it won't be any
different.
There are no situations in which it's worse to use.
Come on, let's have the truth about this: the committee were persuaded
by one hardware vendor to allow mixed stacks. This vendor, who was
thought to be important at the time, told the committee that they
would be unable to create a standard Forth if mixed stacks were
forbidden. Needless to say, the particular vendor is not developing
their hardware any more, but we're still stuck with this requirement.
> What's good about the common stack model? If I were implementing
> f/p on a small system with minimum resources and no fpu I might well
> discover that a mixed stack system took less space and possibly even
> ran faster.
Even on a very small system I doubt it, because of the extra
contortions that it's necessary to perform in the application code.
Ultimately, the key to the argument is this: it's all about whether
the standard prefers usability for the application developer or ease
for the system implementor.
Andrew.
> Ed schreef:
>> It is taking away choice. And for no demonstrable benefit.
>> Forth-94 is looking better all the time...
> It's anaother example of what I've been proclaiming all the time: ANS
> Forth is trying to make architecture decisions, where it shouldn't.
This is not about ANS, but about Forth200X, as the subject says.
> Be a language standard, not an architecture standard.
Totally right. I couldn't agree more.
Andrew.
>Even on a very small system I doubt it, because of the extra
>contortions that it's necessary to perform in the application code.
There are only two situations MPE have found where the mixed stack
has advantages.
1) Small embedded systems, e.g. 8051
2) external graphics packs that take 32 bit floats on the
same stack as 32 bit ints.
The big issue for us is that mandating a separate stack
essentially disenfranchises a lot of stable and mature
existing code.
Stephen
--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads
Thank you for sharing that. Real-world experience is particularly
valuable here.
> The big issue for us is that mandating a separate stack
> essentially disenfranchises a lot of stable and mature
> existing code.
I don't follow this part. You'd have two choices, either continue to
run your legacy code on legacy systems, and not label them 200x
compliant. Or else develop 200x compliant systems (which you will do
anyway, but you might not need to port legacy code to them) and port
the code. Is there any reason your old source code written for a mixed
stack won't compile correctly on a system with separate stacks?
People are claiming that any code that runs on a mixed-stack system
will run on a separate-stack system too. That looks to me like it ought
to be right. The mixed stack is a complication for application
programmers, they have to make sure that the things they want are on
top. There is no standard way to start with ( x1 f1 ) and turn it into
(x1 f1) short of moving the float to a variable, moving the cell-size
item elsewhere (variable, local, return stack, pad, etc) and fetching
the float back. If you've been doing things like ROT to get a single
because your floats happened to be double size, or 3 PICK to get it
because your floats were triples, or something like that, then your
code is not very portable among mixed stacks much less to separate
stacks.
In the general case I don't see extra stacks causing compatibility
problems for application code. A separate loop stack will not cause any
code to fail that was written for a loop stack mixed with return stack
-- the hoops you go through avoiding problems with the mixed stack are
gone, but it causes no trouble that you still jump where those hoops
used to be. A dummy return stack for user data causes no problem for
application code, unless that code does return-address manipulation and
works around user code on the return stack. Standard code doesn't do
that so standard code will run unmodified.
But it doesn't work the other way. If you write code that uses a
separate floating point stack, or a separate loop stack, or a separate
return stack, then your code won't run unmodified on systems that have
all the stacks combined.
> Until someone can prove that a separate stack model is superior
> in every situation, it would be foolish to mandate it.
Yes. Proof for every situation would be a challenge. How about every
situation I have ever seen since 1978?
> What's good about the common stack model? If I were
> implementing f/p on a small system with minimum resources
> and no fpu I might well discover that a mixed stack system
> took less space and possibly even ran faster. I don't need a
> forth standard that tells me I can't do it!
How could it take more space? Memory is memory. You have to put the data
somewhere. Run faster? I can see having to swap the stack pointer for an FP
stack pointer in a resource bound system. But this will pale compared to a
complex multiply on mixed versus separate. This was never a lightly made
decision, even though the code for algorithms with separate stacks is much
more readable (and writable!), speed was the driving factor. I and several
others have done extensive testing on multiple platforms with both forms. The
scientific conclusion? Mixed stack sucks.
-- Charlie Springer
> People are claiming that any code that runs on a mixed-stack system
> will run on a separate-stack system too. That looks to me like it ought
> to be right.
I don't understand this argument. I can picture it for very high level code,
in which the manipulations on the stacks are hidden. But what about more
primitive code? Take a complex multiply for example. You have the addresses
of four floating point numbers and they have to each be used at least twice.
How are they mixed in with the FP numbers? You can use them explicitly as you
need them or on a separate stack model, you can pile of the addresses in the
order needed and "machine gun" the FP. How can this be portable?
-- Charlie Springer
I am not sure what you mean with disenfrenchise, but:
- Forth programs that are Forth-94 standard programs are still
standard with the separate FP stack proposal.
- Some Forth programs that are not Forth-94 standard programs would
become standard programs in a standard that adopts the proposal.
- Some Forth programs that are not Forth-94 standard programs would
continue to be non-standard programs even in a standard that adopts
the proposal.
As a Forth programmer, the choices you have without that proposal
standardized are:
- You can write code that works on separate-stack systems and works on
all different kinds of mixed-stack systems. People who use separate
stack systems find this incredibly painful, and even mixed-stack
advocates admit that they usually don't write such code, but write
code that would not work on mixed-stack systems with a different
number of cells-per-float, or on separate-stack systems.
- You can write non-standard code.
As a Forth programmer, the choices you have with that proposal
standardized are:
- You can write code that works on separate-stack systems and works on
all different kinds of mixed-stack systems.
- You can write code that works only on separate-stack systems.
- You can write non-standard code.
How does this take away choice?
>>Even on a very small system I doubt it, because of the extra
>>contortions that it's necessary to perform in the application code.
> There are only two situations MPE have found where the mixed stack
> has advantages.
> 1) Small embedded systems, e.g. 8051
Snakes alive! You're using floating-point on an _8051_ ! ???
> 2) external graphics packs that take 32 bit floats on the
> same stack as 32 bit ints.
OK, that's an interesting reason.
Andrew.
> I don't understand this argument. .... Take a complex multiply for example. You have the addresses of four floating point numbers and they have to each be used at least twice. How are they mixed in with the FP numbers? You can use them explicitly as you need them ...
Its a generic point, so take a factor accumulator with the accumulator
and factor in memory.
( acc_a factor_a -- ) SWAP >R F@ R@ F@ F* R> F!
... works whether the stacks are mixed or split. But the simpler (on a
split stack system)
OVER F@ F@ F* F!
works only with split stacks. With a mixed stack system, there is no
portable way to directly access non-floating stack values if they are
underneath one or more floats. Since the ANS Forth standard does not
specify any mixed-floating stack manipulators, any portable ANS
mixed-stack code works with a seperate stack.
Specifying split stacks does not break legacy code, it just means that
code on a mixed stack system has to do a port if they are using
Forth200x code.
The main access to a growing public library of floating point routines
is the FSL, which already assumes split stacks. So in terms of public
code base, ANS Forth systems that have mixed floating point stacks
mostly have to do that port anyway, except for legacy mixed stack code
that is already out there. And not being able to claim to be a
Forth200x system won't interfere with the ability to run code written
in 1984.
> works only with split stacks. With a mixed stack system, there is no
> portable way to directly access non-floating stack values if they are
> underneath one or more floats. Since the ANS Forth standard does not
> specify any mixed-floating stack manipulators, any portable ANS
> mixed-stack code works with a seperate stack.
I kinda figured it worked that way. After I thought about it I recalled that
when I first tried a split stack I had to recode for the split, but I was
doing it for efficiency, not because it wouldn't run.
-- Charlie Springer
>Snakes alive! You're using floating-point on an _8051_ ! ???
Not us, but some clients do. It's easier to provide what they
ask for than to argue against it. If they find it easier to
use floating point, they finish writing their apps sooner,
which is good for them.
In nearly all cases that I have examined, the use of FP is to
generate data for display.
>> 2) external graphics packs that take 32 bit floats on the
>> same stack as 32 bit ints.
>OK, that's an interesting reason.
As far as I remember, there's at least one OpenGL implementation
that requires this.
>>Snakes alive! You're using floating-point on an _8051_ ! ???
> Not us, but some clients do. It's easier to provide what they
> ask for than to argue against it.
Haha! Ok, I've been there too. :-)
Andrew.
Or you can write code that works only on separate-stack systems, and
declare an environmental dependency on separate stacks.
> As a Forth programmer, the choices you have with that proposal
> standardized are:
>
> - You can write code that works on separate-stack systems and works on
> all different kinds of mixed-stack systems.
>
> - You can write code that works only on separate-stack systems.
>
> - You can write non-standard code.
>
> How does this take away choice?
I don't see that the choices are different at all.
On Dec 14, 5:42 am, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Wed, 13 Dec 2006 18:47:01 -0000, Andrew Haley
> >> 2) external graphics packs that take 32 bit floats on the
> >> same stack as 32 bit ints.
> >OK, that's an interesting reason.
>
>As far as I remember, there's at least one OpenGL implementation
>that requires this.
>
Unless something has changed, OpenGL specifies its API in C and the
parameter layout depends entirely on the C ABI for the target platform.
-- Trey
it seems that UM* and UM/MOD can be used for doing float calculations
if the mantissa is a double and the exponent is a single. leading to a
more compact system implementation.
3DUP = FDUP
cheers
The main difference is: Such a program is not guaranteed to work on
all ANS Forth systems, but it is guaranteed to work on all systems
conforming with the proposal.
The benefits of standardizing the proposal are:
* Programmers no longer need to declare an environmental dependency
when writing such programs.
* Users have an easier time seeing which program works on which system
if they just see that the program is a standard program and the
system is a standard system. Compare this to a standard program
with an environmental dependency; the user would have to checking
which systems satisfy the dependency; hunting through the
documentation for this is pretty tedious, especially for multiple
environmental dependencies. In the present case this is not even
among the system documentation requirements (well, "size of
floating-point stack" might indicate something about this). And
anyway, most programmers don't declare an environmental dependency
in such a case, so the user has no guidance at all about this
potential problem.
I prefer SRSHIFT.
But that is not the issue. The issue is that [some] separate stack
users are claiming mixed stack usage has no right to exist.
Their argument (as far as I can fathom) is that a separate stack is
"best" because mixed stack is a "pain". Well, surely it is for the
mixed stack users to state what is/isn't a pain for them. I don't
hear them complaining.
As yet no one has been able to explain how separate stack users
have been harmed by the mixed stack system. Until that happens
I can see no justification for its removal.
> But that is not the issue. The issue is that [some] separate stack
> users are claiming mixed stack usage has no right to exist.
Wow.
> Their argument (as far as I can fathom) is that a separate stack is
> "best" because mixed stack is a "pain". Well, surely it is for the
> mixed stack users to state what is/isn't a pain for them. I don't
> hear them complaining.
Maybe there aren't any? (Those making sure their code will work
independent of the stacking method.)
> As yet no one has been able to explain how separate stack users
> have been harmed by the mixed stack system. Until that happens
> I can see no justification for its removal.
As long as the separate stack user has no obligation that his code
should run on a unified stack system, he'll see no reason to complain.
This argument works for the unified stack user too. As long as no
standard (i.e. running on any plain vanilla ANS Forth) floating-point
code needs to be written, there is no problem.
However, when standard code is needed, a publisher must do extra work
to make it work on a unified stack system. Given the nearly
non-existent benefits, and the huge debugging problems that might pop up,
s/he probably won't do that. Or if they do, they may chose to write
a version for a unified stack specifically.
The current separate-stack controversy surely dissatisfies those Forth
users that can't use public domain code written for the alternative method.
At present, cautious Forth users must put in a lot of effort (i.e writing
stack-method independent) to make sure they won't be locked into an obsolete
system by their current vendor.
I see clear advantages for both users and vendors. And as any working code
(specific for a separate stack,specific for a unified stack, and specific
for any stack method) will still work after the change, what's the problem?
-marcel
> But that is not the issue. The issue is that [some] separate stack
> users are claiming mixed stack usage has no right to exist.
No, they aren't.
The point (well, one of the points) of a standard is to allow portable
programs. A it stands at the present time, it's somewhere between
difficult and impossible to write standard floating-point programs.
A standard, by its very nature, eliminates some possibilities. That's
what it's supposed to do.
> Their argument (as far as I can fathom) is that a separate stack is
> "best" because mixed stack is a "pain". Well, surely it is for the
> mixed stack users to state what is/isn't a pain for them. I don't
> hear them complaining.
I'm not surprised. That form of logic makes no sense at all. If they
liked it, why would they complain?
> As yet no one has been able to explain how separate stack users
> have been harmed by the mixed stack system.
How can you be harmed by something you don't use?
The point of this change is not to reduce harm to people who already
have an environmental dependency on a separate floating-point stack.
It's to raise the bar for Forth implementors, and make it easier to
write portable programs.
Andrew.
But it leads to a situation when someone can claim that they have an
ANS Forth implementation that provides Floating Point, and then when a
user tries to use code from the Forth Scientific Library, it doesn't
work.
If the *purpose* of a standard is to allow for the sharing of tested
code, well then ...
... at the present point in time, there is no harm to anyone in
Forth200x specifying split stacks, since the Forth-94 standard exists
and is stable. By standardising the present state of affairs, the FSL
can move to "portable Forth200x" code status.
For standard Forth-94 implementations with mixed stacks, that means
that using that publically available code base either requires:
(1) the overhead of a portability layer, or
(2) it requires recoding all portable Forth200x floating point code to
make it run on a mixed stack system.
And, of course those are the same options they face in December 2006.
So the only difference is making it easier to communicate. Being able
to say "Forth200x floating point" and "Forth-94 floating point". That's
it.
Being able to say to someone, "The Forth-94 floating point option for
that microcontroller leaves more free RAM, but the Forth-200x floating
point option provides access to the Forth Scientific Library."
The claim that it is trying to "outlaw" something simply does not stand
up to scrutiny.
It's very undesirable to publish a standard which implicitly encourages
some folks to cling to the standard it's hoping to replace. It's better
to incorporate as much common practice from the existing standard as
possible. That is why Forth-94 included on an optional basis some words
that were marked as 'obsolescent' to encourage users to phase them out.
They can now be removed from Forth200x (a meeting in 1998 already
voted to do that).
> For standard Forth-94 implementations with mixed stacks, that means
> that using that publically available code base either requires:
> (1) the overhead of a portability layer, or
> (2) it requires recoding all portable Forth200x floating point code to
> make it run on a mixed stack system.
No, it requires neither. It merely requires labeling the system and the
code, so that folks with FP code that has a dependency on mixed or
separate stacks know what a particular implementation provides. And
folks writing code of the other flavor can make the choice of whether to
take either of these two actions or just find a different Forth.
Implementors have a clear view of the market they're intending to serve.
If it's a personal-use system, as many are, standard compliance is
less of an issue. If the system is to be published, one must look at
intended users and decide what will serve them best. Then do the
implementation that way, clearly label it for what it is, and users can
choose intelligently.
> And, of course those are the same options they face in December 2006.
>
> So the only difference is making it easier to communicate. Being able
> to say "Forth200x floating point" and "Forth-94 floating point". That's
> it.
It is already that easy. Just label systems and programs "separate FP
stacks" or "mixed FP stacks". The situation is no worse then the
division issue or other implementation choices.
> Being able to say to someone, "The Forth-94 floating point option for
> that microcontroller leaves more free RAM, but the Forth-200x floating
> point option provides access to the Forth Scientific Library."
You can also make the identical statement using the current terminology.
It's clear from this discussion that there is still a mixed-stacks
constituency, and so long as that's the case I do not think it's
appropriate for Forth200x to insist on separate stacks.
Cheers,
Elizabeth
--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310-491-3356
5155 W. Rosecrans Ave. #1018 Fax: +1 310-978-9454
Hawthorne, CA 90250
http://www.forth.com
"Forth-based products and Services for real-time
applications since 1973."
==================================================
heres a start
: FL R> 2R> ;
: FS 2>R >R ;
: 2FL FL FL ;
: F+ 2FL F+ FS ;
etc and this will make a seperate stack simulation, but R stack can not
be used inbetween sequential floating point words.
> No, it requires neither. It merely requires labeling the system and the
> code, so that folks with FP code that has a dependency on mixed or
> separate stacks know what a particular implementation provides.
The FSL is so labelled, and so lets presume that the mixed stack
Forth-94 implementation is so labelled.
In what way does that label allow that Forth-94 implementation to run
code from the FSL without doing either (1) or (2)?
Don't read "using that" as "using any". "that publically available code
base" in the sentence refers to a previous paragraph, and means:
More likely define a stack "FS" and do the same thing with
: F@ F@ >FS ;
: F! >R FS> R> F! ;
: F+ 2FS> F+ >FS
defined in its own wordset so that in refining you can flip across to
the native Forth-94 mixed float operations for the most time-critical
words.
Even if you are going to end up porting the entire imported code base
to Forth-94 mixed float stack, that makes a useful tool for testing
whether the ported word definitions are in fact equivalent to the
operation of the words as originally defined for a split-stack system.
The label enables a prospective user of the code to make a choice as to
whether to use one of those approaches or find a Forth that will support
the FSL. I don't see how having Forth200x mandate separate stacks
changes anything, other than making implementors who favor mixed stacks
mad that they can't be compliant.
Of course if you broaden the scope of the question you broaden the
options that can be considered. I was addressing the situation facing
someone today with a Forth-94 with a mixed data-float stack.
Of course, there were all the things that go without saying before I
focused in on the FSL ... and maybe leaving them without saying
confused things.
1. The standard has on influence on whatever code that the user writes
for their own use. And as soon as they convert it to portable Forth-94
code, it also becomes portable Forth200x code, so it doesn't place
*additional* demands if they wish to share that code. So that narrows
down the search for any practical impact on the use of publically
available code base.
2. Any public code base that is static is quite clearly unaffected by
any standard enacted after it was published. So that narrows it down
further to an active public code library.
3. The only such floating point code base that I am aware of is the
FSL. If I am wrong about that, and there is another active public code
library out there for floating point code, correct me and I'll stand
corrected.
And so I pointed out that changing a public library from "ANS Forth
with an implementation dependency on divided data and floating point
stacks" to "Forth200x" makes no practical difference FOR THE USER OF A
MIXED STACK SYSTEM *other than* being easier to say.
> I don't see how having Forth200x mandate separate stacks changes anything
That's what I said, so I don't see what you are disagreeing with.
> I don't see how having Forth200x mandate separate stacks changes
> anything, other than making implementors who favor mixed stacks mad
> that they can't be compliant.
I guess you could have said that about any of the requirements of any
programming language standard. Rephrasing slightly, "I don't see how
having ANS Paralang mandate X changes anything, other than making
implementors who favor (not X) mad that they can't be compliant."
You're assuming _a priori_ that Forth200x won't change any Forth
system. If that's really the case there's no point bothering, is
there?
De jure, the only way to write conformant floating-point code at the
moment is to assume a mixed stack, and that makes programming hard to
do. De facto, people assume separate stacks.
As I see it, mandating separate stacks is simply formalizing the de
facto situation.
Andrew.
Or if writing code for a mixed stack, use implementation specific
knowledge of the size of a float on the stack to manipulate mixed data
... which is also not conformant code.
De jure, you can declare a dependency on mixed stacks, or a dependency
on separate stacks, or you can write code that will work on either.
I don't see that it's much harder to write code that runs anywhere
versus code that runs on mixed stacks. I haven't done much of that, but
what I saw was the problem of stack juggling with mixed sizes, and in
general my approach was to put the nonfloat items into variables or on
the return stack to keep them out of the way. It's a little less
efficient to get things out of variables (and of course it isn't
re-entrant) but it works. I figured it was generally more efficient to
@ ! cell-size data than to F@ F! floating data. However, whenever the
floating manipulations got too hard it was no big deal to declare a
floating variable or array, and F@ F! too.
I didn't see any benefit to writing nonportable mixed-stack code. Doing
it that way means you use nonportable methods for mixed stack juggling,
and they make the code harder to write, harder to debug, harder to
read, and there are no big advantages. (Unless you want the floating
point code to be used for, say, multitasking and you don't want to make
your variables be user variables. But then if you have locals, that
just stomps the problem like a 50-ton drop forge.
> As I see it, mandating separate stacks is simply formalizing the de
> facto situation.
I dunno. It could be argued that since it's a Forth standard, it hardly
matters. Should we give up allowing mixed stack systems to call
themselves standard? Should we give up on the dream of not requiring
apps that use a separate stack to be declared with an environmental
dependency (which they mostly don't bother to document anyway)?
However it works, a few Forth programmers will be very upset about it,
and fewer than one programmer in 50,000 will ever hear about it.
> > De jure, the only way to write conformant floating-point code at the
> > moment is to assume a mixed stack, and that makes programming hard to
> > do. De facto, people assume separate stacks.
> De jure, you can declare a dependency on mixed stacks, or a dependency
> on separate stacks, or you can write code that will work on either.
Well, not de jure as such, not unless you sign a contract saying that
the code will be ANS Standard, but that aside ... does the "law" say
something different in the version that was actually passed compared to
the draft?
dpANS94 says nothing about having to declare any dependency other than
needing a float stack more than six deep. It says that seperate stacks
are the default, and gives a mechanism for determining if that default
is in use, via an environment query that returns 0 rather than the
number of floats available.
The dpANS94 A.12 entry on the floating point stack says:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Floating-point stack: By default the floating-point stack is
separate from the data and return stacks; however, an
implementation may keep floating-point numbers on the
data stack. A program can determine whether floating-point
numbers are kept on the data stack by passing the string
FLOATING-STACK to ENVIRONMENT? It is the experience
of several members of the Technical Committee that with
proper coding practices it is possible to write floating-point
code that will run identically on systems with a separate
floating-point stack and with floating-point numbers kept
on the data stack.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I can see that you'd have to declare an dependency if you wrote
mixed stack code that relied on knowing the size of the floating
point item on stack (variously single, double, triple or quadruple),
since then you'd be using stack manipulation words in ways that
are not defined in the standard.
No, I'm hoping that most of what happens with Forth200x is that some
desirable features such as DEFER get added, and relatively few actual
changes are required of Forth94 systems to claim Forth200x conformance.
> De jure, the only way to write conformant floating-point code at the
> moment is to assume a mixed stack, and that makes programming hard to
> do. De facto, people assume separate stacks.
No, you can write perfectly conformant floating-point code labeled as
requiring separate stacks. You can also write conformant FP code
labeled as requiring mixed stacks. That's more informative and less
pejoritive-sounding than saying "my mixed-stack code isn't compliant."
> As I see it, mandating separate stacks is simply formalizing the de
> facto situation.
If it were really true that no one used mixed stacks I'd happily agree
with you. For example, I'd support it for Forth200x declared itself to
be two's complement, since that really is a de facto situation. But it
turns out that numerous folks have shown up in this discussion saying
they have, need, or prefer mixed-stack FP. Since that's the case, I
don't think it's appropriate to mandate separate stacks.
You can also do that if the proposal is standardized.
> That's more informative and less
>pejoritive-sounding than saying "my mixed-stack code isn't compliant."
Given the lack of labeling for current non-standard programs that
might be labeled as "standard with an environmental dependency on
separate stacks", I think not many programmers have a problem with
that sound in practice.
>If it were really true that no one used mixed stacks I'd happily agree
>with you. For example, I'd support it for Forth200x declared itself to
>be two's complement, since that really is a de facto situation.
Well, how about making an RfD?
> But it
>turns out that numerous folks have shown up in this discussion saying
>they have, need, or prefer mixed-stack FP.
Numerous ("very many" according to www.dictinary.com)? I count one.
But maybe I missed some. Can you name at least ten of the numerous
folks that have shown up?
I wonder, though, why you are resurrecting this discussion now.
That is pretty unavoidable in general; e.g., some people clung to
Forth-79, some to Forth-83. The only way to avoid this would be to
never update the standard.
> It's better
>to incorporate as much common practice from the existing standard as
>possible. That is why Forth-94 included on an optional basis some words
>that were marked as 'obsolescent' to encourage users to phase them out.
> They can now be removed from Forth200x (a meeting in 1998 already
>voted to do that).
I don't think it is useful to compare this to the separate-stackl
proposal, because the separate-stack proposal adds a feature (all
existing standard programs comply with that proposal), whereas
removing obsolescent words removes a feature (some standard programs
would become non-standard).
>It merely requires labeling the system and the
>code, so that folks with FP code that has a dependency on mixed or
>separate stacks know what a particular implementation provides. And
>folks writing code of the other flavor can make the choice of whether to
>take either of these two actions or just find a different Forth.
>
>Implementors have a clear view of the market they're intending to serve.
> If it's a personal-use system, as many are, standard compliance is
>less of an issue. If the system is to be published, one must look at
>intended users and decide what will serve them best. Then do the
>implementation that way, clearly label it for what it is, and users can
>choose intelligently.
Except that it does not work in practice: Systems are not required by
the standard to document whether they use separate or unified stacks,
and while programs that rely on that might be documented as standard
programs with an appropriate environmental dependency, hardly anybody
bothers with that. Overall, the Forth-94 compromise on this issue is
a failure. Fortunately, separate stacks have become a de-facto
standard, and the proposal is about making that de-facto standard more
formal.
Another thing about the "just label it" approach is that it does not
scale. Consider taking it further; taking it to the extreme: don't
require anything of a system, and just require appropriate
documentation about the environmental dependencies from a program.
Then every system would be a standard system, and every standard
program would come with a document about the environmental
dependencies that approaches the size of the ANS Forth document. Of
course nobody would bother to produce such documentation (we don't
even bother with labeling a dependency on separate stacks), so there
would be no standard programs, but hey, we would have lots of standard
systems.
>It is already that easy. Just label systems and programs "separate FP
>stacks" or "mixed FP stacks". The situation is no worse then the
>division issue or other implementation choices.
Except that there are no standard programs (without environmental
dependencies, usually undeclared) using FP, whereas there are lots of
standard programs using division (e.g., we changed Gforth from
symmetric to floored division since 0.6, and none of the code I have
run broke).
>It's clear from this discussion that there is still a mixed-stacks
>constituency, and so long as that's the case I do not think it's
>appropriate for Forth200x to insist on separate stacks.
Looking at the current poll standings in
<http://www.forth200x.org/fp-stack.html>, the situation is pretty
clearly in favour of separate stacks.
Compare this to the Forth-94 situation: If I had asked of the
programmers
[ ] I have written programs using FP words that work on both
separate-stack and unified-stack systems.
[ ] I have written programs using FP words with an environmental
dependency on a separate-stack or a unified-stack system, and
labeled them as such.
I do not think that as programmers would have answered yes to either
of these questions as have answered yes to
[ ] I have used (parts of) this proposal in my programs
In the early days of OpenGL bindings in bigFORTH, I had passed all C
parameters on the Forth data stack, and therefore, the floating point
numbers had to be put on the stack (I therefore have f>fd and f>fs to put
floating point numbers on the stack in double and single precission, native
format). This was ugly, and the primary reason why I rewrote my C library
interface. Now, the interface can deal with two stacks on the Forth side,
and moves the data to a separate stack for C. This might be slightly
slower, but at least it allows Forth users to pass the data in the order
that's documented in the manpages (and not in the reverse order as before),
and mixing integers and floats is much easier.
--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/
It's not important to me.
>> But it
>> turns out that numerous folks have shown up in this discussion saying
>> they have, need, or prefer mixed-stack FP.
>
> Numerous ("very many" according to www.dictinary.com)? I count one.
> But maybe I missed some. Can you name at least ten of the numerous
> folks that have shown up?
I haven't taken a census, here or anywhere else. FORTH, Inc. uses
separate stacks in SwiftForth, and mostly fixed-point fractions in
SwiftX (except for processors with hardware FP, where we use separate
stacks).
But the prior ANS Forth TC did make surveys to see how many people were
using various strategies that we were considering standardizing (we used
a FIG mailing list and solicited implementors to give us information and
poll their users), and found that quite helpful.
> I wonder, though, why you are resurrecting this discussion now.
I don't think I resurrected it, I just jumped in with an opinion.
> No, I'm hoping that most of what happens with Forth200x is that some
> desirable features such as DEFER get added, and relatively few actual
> changes are required of Forth94 systems to claim Forth200x conformance.
Aha! OK, that makes perfect sense. I understand where you're coming
from.
On the other hand, some of us would like the opportunity to correct
"mistakes" such as this one -- which, I suspect, would not get through
the net if the standard were being written today.
>> De jure, the only way to write conformant floating-point code at
>> the moment is to assume a mixed stack, and that makes programming
>> hard to do. De facto, people assume separate stacks.
> No, you can write perfectly conformant floating-point code labeled
> as requiring separate stacks.
Hmm. As I see it, it's either an ANS Standard program or it isn't,
and if it requires a separate floating-point stack, it isn't an ANS
Standard program. But this is quibbling about terminology, I accept.
> If it were really true that no one used mixed stacks I'd happily
> agree with you. For example, I'd support it for Forth200x declared
> itself to be two's complement, since that really is a de facto
> situation. But it turns out that numerous folks have shown up in
> this discussion saying they have, need, or prefer mixed-stack FP.
Steve has said he's shipped such a thing, but I don't think he's used
it himself!
As far as I can tell, because of the near-impossibility of
manipulating floating-point data on the stack, people end up needing
variables to write even simple floating-point code. (Does ANS even
have floating-point locals?) This is, crudely, very bad language
design.
Andrew.
> As far as I can tell, because of the near-impossibility of
> manipulating floating-point data on the stack, people end up needing
> variables to write even simple floating-point code. (Does ANS even
> have floating-point locals?) This is, crudely, very bad language
> design.
I just re-read this post, and I seem to be taking an unnecessarily
extreme position. I mean, it _is_ awkward, but near impossible?
Naaah. :-)
Andrew.
It is straightforward to write conformant FP code that *requires* the
default (though not the converse -- cf. *aside*).
And labelling THAT is NOT REQUIRED by the standard. Program authors who
do not label that dependency *are following Forth-94 to the letter*,
since it says:
12.4.2 Program documentation
12.4.2.1 Environmental dependencies
- requiring the floating-point stack to be larger than six items
(12.3.3 Floating-point stack).
12.4.2.2 Other program documentation
- no additional requirements.
IOW, while the situation that you are describing seems to be good
practice, and therefore good advice, its not in the standard. Putting
it into the standard (at least for the case that is actually feasible,
cf. *aside*), would require something along the lines of:
12.3.3 Floating-point stack
A last in, first out list that shall be used by all floating-point
operators.
The width of the floating-point stack is implementation-defined.
By default the floating-point stack shall be separate from the data and
return stacks. A program may determine whether floating-point numbers
are kept on the data stack by passing the string "FLOATING-STACK"
to ENVIRONMENT?. The size of a floating-point stack shall be at least 6
items.
A program that depends on the floating-point stack being larger than
six items has an environmental dependency.
++ A program that depends on the default of a separate floating point
stack without verification using the ENVIRONMENT? query has an
environmental dependency.++
*aside*
I don't believe that you can write conformant FP code that is portable
and requires mixed stacks. That's why there is no restriction imposed
on authors of floating point *code* by the proposal.
The reason is that there are no ANS Forth standard words that that have
mixed-stack semantics which transpose a float and a cell input value.
And there is no standard ENVIRONMENT? query that provides the number of
stack cells occupied by a float when it occupies a mixed stack.
So, what about an enviroment dependency on the presence of, eg,
NFN-ROT ( n1 f n2 -- f n2 n1 )
Such code could be considered portable, since defining those words once
for the foreign system allows the code to be imported.
However, while such a word may be provided to write portable
mixed-stack code, it does not introduce a dependency on a mixed-stack.
Such words are, in fact, more readily supported in a foreign separate
stack system than in a foreign mixed stack system - for a separate
stack, one portable definition exists for each such mixed stack
manipulation, while mixed stacks require different definitions for each
different floating size in cells. And on a separate stack system, many
of them will be NOPs or SWAPs.
Indeed, given this situation, it is possible for the code author to do
the ENVIRONMENT? query for floating point stack size, and load the
"split-stack" portable definitions of those stack juggling words if
nonzero, and then do an implementation-specific ENVIRONMENT? query for
their own mixed-stack system, and load the stack juggling definitions
for their implementation if it matches. However, if neither are the
case, the only portable step to take next is to print out an advisory
message and abandon the compilation.
> Hmm. As I see it, it's either an ANS Standard program or it isn't,
> and if it requires a separate floating-point stack, it isn't an ANS
> Standard program.
Where do you stand on symmetric versus floored division? You can write
ANS Standard programs in which it doesn't matter, by making sure you
never do a division that involves a negative number.
Or you can use FM/MOD or SM/REM and build MY-/ which does it your way.
I think there are other examples but that's the first one I remembered.
If it's either ANS Standard or not, you don't want to use anything but
the Core wordset, right? Use anything else and you have a dependency on
an extra wordset.
But the standard says, regarding floats, the only environmental
dependency a standard program needs to note is if it requires a
floating point stack deeper than six floats (its not spelled out, but I
presume that in mixed stack systems this implies that the stack must
accomodate at least 32 regular data stack items plus six floats).
And Forth-94 both defines seperate stacks as the default and gives a
mechanism for ensuring that the default is in fact present. So surely
the following is allowed in a ANS Standard program:
S" FLOATING-STACK" ENVIRONMENT? [IF]
INCLUDE fsl-loader.f
[ELSE]
CR .( This code assumes seperate data and floating point stacks.)
CR .( This system has a combined data and floating point stack.)
CR .( The words definitions you require should be examined to )
CR .( determine the modifications required for this system.)
CR
[THEN]
> Andrew Haley wrote:
>> Hmm. As I see it, it's either an ANS Standard program or it isn't,
>> and if it requires a separate floating-point stack, it isn't an ANS
>> Standard program.
> Where do you stand on symmetric versus floored division?
Same deal: there's no need to _require_ either, because of SM/REM and
FM/MOD.
> I think there are other examples but that's the first one I remembered.
> If it's either ANS Standard or not, you don't want to use anything but
> the Core wordset, right? Use anything else and you have a dependency on
> an extra wordset.
Fair point.
Andrew.
>The big issue for us is that mandating a separate stack
>essentially disenfranchises a lot of stable and mature
>existing code.
Oops! What a lot of discussion.
Let me summarise my corporate position in more detail.
1) I prefer a separate FP stack when coding.
2) I prefer that an entitlement is first made obsolete
and *then* removed. From a corporate point of view
this is actually more embarrassing then saying we
just stuck with mature code.
3) We have a lot of mixed FP stack code that has been
out there for a very long time and people still use
it.
4) Even if we convert all new systems to a separate FP
stack we will still have to support the mixed stack
code for some years.
5) Some very RAM-limited systems will continue to use
mixed stack code because it is a better technical
solution in that particular case.
Overall I am positive about declaring mixed-stack code
obsolete.
Stephen
A man who is right every time is not likely to do very much.
(Francis Crick, co-discover of DNA).
--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads
Seconded. A most excellent compromise.
Andrew.
> >The big issue for us is that mandating a separate stack
> >essentially disenfranchises a lot of stable and mature
> >existing code.
> Oops! What a lot of discussion.
> Let me summarise my corporate position in more detail.
...
> 2) I prefer that an entitlement is first made obsolete
> and *then* removed. From a corporate point of view
> this is actually more embarrassing then saying we
> just stuck with mature code.
> 3) We have a lot of mixed FP stack code that has been
> out there for a very long time and people still use
> it.
> 4) Even if we convert all new systems to a separate FP
> stack we will still have to support the mixed stack
> code for some years.
> 5) Some very RAM-limited systems will continue to use
> mixed stack code because it is a better technical
> solution in that particular case.
The question I have is to what extent that mixed FP *code* that is not
supported by a separate floating point stack implementation conforming
to Forth-94 is *presently* enfranchised. As far as I can see:
(1) any code that relies that relies on knowledge of the size of a
float when held on the stack is already outside the scope of Forth-94,
and
(2) any code that relies strictly on Forth-94 semantics, for example by
using locals for integers and addresses, will work without modification
on the Forth-94 default of a separate floating point stack.
If that is the case, then the present entitlement is soley for
implementations. I agree with the phase-out argument, so that is
reflected below.
The present state of the standard is that an implementation is allowed
to provide either the standard default or mixed-stacks; and that code
requiring the standard default neither has to declare an environmental
dependency nor has to use the tools already provided to ensure that the
default is available.
In terms of portability of code, that is a hole. And, as an aside
below, a hole at a portability threshold that can in some contexts be
crossed daily.
Three Resolutions to fill the hole:
I. Disenfranchise code that relies on separate floating point stacks.
At present, if this code relies on the split stack semantics in the
FLOAT vocabulary, they are only required to declare an environmental
dependency if they require a floating point stack more than size deep.
There is no labelling requirement if they require split stacks.
(I.a) Code that requires split stacks must declare an environmental
dependency
OR
(I.b) Code that requires split stacks must delclare an environmental
dependency unless it checks for the presence of split stacks with an
ENVIRONMENT? query.
II. Segregate mixed-stack code at the labelling level and enfranchise
mixed stack code at the operational level.
(II.a) Provide the missing semantics to portably define mixed stack
manipulations with a "MIXED-STACK-WIDTH" ENVIRONMENT? query that
returns 0 for separate floating point stacks and the number of stack
cells occupied by a float for a mixed stack system.
(II.b) Code that relies on the presence of a mixed stack must declare
an environmental dependency.
(II.c) An implementation that provides mixed-stack floats must document
that fact, and the stack cells occupied by a the floats implemented.
III. Disenfranchise mixed-stack implementations by phasing the
mixed-stack semantics out of the standard.
(III.a) To the statement that split stacks are the default, add the
declaration that mixed-stacks are OBSOLESCENT.
(III.b) Move the mixed stack stack picture of FLOAT words to a line
following the main description of stack word semantics, "For
mixed-stack implementations, the stack parameters in a mixed stack
system are:"
III.Note.
Where RAM is the dominant constraint, and stacks are in RAM, the
minimum Forth-94 stack memory usage is 96 bytes, plus 2 bytes for
indices where the indices cannot reside in a register. The RAM saving
of a mixed-stack system would come from re-using the 64 bytes (or more)
set aside for the data stack.
The smallest memory footprint from a split-stack system would therefore
be to implement the floating point stack in the data stack memory
space, building from the location of the maximum top of the data stack
toward the bottom of the data stack. This would require an additional
byte for floating point stack index if a register cannot be dedicated
to that purpose. Obviously, in terms of RAM usage, it places the same
constraint on the space for data stack items that is imposed by the
mixed stack.
A very nice summary. I agree with all of that, especially point #2.
Point 5 suggests that a mixed stack is not obsolete and
therefore not a candidate for obsolescence!
We all make arbitrary assumptions - typically derived from
our own situation. Recently someone expressed disdain
that anyone would use floating point on a 8051. It is actually
not unusual. Intel's popular 8052 BASIC microcontroller
used 8 digit BCD floating point. Today there are many
ANSI C compilers offering floating point for small cpu's
such as the 8051 and PIC.
It would be counter-productive for a Forth standard to
exclude itself from any potential market simply because
of an ideological notion of what is "best".
When the mixed-stack option has been eradicated from
the standard, what will be next? Do we ban BCD floating
point representation because binary is "best"? Of the binary
ones do we then insist on IEEE? Ban all rounding forms
other that round-to-nearest-even? The list could go on.
Creating a forth standard has [or should have] different
goals from creating a forth. The former is a process of
inclusion while the latter is one of exclusion.
It is impossible to create a forth that is good for every
situation. A Standard should ideally encompass all techniques
and leave it to the user to decide what is best. It is to their
credit that Forth-94 took exactly that approach and did not
make arbitrary decisions about what is "good" for everyone.
There was a time when I thought floored-division was "best".
I now know that many things don't have a "best". I'm glad they
don't because it makes the world that much more interesting :)
> "Stephen Pelc" <steph...@mpeforth.com> wrote in message news:4586a71d....@192.168.0.50...
>> On Wed, 13 Dec 2006 12:37:15 GMT, steph...@mpeforth.com (Stephen
>> Pelc) wrote:
>>
>> ...
>> 5) Some very RAM-limited systems will continue to use
>> mixed stack code because it is a better technical
>> solution in that particular case.
>>
>> Overall I am positive about declaring mixed-stack code
>> obsolete.
> Point 5 suggests that a mixed stack is not obsolete and
> therefore not a candidate for obsolescence!
Yeah, and I'm convinced Point 5 is wrong. Note that Steve doesn't
actually use this mixed stack system himself, just provides it! It is
almost certain that a separate stack is a better engineering choice,
even on an 8051, if you take the complexity of the application program
into account.
If you only take into account the difficulty of providing the Forth
system, maybe mixed floating-point is easier to do. But the instant
you actually want to _use_ this system, it's worse!
> We all make arbitrary assumptions - typically derived from our own
> situation. Recently someone expressed disdain that anyone would use
> floating point on a 8051.
Yes, me. I'm a very experienced 8051 programmer, and it is almost
certainly a foolish thing to do.
> It is actually not unusual. Intel's popular 8052 BASIC
> microcontroller used 8 digit BCD floating point. Today there are
> many ANSI C compilers offering floating point for small cpu's such
> as the 8051 and PIC.
And Ford built the Edsel.
> It would be counter-productive for a Forth standard to exclude
> itself from any potential market simply because of an ideological
> notion of what is "best".
> When the mixed-stack option has been eradicated from the standard,
> what will be next? Do we ban BCD floating point representation
> because binary is "best"? Of the binary ones do we then insist on
> IEEE? Ban all rounding forms other that round-to-nearest-even? The
> list could go on.
You are not addressing the core issue, which is that mixed-stack
floating point is horrible to use. It is a bad choice for Forth
application code.
Andrew.
Actually, you're not done with providing NFN-ROT. A full set of stack
juggling words would have to include 3^3 = 27 different versions of ROT in
order to cover all combinations of single-cell, double-cell, and
floating-point values. That's clearly not practical in ANS Forth, where each
word has to have a unique name.
I consider the fact that a Forth programmer has to take care about different
sizes of data types as being a major drawback of the language. Most other
high-level languages are completely transparent in this respect. On the
other hand, floating-point arithmetic has never been the main focus of
typical Forth applications. But even the simple fact that you have to write
ROT in order to SWAP a single-cell item and a double-cell item looks prettı
strange to me.
It's obvious that a separate floating-point stack is the solution of choice.
However, I feel uneasy about the fact that implementors tend to solve so
many problems by introducing new stacks. Meanwhile, we have a data stack, a
return stack, a floating-point stack, a control flow stack, a loop parameter
stack, a locals stack and who knows what else. IMO, having a single stack
for almost everything is one of the highlights of the language. The need to
keep track of multiple stacks in parallel doesn't make a programmer's job
easier.
<snip>
>
> It's obvious that a separate floating-point stack is the solution of choice.
> However, I feel uneasy about the fact that implementors tend to solve so
> many problems by introducing new stacks. Meanwhile, we have a data stack, a
> return stack, a floating-point stack, a control flow stack, a loop parameter
> stack, a locals stack and who knows what else. IMO, having a single stack
> for almost everything is one of the highlights of the language. The need to
> keep track of multiple stacks in parallel doesn't make a programmer's job
> easier.
it is possible to give a single cell pointer to all floats, but then a
simple gc is required for intermediate results or some limit on
intermediate complexity in the calculation.
FSP and SP to switch active data stack from integer to float stack
space is a very portable solution which removes continual pointer
swapping on a register light processor. and it allows UM/MOD etc to be
used in the float operation words.
if these are null compiles on a seperate stack system, then where is
the loss?
Fortunately, most of these are conceptual entities only. The control
flow stack, for example, is usually just the data stack being used to
keep track of origin and destination addresses during compilation. The
loop parameters are usually kept on the return stack, and locals are in
a temporary storage place but not really treated as a stack by the
programmer. The separation of the data and return stacks is very
helpful, and floating point stacks usually come with the hardware. 95%
of the time the data stack is the only thing you really have to keep
track of.
The heart of most algorithms for solving programming problems is
creating the appropriate data structure(s). If that turns out to
be a stack (say because you are doing recursive-descent parsing--
of course some use linked lists or trees for this, but I prefer
a stack), why in the world would you
a) hesitate to create it?
b) think it was somehow superior to mingle it with
the already extant data stack in the name of some
meaningless unity?
Keeping track of multiple stacks can and should be made as
invisible as possible. This is, after all, how the separate
fp stack does it: F@ and F! make no reference to the fp
stack, per se. For example, the recursive descent parser I
wrote to do formula translation uses a stack to hold 2 pointers
and an operator token. The words $pop and $push move these
to/from the data stack. I see no problem in keeping track of
what's going on.
But suppose for some reason I needed 10 new stacks. I could
use these same names, but redefined so they take the name
of the desired stack as an argument. This would also include
access to the width of the user stack (in units of cells).
Thus I could say
ptr-stack $pop ( -- end beg token)
or
ptr-stack $push ( end beg token -- )
and if I were accessing a different stack (perhaps with a
different width) it would be via
other-stack $pop ( -- arg1 arg2 ... )
etc. IMO any problems are more imaginary than real.
--
Julian V. Noble
Professor Emeritus of Physics
University of Virginia
What would you say if someone suggested introducing separate stacks for
double numbers, for addresses, or for flags? These can have advantages in
the implementation as well as in applications. People don't do that, because
they value the elegance and simplicity of a single data stack. No one
disagrees that it is often useful to create specific data structures like
additional stacks for application data, especially if these data are
structures. But not for floating-point numbers, unless the language enforces
it. All other high-level languages I know seamlessly integrate
floating-point arithmetic, and even overload arithmetic operators for
integer and floating-point operations.
With a separate floating-point stack, we give up a part of the simplicity
and elegance of a single data stack. It's a price Forth programmers have to
pay. It's obvious that for ANS Forth the unique stack model is not a
practical solution.
> Keeping track of multiple stacks can and should be made as
> invisible as possible. This is, after all, how the separate
> fp stack does it: F@ and F! make no reference to the fp
> stack, per se. For example, the recursive descent parser I
> wrote to do formula translation uses a stack to hold 2 pointers
> and an operator token. The words $pop and $push move these
> to/from the data stack. I see no problem in keeping track of
> what's going on.
Whenever you use floating-point numbers, you have to keep track of two
stacks. The stack diagrams of F@ and F! in a system with separate stacks are
not as simple as the ones of @ and !, and the separate stack is definitely
not invisible. Of course, everyone can get used to it. But with a separate
stack, the floating-point word set looks more like a library that has been
attached to the system, instead of an intregral part of the system, as it
does in most other programming languages.
John Doty's LSE solves that simply. He makes all types the same size on
the stack. He makes stack items big enough to handle his floats. Then
if you want to save memory space or disk space you can track what size
things actually are and fetch and store them in smaller sizes.
This approach solves your problem with utter simplicity, at the cost of
some efficiency. If it's a problem to you to handle different sizes of
data types then I recommend his solution to you.
> >> It's obvious that a separate floating-point stack is the solution of
> >> choice. However, I feel uneasy about the fact that implementors tend to
> >> solve so many problems by introducing new stacks. Meanwhile, we have a
> >> data stack, a return stack, a floating-point stack, a control flow stack,
> >> a loop parameter stack, a locals stack and who knows what else. IMO,
> >> having a single stack for almost everything is one of the highlights of
> >> the language. The need to keep track of multiple stacks in parallel
> >> doesn't make a programmer's job easier.
Almost every one of these is commonly implemented on the data stack or
the return stack. The result is that programmers must continually take
care about the dependencies among them. Forth programmers eventually
get the dependencies so deeply ingrained into their reflexes that they
don't even remember how bewildering it was while they were learning.
The control-flow stack is typically implemented on the data stack. So
it interferes with the use of the data stack for data while compiling
control structures. You can't do
: FOO .... [ compute some stuff ] IF .... LITERAL ....
because IF leaves stuff on the data stack and your data is unavailable
until the control-flow stuff is gone.
The loop stack is typically implemented on the return stack. You can't
do
.... >R 50 0 DO .... R@ ....
because your data on the return stack is unavailable until the loop
parameters are gone. If you leave a loop with EXIT (or nonstandardly
with an unnested control structure) then you have to remember to use
UNLOOP to get rid of the loop parameters or they'll crash your return
stack. That's not a big deal, just one logical step to remember. But
having the return stack unavailable is a big inconvenience that you
learn not to notice.
The locals stack is typically implemented on the return stack. But it's
implemented in a special way that lets it work inside loops and with
extra data >R'd above it. It doesn't actually take much extra
complexity to do that, and if you use locals you don't care about the
problems of extra stacks and under-the-hood complexity anyway. When you
leave a routine you automatically destroy all its locals. When you call
a new routine all the old locals become unavailable. Some other
languages provide ways to get at locals from parent words, but I've
never heard a Forth programmer complain about lacking that. Locals are
the most unobtrusive re-use of an existing stack I've ever heard of,
and it's because they're kept entirely under-the-hood with all their
mechanisms hidden and no way for users to tinker with them at all.
People don't think of locals as a stack, they think of them as
temporary named variables, and they don't care how they're implemented
as long as they work. And that makes all the difference.
The wordlist search stack is typically implemented as a linked list in
memory. It doesn't interfere with anything else. The list doesn't
change real often and it doesn't need to be incredibly efficient.
Once you feel the need for an extra stack, you have to either deal with
new commands to handle the extra stack or else you'll have to juggle
the new stack items on an existing stack. Neither is ideal. But the
stack juggling will be a complication for app programmers as long as
they use a mixed stack system. New commands for new functions is
something they're used to, and not as bad. If you want simplicity, you
do better to avoid the need for the extra stack in the first place. So:
The best way to avoid trouble with floating point numbers is not to
have a separate floating stack or a mixed stack, but to avoid using
floating point numbers. Don't accept the complications inherent in
floating point unless you really need to.
The best way to avoid trouble with the control-flow stack is to not do
any nested control-flow structures. Then you can get by with one short
data structure to handle all your control-flow needs. If you nest
control structures your routine will inevitably be a bit long. Don't do
it unless you need to.
I'm not sure the best way to handle a loop stack. If you aren't real
constrained for space (and maybe for registers) then I'd say just make
a separate loop stack and forget it. You already have all the words you
need to access it. DO ?DO I J UNLOOP LOOP +LOOP A separate loop stack
needs no new user words at all. It gives app programmers more power and
less complexity, in return for trivial extra complexity for the system.
Say you make the loop stack deep enough to handle 128 loops. A forth
program with 128 nested loops has problems that a mixed stack can't
solve. A separate loop stack is better than a mixed stack unless your
system has severe resource constraints. However, you might consider
what Chuck has been doing. He decided he didn't need loops at all. He
made a few new words, like one to autoincrement the top return stack
item, and then he felt like he didn't need the overhead of a loop
mechanism. So, for example, if you have two addresses on stacks or in
registers or something and you can fetch and store them
nondestructively, then it's no big deal to fetch from one and store to
the other and increment them both. You need a number to track when to
quit. Maybe you don't need a loop mechanism at all.
Locals cause the least trouble of any mixed stack I've seen, but you
can eliminate any trouble from them by eliminating locals.
> > The heart of most algorithms for solving programming problems is
> > creating the appropriate data structure(s). If that turns out to
> > be a stack (say because you are doing recursive-descent parsing--
> > of course some use linked lists or trees for this, but I prefer
> > a stack), why in the world would you
> >
> > a) hesitate to create it?
> >
> > b) think it was somehow superior to mingle it with
> > the already extant data stack in the name of some
> > meaningless unity?
>
> What would you say if someone suggested introducing separate stacks for
> double numbers, for addresses, or for flags?
In each case I'd wonder whether the advantages were worth the
complexity. Rick Hohensee implemented a system where the size of a
stack item was variable. Any time you wanted you could switch to a
double-wide stack and then manipulate doubles with DUP OVER SWAP etc.
Or switch down to bytes. Or up to quad. It was elegant. Somehow I never
used it beyond playing with it a little.
Rick also suggested a separate address stack. Randy Dumse had suggested
something like that too. I implemented it. It allowed some common tasks
to get done much simpler, but I found it easy to use it in ways that
were complex and that required a lot of new names for new functions.
Some of the new names could be avoided by swapping the data and address
stacks -- when you made the address stack be the data stack then you
could use all the usual stack words on it. In my limited testing, it
didn't result in simpler coding. But if I'd tested it enough to find
out how to work with it well, the results might have been simpler. They
were sometimes simpler, and with practice I might have avoided the
complications.
> These can have advantages in
> the implementation as well as in applications. People don't do that, because
> they value the elegance and simplicity of a single data stack.
Usually I don't do it because when I make an extra stack and use it for
anything more than one special application, I wind up not writing
Forth. When I do Forth at least there's a small band of other Forth
programmers to talk to. When I make a new Forthlike language that's
different enough that regular Forth programs won't run on it or vice
versa, then I'm all alone with nobody to talk to.
> No one
> disagrees that it is often useful to create specific data structures like
> additional stacks for application data, especially if these data are
> structures. But not for floating-point numbers, unless the language enforces
> it. All other high-level languages I know seamlessly integrate
> floating-point arithmetic, and even overload arithmetic operators for
> integer and floating-point operations.
I don't like operator overloading. You get the computer to make
complicated judgements and do stuff behind your back, and then you need
complicated debugging tools to figure out what went wrong.
I think it's better for Forth to keep it simple. Do things that are
close to what the processor is actually doing -- but simplified in
simple consistent ways. Then it's my job to write a program that does
what the application needs -- high-level commands that are simple and
consistent and that fit the problem to be solved. And it's my job to
find a reasonably simple way to get from the simple processor commands
to the simple application commands. When the system gives me complex
tools that do complex things with subtle interdependencies, it *doesn't
help*.
> With a separate floating-point stack, we give up a part of the simplicity
> and elegance of a single data stack. It's a price Forth programmers have to
> pay. It's obvious that for ANS Forth the unique stack model is not a
> practical solution.
The problem is big unwieldy floating point numbers. If you need them,
you have to deal with the problem. So OK, a 64-bit Forth can handle
64-bit floating point numbers just like anything else. Problem solved,
if all you need is 64-bit floating point. You get some inefficiency
when for every fp arithmetic op you have to move two numbers to the
onchip floating stack, do the operation, and move the result back to
the data stack. If that inefficiency is a problem, you can recode your
lowest-level words into something more efficient. Assembly, C, a
special Forth wordset that leaves things on the fp stack, whatever
works. But you can get it running first and do tests to find out where
the slow parts are before you need those complications.
> Whenever you use floating-point numbers, you have to keep track of two
> stacks. The stack diagrams of F@ and F! in a system with separate stacks are
> not as simple as the ones of @ and !, and the separate stack is definitely
> not invisible. Of course, everyone can get used to it. But with a separate
> stack, the floating-point word set looks more like a library that has been
> attached to the system, instead of an intregral part of the system, as it
> does in most other programming languages.
Most other languages don't give you access to those stacks anyway.
Write your algebraic expression using variables in infix notation.
Trust the system to figure out what you want and do it for you.
I say, if you need to track data that's hard to juggle on a single
stack, then extra stacks can help. Better when they have
clearly-defined functions, preferably functions that don't require much
interaction with other stacks. Better when they're completely separate
stacks that don't interfere with the use of other stacks. The very best
is to arrange it so your data isn't hard to juggle on a single stack.
But sometimes you have to be real smart to do that.
> > The reason is that there are no ANS Forth standard words that that have
> > mixed-stack semantics which transpose a float and a cell input value.
> > And there is no standard ENVIRONMENT? query that provides the number of
> > stack cells occupied by a float when it occupies a mixed stack.
> > So, what about an enviroment dependency on the presence of, eg,
> > NFN-ROT ( n1 f n2 -- f n2 n1 )
> > Such code could be considered portable, since defining those words once
> > for the foreign system allows the code to be imported.
> Actually, you're not done with providing NFN-ROT. A full set of stack
> juggling words would have to include 3^3 = 27 different versions of ROT in
> order to cover all combinations of single-cell, double-cell, and
> floating-point values. That's clearly not practical in ANS Forth, where each
> word has to have a unique name.
In this context, what would be provided would be what the code in
question uses. And it should be clear that with the naming convention
above -- an ideogram of the input stack picture and the equivalent
single-cell stack operation -- that it is clearly practical to name
each specific stack juggling operation in use without any namespace
contention.
> I consider the fact that a Forth programmer has to take care about different
> sizes of data types as being a major drawback of the language. Most other
> high-level languages are completely transparent in this respect.
It is one of the features of the language as well. If I want to
manipulate data without worrying about data typing, memory allocation,
details of the input format of the data file, I program in AWK. If I'm
programming to meet some resource constraint - space, processing speed
- I find that the benefits of early availability of compiled code for
testing and of being in control of the data being used outweighs the
benefits of auto type conversions.
> On the other hand, floating-point arithmetic has never been the main focus of
> typical Forth applications. But even the simple fact that you have to write
> ROT in order to SWAP a single-cell item and a double-cell item looks prettý
> strange to me.
Then SD-SWAP instead. After all, extending the language to suit your
preferences is what you are supposed to be doing.
However, excessive stack juggling in high level code is typically
symptomatic of poorly designed stack interfaces, so if those annoyances
are not encapsulated within low level code, there is probably a design
issue to solve.
> It's obvious that a separate floating-point stack is the solution of choice.
> However, I feel uneasy about the fact that implementors tend to solve so
> many problems by introducing new stacks.
Quite so. Far better if they solved more problems with hashed linked
lists, and not so many with stacks. And if Forth implementors have a
bias toward LIFO data structures, what about C-family languages and
their predilection to using buffered queues for things that could be
implemented as hashed linked lists? Scandalous.
Seriously, a LIFO data structure is a standard solution, and
familiarity with working with stacks makes it a natural solution to use
where it works.
> Meanwhile, we have a data stack, a
> return stack, a floating-point stack, a control flow stack, a loop parameter
> stack, a locals stack and who knows what else.
The control flow stack is usually the data stack. The loop parameter
and locals stack is usually the return stack. Abstracting from those
equivalences is required to allow standard implementations to have
different sized entities on the stack and enfranhises an implementation
to split off any of those stacks where there are benefits with a
specific processor from doing so.
> What would you say if someone suggested introducing separate stacks for
> double numbers, for addresses, or for flags? These can have advantages in
> the implementation as well as in applications. People don't do that, because
> they value the elegance and simplicity of a single data stack. No one
> disagrees that it is often useful to create specific data structures like
> additional stacks for application data, especially if these data are
> structures. But not for floating-point numbers, unless the language enforces
> it. All other high-level languages I know seamlessly integrate
> floating-point arithmetic, and even overload arithmetic operators for
> integer and floating-point operations.
>
> With a separate floating-point stack, we give up a part of the simplicity
> and elegance of a single data stack. It's a price Forth programmers have to
> pay. It's obvious that for ANS Forth the unique stack model is not a
> practical solution.
It's a matter of cost-benefit tradeoffs. In most of the instances you
cite above, the cost of implementing a separate stack (in code size &
complexity) far outweighs any "convenience" that might be achieved. In
the case of floating point, however, most processors with hardware FP
have a separate on-board stack, so you gain a lot of performance as well
as convenience by using it. And the convenience mainly comes from being
able to use full-size IEEE format values, which are extremely ungainly
on the data stack. I don't know, but I strongly suspect that most
mixed-stack FP implementations use a 32-bit representation, which is
tolerable from the programming point of view (you can use all the 2's
operators) but loses precision.
Languages that make data types "transparent" do so at a considerable
cost in the complexity of the compiler, with accompanying loss of
control by the programmer. Again, a matter of tradeoffs, personal
preference, and application constraints. Forth programmers tend to be
control freaks -- we like knowing exactly what's being generated for us
by the compiler, and being able to manipulate it directly if we wish.
> Whenever you use floating-point numbers, you have to keep track of
> two stacks. The stack diagrams of F@ and F! in a system with
> separate stacks are not as simple as the ones of @ and !, and the
> separate stack is definitely not invisible.
IME a separate stack is easier, precisely because you don't have to
keep track of it. On a combined stack, you do have to keep track of
where floats and ints are.
A concrete example:
: f@+ ( a - a') ( - f) dup f@ float+ ; ok
: dot-product ( a1 a2 len) ( - f)
0.0e0 0 do f@+ swap f@+ f* f+ loop 2drop ;
Andrew.