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

Top 10 Language Constructs (Forth)

14 views
Skip to first unread message

Bruno Gustavs

unread,
Jul 14, 2000, 3:00:00 AM7/14/00
to
What do you think are the top ten language constructs in Forth?
Please don't answer in terms of OO concepts, but try to restrict
yourself to those statements you really use to cope with your
daily work.

Curious why I'm asking this question? In spite of all requirements
engineering effort we know exactly *how* to solve problems
with computer languages but know fairly, *what* we're doing
during this process.

Regards
Bruno Gustavs

Bernd Paysan

unread,
Jul 14, 2000, 3:00:00 AM7/14/00
to
Bruno Gustavs wrote:
> What do you think are the top ten language constructs in Forth?
> Please don't answer in terms of OO concepts, but try to restrict
> yourself to those statements you really use to cope with your
> daily work.

I'm not sure if this is what you are looking for, but Forth is mostly
words, and there are few language constructs. Those that are (not
necessarily in that order), are:

10. RPN, i.e. implicit parameter passing on stack with multiple return
values. This allows to factor common parts by just cut&pasting the equal
parts out of the code and replace it by the factor. IOW you can do
"reverse cut&paste programming". Since most languages highly favour
forward cut&paste programming and that tends to code explosion (of code
that's probably slightly deffective and copied all over the place before
the bug is eliminated). It's not a language construct as "IF THEN", but
a sort of meta-language construct.

9. CREATE DOES>. This is a very powerful and lightweight concept to
"curry" data and functions together. I use it in almost any program.

8. The interpreter. If you know how to use it in the final application,
you see how much work is already done and how little things you have to
add to get the real work done. As item 1, it's a meta-language
construct, though it manifests in words as EVALUATE, INCLUDED and such.

7. The interpreter, again, this time to interactively test words. It's a
different feature (and some debugger environment allows to interactively
test C functions, too), but ultimatavely, using words interactive shows
you the way how to develop an application language that suits item 3.

6. POSTPONE/IMMEDIATE. Generating code is often a good idea, and you
naturally extend your language to fit what you need.

5. IF ELSE THEN, DO LOOP, BEGIN WHILE REPEAT.

4. : <name> ;

3. Create, Variable, Value, Constant, ...

2. Comments like ( .. -- .. ) or \ to the end of line

1. All the other non-immediate words.

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

Julian V. Noble

unread,
Jul 14, 2000, 3:00:00 AM7/14/00
to
Bruno Gustavs wrote:

> What do you think are the top ten language constructs in Forth?
> Please don't answer in terms of OO concepts, but try to restrict
> yourself to those statements you really use to cope with your
> daily work.
>
> Curious why I'm asking this question? In spite of all requirements
> engineering effort we know exactly *how* to solve problems
> with computer languages but know fairly, *what* we're doing
^^^^^^ "faily little" ?

> during this process.
>
> Regards
> Bruno Gustavs

The fact that the compilation mechanism is

a) included in the CORE wordset;
b) open to the user

is IMO the most important aspect of Forth.

The next most important is the use of two stacks to separate data
(integers, flags, addresses) from return addresses used by the threading
mechanism. (Look at what happens in Java with its single stack.) Direct
access to the stack(s) is a sine qua non of Forth and truly
distinguishes it from other languages. Among other things it permits
much finer grained decomposition of programs into subroutines, without
(much) loss of performance in subroutine-calling overhead.

Third is the philosophy that things should be computed (executed) rather
than decided. That is, the operation of branching constructs like
IF...ELSE...THEN, BEGIN...WHILE...REPEAT or DO...LOOP is accomplished
via immediacy--execution during the compilation process.

The stack manipulation and memory manipulation words are not special to
Forth, they are just concealed in other languages. They often appear as
"noise" words in excessively verbose definitions, so good style tends to
find circumlocutions such as VALUE.

Forth permits several forms of self-modifying code--usually a no-no, but
often immensely valuable for certain tasks. One of the simplest is
vectoring, but Forth also allows EVALUATE, a Lisp-like construct. So in
principle PostScript and other specialized interpretive languages could
be written in Forth. Not everyone agrees that EVALUATE is good. Wil
Baden uses it, Anton Ertl eschews it--their opinions are cogent and
well-reasoned--probably you can find them archived in deja.com .

And I like Forth's simplicity: everything is a subroutine, so you don't
have to wonder about the distinctions between functions, subroutines,
data structures, operators, memory allocators, etc. etc. Fortran had way
too many things for me to keep track of. Forth, being extensible, let me
do everything I used to do with Fortran, and made many things easy that
are hard in Fortran.

In my own programming (mostly number-crunching and some computer
algebra) I find I use decision structures like jump tables and state
machines frequently. The words ' ("tick") and , ("comma"), and
CREATE...DOES> are key to constructing them. I only rarely have found
uses for :NONAME and COMPILE, . My use of these constructs can be seen
in some of the programs at my Computational Methods website

http://Landau1.phys.virginia.edu/classes/551/

under "Forth system and example programs".

--
Julian V. Noble
j...@virginia.edu

"Elegance is for tailors!" -- Ludwig Boltzmann

Note mailing address change

Department of Physics
University of Virginia
P.O. Box 400714 <---Required now!
Charlottesville, VA 22904-4714

Steven Wheeler

unread,
Jul 14, 2000, 3:00:00 AM7/14/00
to
Bruno Gustavs wrote:
>
> What do you think are the top ten language constructs in Forth?
> Please don't answer in terms of OO concepts, but try to restrict
> yourself to those statements you really use to cope with your
> daily work.

I'm not going to give you a list; I'm sure others will do that. Besides
the other things I like about Forth, one thing that will certainly be
mentioned is the separate data stack. What I really appreciate about
this is that its contents are readily visible and manipulable. How many
other languages can you name which allow a function to have multiple
return values (other than by returning a pointer to a memory region
containing the values)?

- wheels

cLIeNUX user

unread,
Jul 15, 2000, 3:00:00 AM7/15/00
to
j...@virginia.edu...
>Bruno Gustavs wrote:
>
>> What do you think are the top ten language constructs in Forth?
>> Please don't answer in terms of OO concepts, but try to restrict
>> yourself to those statements you really use to cope with your
>> daily work.
>>

NO DEFAULT SYNTAX
To the above I would add that numbers are verbs. A number does "put
yourself on the stack". All tokens therefor have an implicit action. There
is therefor no need for a syntax, and so there is no default syntax.
Things can be acted upon as soon as they are extracted from the input
stream. Words can change the default syntax, and the input buffer is
anyone's to use. This is startling when you see what you can do with it.
RPN isn't a syntax, it's JUST DO IT.

RPN is understandably somewhat off-putting, but it's right up there with
two stacks and the integral compiler for keeping things efficient. I'm
writing a language based on Forth, but very different, and I haven't
even considered making it not be RPN.

SUCCINT VIRTUAL MACHINE
Forth can be a machine, or a virtual machine. The ANS Forth Standard, if I
read it right, expresses a range of such machines as Standard. For any
particular instance of a Forth, standard or otherwise, the machine in
question is utterly un-ambiguous. The value of that is hard to express.

NO `PUNCTUATION'
As a style matter, Forth doesn't attempt to make an artificial distinction
between punctuation and "other". Most languages sortof assume that
puntuation marks are somehow distinct from letters and underscore. They
certainly aren't to a computer. This is a stylistic limitation Forth
lacks.

Forth's downsides are;
it models a machine that doesn't run well natively on most normal
CPUs, but the hit is not as bad as most other "interpreters". This
"impedance mismatch" becomes a huge advantage if you happen to have
a Forth engine for a CPU, which I believe are fundamentally
superior to register machines. This is indicative of the
programming ability of the author of Forth, Chuck Moore. He wanted
a better language, and his better language inately implies a
genuinely superior CPU.
If you have a commodity one-stack CPU, we are blessed with
wonderful commercial optimizing Forth compilers, which I personally
tend to consider an additional concept to Forth itself, but
certainly a valuable enhancement for viability in the highly
competitive global mission-critical bla, zay, woof and/or WOOF,
as the case may be.

Forth namespace tends to explode. "Keep it simple" means have
jillions of little "it"'s.

Having the threader, the definer of new words, AKA the
compiler, integral to the interpreter and the virtual machine
is bewildering. It's a full axis on understanding Forth that
is absent elsewhere. CREATE/DOES> that Julian mentioned means you
also have control of the threader as well as the rest of the
language. CREATE/DOES> is also perhaps the "If you get that, you
got it." of Forth.
Having said that, that axis isn't really absent elsewhere.
Programming in a batch-compiled language like C is invariably
fraught with wondering what the compiler will do with
such-and-such construct. Forth just makes it explicit, but it's
tricky, and a bit more of an initial hurdle type thing.

Forth's design implies that you can get at the guts of it. I
believe this openness and flexibility has played to Forth's
disadvantage in the commercial marketplace so far.

In general, Forth suffers from extreme flexibility.

Note that Forth's essence is utterly antithetical to a listing of discrete
features. RPN works with 2 stacks which works with the fact that it's an
interpreter and a "compiler" etc. etc. etc. Listing the features is like
saying a great historic chess game had some pawns, some bishops, a couple
kings...


Rick Hohensee
ri...@clienux.com

Bernd Paysan

unread,
Jul 17, 2000, 3:00:00 AM7/17/00
to
cLIeNUX user wrote:
> Forth's downsides are;
> it models a machine that doesn't run well natively on most normal
> CPUs, but the hit is not as bad as most other "interpreters". This
> "impedance mismatch" becomes a huge advantage if you happen to have
> a Forth engine for a CPU, which I believe are fundamentally
> superior to register machines.

That's wrong. Forth is as good for running on a register-oriented CPU as
other languages like C or Fortran. It just takes the same amount of work
to write an optimizing compiler backend for Forth as for any of the
other languages (you save a lot of time on the frontend, though),
something most Forth authors are reluctant to do, because they have
better things to do.

Anton Ertl has several papers about Forth native code generation on
http://www.complang.tuwien.ac.at/projects/forth.html, which you really
should read.

F...@ultratechnology.com

unread,
Jul 17, 2000, 3:00:00 AM7/17/00
to
In article <3972CBBE...@mikron.de>,
Bernd Paysan <bpa...@mikron.de> wrote:

> cLIeNUX user wrote:
> > Forth's downsides are;
> > it models a machine that doesn't run well natively on most
normal
> > CPUs, but the hit is not as bad as most other
"interpreters". This
> > "impedance mismatch" becomes a huge advantage if you happen
to have
> > a Forth engine for a CPU, which I believe are fundamentally
> > superior to register machines.

I see two statements here. The first is that Forth does not take
full advantage of the architectural features of registers based
machines. The second statement is that Forth engines are


fundamentally superior to register machines.

The first statement has been made by other people. As I recall
the way Wil Baden explained this one time was that some algorithms
require juggling a bunch of parameters and that these may be
difficult to express in Forth. Wil has stated that these sort
of problems are more easily expressed in some other language
than Forth where the stacks only provide easy access to things near
the top of the stacks and where access to a bunch of parameters
can become ugly.

I think that is the point that was being made about Forth and
register machines. Not that Forth can't compile efficiently
on register based machines, but rather that Forth does not take
full advantage of all the features on these machines. Because
Forth uses the stack notation it is not always the best match to
register based machines.

Now as to Forth machines being superior to register machines
the statement requires a lot of context in which superior has
a definition. I think the simplest interpretation is that
the match between Forth and Forth machines is
superior to the match between Forth and register machines
because Forth may not take full advantage of the register
based designs. In that context it seems like a very defensible
statement.

Of couse superiority is an opinion. In the context of cost,
power consumption, performance/cost, ease of programming (in Forth),
and things like that I would agree that Forth machines are superior
to register based machines. But it is just my opinion. I also
think register based machines are superior for things other than
Forth so I think the statment needs a lot of context to have any
real meaning.

> That's wrong. Forth is as good for running on a register-oriented CPU
as
> other languages like C or Fortran. It just takes the same amount of
work
> to write an optimizing compiler backend for Forth as for any of the
> other languages (you save a lot of time on the frontend, though),

but the issue is not just the internals of the compiler, but the
Forth source code itself. Stack based notations are just not the
easiest way to express all programs.

> something most Forth authors are reluctant to do, because they have
> better things to do.

I think the issue is more writing Forth code than writing Forth
compilers. Despite the fact that I prefer Forth for what I do
I don't think it is the best way to express everything.

> Anton Ertl has several papers about Forth native code generation on
> http://www.complang.tuwien.ac.at/projects/forth.html, which you really
> should read.

I think the issue is not so much code generation as the nature
of expressing algorithms in terms of stack use. Forth machines map
well to Forth, but Forth does not map well to everything. Register
machines map well to Forth, but I question if Forth maps as well
to register based machines.

--
Jeff Fox UltraTechnology
www.UltraTechnology.com


Sent via Deja.com http://www.deja.com/
Before you buy.

F...@ultratechnology.com

unread,
Jul 17, 2000, 3:00:00 AM7/17/00
to
In article <8kmjpm$laq$1...@pollux.ip-plus.net>,

"Bruno Gustavs" <Gust...@ch.sibt.com> wrote:
> What do you think are the top ten language constructs in Forth?

I like some of the answers I have seen. Mine would be:

1. Stacks. One for data, one for return, possibly more.
2. Words. Words and spaces, colon definitions (little syntax).
3. Blocks. Simple custom drivers to hardware.

4. Factor. Factor the solution to match the problem.
5. Focus. Focus on the problem being solved.
6. Fun. Half the fun of Forth is doing it your own way. (C.M.)

7. Think. View from above, build from below, consider everything.
8. Avoid. Avoid unsolvable problems seemingly blocking your path.
9. Abstract. Abstract where useful, specialize when it is useful.

10. Choose. Good, Fast, Cheap, Standard: Pick two or three.

Reuben Thomas

unread,
Jul 18, 2000, 3:00:00 AM7/18/00
to
On Mon, 17 Jul 2000 14:54:45 GMT, F...@UltraTechnology.com <F...@UltraTechnology.com> wrote:

>Register
>machines map well to Forth, but I question if Forth maps as well
>to register based machines.

What do you mean here?

--
http://sc3d.org/rrt/

F...@ultratechnology.com

unread,
Jul 18, 2000, 3:00:00 AM7/18/00
to
In article <slrn8n8kg...@localhost.localdomain>,

Register machines map well to Forth because they have more than
enought resources to do everything demanded by Forth. Their
instruction set is more than rich enough to provide efficient
implementation of a Forth virtual machine. The use of registers
to cache stack cells, control stack cells etc. provides for very
high performance of Forth on these machines.

Forth may not map as well to register machines because they
have features that may not be exploited by Forth. In particular
they can juggle many parameters at once since addressable
registers operate as very fast addressable memory and provide
a mechanism to cache the most valuable variables in a function.

The optimization techniques needed to take advantage of this
style of hardware are different than the optimization techniques
used to optimize stack use. The mismatch between the simplicity
of the Forth virtual machine and the complexity of register
based machines means that register machines are good for Forth
but that Forth my not be the best choice on register based
machines.

Personally I prefer a simple compiler on simple hardware to
be able to do the same things with less work all around. I
can understand that if you choose hardware that is 1000x
more complex that the software will also have to be more
complex. If you choose Forth software that is 100 or 1000x
more complex to match the complex hardware it can take more
advantage of the power hidden in the software. But other
people are using software that is 1,000,000 times larger
to take full advantage of the hidden power in the hardware.

One can use some of very complex hardware by using simple
software. It may be of some advantage for productivity to
use this approach but it doesn't squeeze the last of the
juice out of the hardware. One still has to pay for all
the transistors even if one's approach to software only uses
a few of them. I recognize that if one pays for the hardware
up front that one can consider paying for the effort to pay for
software that uses the features of register machines that
are not elligantly expressed in Forth.

A good example of the problem is that when people copy
programs from that enviroment into Forth they say they
have the same functionality but they may give up 99% of
the performance by doing this. They are paying for all
the transistors but only using a small percentage and
thrashing variables in memory if they use code that is
not factored for stack use. The huge difference between
register speed and memory speed means that caching the
stack but not variables in registers may slow things down
by 100 times. This type of software on this type of hardware
cries out for multi-pass optimization techniques with careful
variable to register assignments.

cLIeNUX user

unread,
Jul 18, 2000, 3:00:00 AM7/18/00
to
bpa...@mikron.de...
>cLIeNUX user wrote:
>> Forth's downsides are;
>> it models a machine that doesn't run well natively on most normal
>> CPUs, but the hit is not as bad as most other "interpreters". This
>> "impedance mismatch" becomes a huge advantage if you happen to have
>> a Forth engine for a CPU, which I believe are fundamentally
>> superior to register machines.
>
>That's wrong. Forth is as good for running on a register-oriented CPU as
>other languages like C or Fortran. It just takes the same amount of work
>to write an optimizing compiler backend for Forth as for any of the
>other languages (you save a lot of time on the frontend, though),
>something most Forth authors are reluctant to do, because they have
>better things to do.
>
>Anton Ertl has several papers about Forth native code generation on
>http://www.complang.tuwien.ac.at/projects/forth.html, which you really
>should read.
>

cLIeNUX user

unread,
Jul 18, 2000, 3:00:00 AM7/18/00
to
bpa...@mikron.de...
>cLIeNUX user wrote:
>> Forth's downsides are;
>> it models a machine that doesn't run well natively on most normal
>> CPUs, but the hit is not as bad as most other "interpreters". This
>> "impedance mismatch" becomes a huge advantage if you happen to have
>> a Forth engine for a CPU, which I believe are fundamentally
>> superior to register machines.
>
>That's wrong. Forth is as good for running on a register-oriented CPU as
>other languages like C or Fortran. It just takes the same amount of work
>to write an optimizing compiler backend for Forth as for any of the
>other languages (you save a lot of time on the frontend, though),
>something most Forth authors are reluctant to do, because they have
>better things to do.
>
>Anton Ertl has several papers about Forth native code generation on
>http://www.complang.tuwien.ac.at/projects/forth.html, which you really
>should read.

OK, I will. This is about batch-compiling Forth right? That ain't Forth.
It may be important, etc., but it's not "Forth" in the basic sense.

I think it's great that it's possible, profitable for a few of you, etc.
I don't think Forth is going anywhere by being "just as good as C".
I admire Forth for the things about Forth itself that are wildly superior
to batch compilers. All this native code optimizing vanishes on a Forth
machine, but it makes widespread use of Forth machines less likely.

etc. etc.

Rick Hohensee
bla zay woof WOOF

F...@ultratechnology.com

unread,
Jul 18, 2000, 3:00:00 AM7/18/00
to
In article <8l229k$5rv$2...@news.smart.net>,
r@your_host.com (cLIeNUX user) wrote:

>All this native code optimizing vanishes on a Forth machine,

I don't agree with that. There are many possible implemenations
of Forth machines. Many different native code optimization
techniques can be applied to various designs.

Some of it is just the preference of the programmer. A simple
Forth can be used on a simple chip but one can also use a
complex Forth with lots of optimization tricks. Having done
both on simple machines I personally came to feel that I could
do all the same optimizations myself in simple code that I
could put into a sophisiticed optimizing compiler that I was
not personally gaining enough by using that approach to prefer
it. But I can understand that there is value to using more
standard looking code and more sophisticated compiling
techniques.

It is hard to make blanket statements about Forth hardware
just as it is about Forth software. There are so many variations
possible that there will be lots of excepts to any statements
that are not qualified with a specific context.

I have done ANS optimizing compilers and simple machine Forth
on different machines. Both approaches have their values.
I prefer one but it doesn't make the other vanish.

>but it makes widespread use of Forth machines less likely.
>
> etc. etc.

I would not agree with that either. Only in the sense that if
people focus so much on one approach that they will refuse to
even look at other approaches would this sort of thing be true.
I think people designing simple machines with simple software
can benefit by learning tricks used on the complex machines
and complex software. They can add them to their bag of tricks
and use them where applicable. The same applies in reverse.
There is still a lot of unexplored territory.

Jet Thomas

unread,
Jul 18, 2000, 3:00:00 AM7/18/00
to
F...@UltraTechnology.com wrote:

>A simple
>Forth can be used on a simple chip but one can also use a
>complex Forth with lots of optimization tricks. Having done
>both on simple machines I personally came to feel that I could
>do all the same optimizations myself in simple code that I
>could put into a sophisiticed optimizing compiler that I was
>not personally gaining enough by using that approach to prefer
>it. But I can understand that there is value to using more
>standard looking code and more sophisticated compiling
>techniques.

..

>I think people designing simple machines with simple software
>can benefit by learning tricks used on the complex machines
>and complex software. They can add them to their bag of tricks
>and use them where applicable. The same applies in reverse.
>There is still a lot of unexplored territory.

So, if you happen to have an optimising compiler, you can look at what it
does and maybe you'll pick up some tricks from it. Even if it isn't a great
optimising compiler. Even if it isn't a very good optimising compiler,
provided it knows some tricks that you don't think to apply.

On the other hand, if you use tricks that didn't come naturally to you, they
probably won't come naturally to other people either. So your code will get
harder to read.

Maybe the most readable code has to be written in Visual Basic.
Well-written VB code can be read by any programmer, and even nonprogrammers
can mostly pick out the meaning. If readability is the only important thing
maybe some sort of pseudo-code would be particularly readable. And if
readability is the most important but you'd like it to run also, then VB
might still be the best.

And only when some combination of other criteria are collectively as
important as readability should you use anything else.

cLIeNUX user

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
F...@UltraTechnology.com...
>In article <8l229k$5rv$2...@news.smart.net>,
> r@your_host.com (cLIeNUX user) wrote:
>
>>All this native code optimizing vanishes on a Forth machine,
>
>I don't agree with that. There are many possible implemenations
>of Forth machines. Many different native code optimization
>techniques can be applied to various designs.
>
>Some of it is just the preference of the programmer. A simple

>Forth can be used on a simple chip but one can also use a
>complex Forth with lots of optimization tricks. Having done
>both on simple machines I personally came to feel that I could
>do all the same optimizations myself in simple code that I
>could put into a sophisiticed optimizing compiler that I was
>not personally gaining enough by using that approach to prefer
>it. But I can understand that there is value to using more
>standard looking code and more sophisticated compiling
>techniques.
>
>It is hard to make blanket statements about Forth hardware
>just as it is about Forth software. There are so many variations
>possible that there will be lots of excepts to any statements
>that are not qualified with a specific context.
>
>I have done ANS optimizing compilers and simple machine Forth
>on different machines. Both approaches have their values.
>I prefer one but it doesn't make the other vanish.
>
>>but it makes widespread use of Forth machines less likely.
>>
>> etc. etc.
>
>I would not agree with that either. Only in the sense that if
>people focus so much on one approach that they will refuse to
>even look at other approaches would this sort of thing be true.
>I think people designing simple machines with simple software
>can benefit by learning tricks used on the complex machines
>and complex software. They can add them to their bag of tricks
>and use them where applicable. The same applies in reverse.
>There is still a lot of unexplored territory.
>
>--
>Jeff Fox UltraTechnology
>www.UltraTechnology.com


Well, the blanket statements are in response to Forth newbie questions.
Sometimes :o) BTW, back a post or two you said

View from above. Build from below. Consider everything.

Or similar. That's a beaut, dude. Is that you, or a quote?

Rick Hohensee
ri...@clienux.com

cLIeNUX user

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
jeth...@ix.netcom.com...
>F...@UltraTechnology.com wrote:
>
>>A simple
>>Forth can be used on a simple chip but one can also use a
>>complex Forth with lots of optimization tricks. Having done
>>both on simple machines I personally came to feel that I could
>>do all the same optimizations myself in simple code that I
>>could put into a sophisiticed optimizing compiler that I was
>>not personally gaining enough by using that approach to prefer
>>it. But I can understand that there is value to using more
>>standard looking code and more sophisticated compiling
>>techniques.
>
>..

>
>>I think people designing simple machines with simple software
>>can benefit by learning tricks used on the complex machines
>>and complex software. They can add them to their bag of tricks
>>and use them where applicable. The same applies in reverse.
>>There is still a lot of unexplored territory.
>
>So, if you happen to have an optimising compiler, you can look at what it
>does and maybe you'll pick up some tricks from it. Even if it isn't a great
>optimising compiler. Even if it isn't a very good optimising compiler,
>provided it knows some tricks that you don't think to apply.
>
>On the other hand, if you use tricks that didn't come naturally to you, they
>probably won't come naturally to other people either. So your code will get
>harder to read.
>
>Maybe the most readable code has to be written in Visual Basic.
>Well-written VB code can be read by any programmer, and even nonprogrammers
>can mostly pick out the meaning. If readability is the only important thing
>maybe some sort of pseudo-code would be particularly readable. And if
>readability is the most important but you'd like it to run also, then VB
>might still be the best.
>
>And only when some combination of other criteria are collectively as
>important as readability should you use anything else.


JET, maybe you shouldn't worry about readability. I can't read a lot of
your code, or Wil's, because I don't understand what it's doing at the
fundamental algorithm level. I'd hate to see you and Wil in VB,
even if I _could_ read it :o)

Plan9 has very sparse comments in the source. Being written by Thompson,
Ritchie, Kernighan, Pike and so on, they seem to assume the reader knows
C. The docs are the docs, which are, not surprisingly, easily, flatly
lucid. Unix manpages/source seem to be evolving toward shadow blocks ;o)

Rick Hohensee
ri...@clienux.com


F...@ultratechnology.com

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
In article <8l3bvd$a5s$2...@news.smart.net>,
r@your_host.com (cLIeNUX user) wrote:

> F...@UltraTechnology.com...


> > View from above. Build from below. Consider everything.
>
> Or similar. That's a beaut, dude. Is that you, or a quote?

That one was mine. The first three were paraphrasing what
Chuck has always said from what I can tell. A few others
were ideas Chuck has expressed at different times. The
one about Forth being fun, and "Half the fun of Forth is
doing it your own way." was a direct quote thus the (C.M.)
at the end of the line.

--
Jeff Fox UltraTechnology
www.UltraTechnology.com

Reuben Thomas

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
On 18 Jul 2000 16:57:24 GMT, cLIeNUX user <r@your_host.com> wrote:

>OK, I will. This is about batch-compiling Forth right?

Wrong. It's the same sort of technologies as go into MPE's products. Like
all but the most aggressive optimising compilers, it works at the per-word
level, and is therefore fine for ordinary Forth systems (IIRC, in MPE's VFX
compilers, it's implemented as a smart COMPILE, that buffers everything
until ; and then compiles the whole lot at once).

--
http://sc3d.org/rrt/

Reuben Thomas

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
On Tue, 18 Jul 2000 19:58:51 GMT, Jet Thomas <jeth...@ix.netcom.com> wrote:

>Maybe the most readable code has to be written in Visual Basic.

Hmm, yes, a language where you can't easily tell where parameters are being
passed by reference or value, and has a thousand and one syntactic
nightmares. Count me out!

I think the easiest languages to read are functional programming languages,
for two reasons:

1. Most functions are simple case-by-case analyses:

fun fact 0 = 1
| fact n = n * fact (n-1);

(that's real ML code).

2. No side effects (in a pure functional language).

--
http://sc3d.org/rrt/

Reuben Thomas

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
On Tue, 18 Jul 2000 15:06:23 GMT, F...@UltraTechnology.com <F...@UltraTechnology.com> wrote:
>In article <slrn8n8kg...@localhost.localdomain>,
> r...@sc3d.org wrote:
>> On Mon, 17 Jul 2000 14:54:45 GMT, F...@UltraTechnology.com
><F...@UltraTechnology.com> wrote:
>>
>> >Register
>> >machines map well to Forth, but I question if Forth maps as well
>> >to register based machines.
>>
>> What do you mean here?
>
>Register machines map well to Forth because they have more than
>enought resources to do everything demanded by Forth. Their
>
>Forth may not map as well to register machines because they
>have features that may not be exploited by Forth. In particular

Sorry, I understood this the other way around: Forth maps well to register
machines (it's easy to implement Forth simply and efficiently on a register
machine), but register machines map poorly to Forth (it's hard to make good
use of registers in Forth). Perhaps "mapping" is just a bad way of putting
it. Perhaps it's easier to say that register machines can easily implement
Forth, but Forth can't easily exploit their full potential.

--
http://sc3d.org/rrt/

Marcel Hendrix

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
Reuben Thomas wrote in message ...

> Perhaps "mapping" is just a bad way of putting
> it. Perhaps it's easier to say that register machines can easily implement
> Forth, but Forth can't easily exploit their full potential.


Don't understand that. When generating native code the compiler
decides to put values from the conceptual stack(s) into registers.
The more registers there are, the better. (On the x86 I could easily
use 8 to 16 extra registers in the optimizers). If there are more than,
say, 32 registers, it would become a problem what to do with them. (You
could give them names and use them like fast global variables :-)

But I guess this would be a problem for other compilers too?

-marcel


Luddy Harrison

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
"Marcel Hendrix" <m.a.m....@nl.cis.philips.com> wrote:

> -marcel

One way that aggressive optimizing compilers make use of additional
registers is to perform optimizations that increase register pressure,
like loop unrolling and software pipelining. I don't know if there
are any Forth compilers that attempt such things.

I suppose also that the register pressure will depend directly upon
how `deep' the compiler is able to reach into the stack; that is, what
number of pushes and pops are dissolved into mere references to simple
temporaries. No?

-Luddy Harrison
luddy at concmp dot com

Stephen Pelc

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to comp.lang.forth
cLIeNUX user wrote in message <8l229k$5rv$2...@news.smart.net>...

>OK, I will. This is about batch-compiling Forth right? That ain't
Forth.
>It may be important, etc., but it's not "Forth" in the basic sense.
Why? If you can't tell the difference what is the difference? The only
difference between Forths with and without optimisation is the
optimiser.

>I think it's great that it's possible, profitable for a few of you,
etc.
>I don't think Forth is going anywhere by being "just as good as C".
>I admire Forth for the things about Forth itself that are wildly
superior

>to batch compilers. All this native code optimizing vanishes on a Forth
>machine, but it makes widespread use of Forth machines less likely.
Stack machines like the RTX require an optimiser for Forth to
obtain best performance. Optimisation is just a way to improve
performance without changing source syntax. What's wrong with
that?
--
Stephen Pelc, s...@mpeltd.demon.co.uk
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)2380 631441, fax: +44 (0)2380 339691
web: http://www.mpeltd.demon.co.uk - free ProForth downloads!


Bernd Paysan

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
cLIeNUX user wrote:
> >Anton Ertl has several papers about Forth native code generation on
> >http://www.complang.tuwien.ac.at/projects/forth.html, which you really
> >should read.
>
> OK, I will. This is about batch-compiling Forth right? That ain't Forth.
> It may be important, etc., but it's not "Forth" in the basic sense.

No. This is about compiling Forth to optimized native code. There's
nothing that requires batch-compiling here. RAFTS defers some of the
compilation because then it doesn't need to compile those words that are
competely inlined (saves code space), but once you ' a word, you get it
compiled.

Note that C compilers have much less opportunity to globaly optimize
than Forth compilers, because C allows separate compilation. So the C
compiler knows next to nothing about functions that have been separately
compiled. Forth is an incremental compiler, thus you can only use words
that already have been defined, and the compiler can do whatever it
likes (constant propagation, inlining, etc.).

Jet Thomas

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
r...@sc3d.org wrote:
><jeth...@ix.netcom.com> wrote:

>>Maybe the most readable code has to be written in Visual Basic.

>Hmm, yes, a language where you can't easily tell where parameters are being
>passed by reference or value, and has a thousand and one syntactic
>nightmares. Count me out!

I should have made it plain I was being sarcastic. Better yet, I should
have avoided sarcasm in the first place.

>I think the easiest languages to read are functional programming languages,
>for two reasons:

>1. Most functions are simple case-by-case analyses:

>fun fact 0 = 1
> | fact n = n * fact (n-1);

>(that's real ML code).

When I first read that, it looked like it said: fun fact 0=1 . That would
be a fun fact, all right.

In Forth that might look like

: fact ( n -- n!)
DUP 1 > IF
DUP 1- RECURSE * ELSE
DROP 1 THEN ;

This is not very readable unless you're familiar with Forth. Also it has a
bug, negative numbers all give 1 as their factorial.

Anyway, I'd figure there are several different things to readability. One
is how much the language gets in your way. If it looks weird, that's bad
for the people it looks weird to. Side-effects are another issue, as you
point out. But one important readability problem comes from unexpected
algorithms. If you are trying to do something that people don't understand
ahead of time, they'll have trouble following your reasoning. So the most
readable code won't do anything clever. It will do things precisely the way
people would first imagine they should be done, without any subtle thinking.
If there is a written algorithm the code should do the same things in the
same order, so that a reader can look at the algorithm and look at the code
and see that each line of the algorithm exactly corresponds to a line of
code.

For that purpose, the factorial might better be written:

: fact ( n -- n! )
1 SWAP 1 MAX 1 ?DO
I *
LOOP ;

If the definition of factorial that the reaser uses is written like
n*(n-1)*(n-2)*...*1 or 0! =1 then it's more readable to do the
multiplications than to use recursion.

Similarly for sigmaI which is like factorial but adds instead of
multiplies:

: sigmaI ( n -- n*[n+1]/2 )
0 SWAP 1 MAX 1 ?DO
I +
LOOP ;

even though it would be simpler and more efficient for all purposes but
readability to do

: sigmaI (n -- n*[n+1]/2 )
DUP 1+ * 2/ ;

But I'm afraid I'm veering far too close to sarcasm again, so I'll stop now.

Jerry Avins

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
Stephen Pelc wrote:
>
> cLIeNUX user wrote in message <8l229k$5rv$2...@news.smart.net>...
> >OK, I will. This is about batch-compiling Forth right? That ain't
> Forth.
> >It may be important, etc., but it's not "Forth" in the basic sense.
> Why? If you can't tell the difference what is the difference? The only
> difference between Forths with and without optimisation is the
> optimiser.
>
> >I think it's great that it's possible, profitable for a few of you,
> etc.
> >I don't think Forth is going anywhere by being "just as good as C".
> >I admire Forth for the things about Forth itself that are wildly
> superior
> >to batch compilers. All this native code optimizing vanishes on a Forth
> >machine, but it makes widespread use of Forth machines less likely.
> Stack machines like the RTX require an optimiser for Forth to
> obtain best performance. Optimisation is just a way to improve
> performance without changing source syntax. What's wrong with
> that?
> --
> Stephen Pelc, s...@mpeltd.demon.co.uk
> MicroProcessor Engineering Ltd - More Real, Less Time
> 133 Hill Lane, Southampton SO15 5AF, England
> tel: +44 (0)2380 631441, fax: +44 (0)2380 339691
> web: http://www.mpeltd.demon.co.uk - free ProForth downloads!

Stephen,

"This is about batch-compiling Forth right?" is so wide of the mark that
it's easy to miss Rick's assertion. He takes "batch" to mean the whole
program, and that would indeed not be Forth as we know it. In actuality,
the batch, if there's anything to be called that, is a single
definition, optimized as a whole instead of being compiled a word at a
time.

Jerry
--
Engineering is the art of making what you want from things you can get.
-----------------------------------------------------------------------

Bernd Paysan

unread,
Jul 19, 2000, 3:00:00 AM7/19/00
to
Marcel Hendrix wrote:
> Don't understand that. When generating native code the compiler
> decides to put values from the conceptual stack(s) into registers.
> The more registers there are, the better. (On the x86 I could easily
> use 8 to 16 extra registers in the optimizers). If there are more than,
> say, 32 registers, it would become a problem what to do with them. (You
> could give them names and use them like fast global variables :-)

Anton proposes to use them as registers for leaf functions. I.e. do
static stack allocation reverse - the leaf routine tells you which
registers it uses, and the next outer word doesn't use those registers,
and thus the leaf routine doesn't have to save any registers (you can
continue the static analysis until all registers are used by called
words; then you need to start spilling). I think 16 registers are fine
for optimizing within a single Forth word, and 32 are good for global
optimizing. Also, some fast globals aren't too bad, either.

Since the Forth compiler has always complete knowledge about the called
words, it can do theoretically better than an ordinary C compiler, which
has to follow calling conventions. Only EXECUTE needs tokens with
standard calling conventions, and Anton already proposed to use a
variation of EXECUTE that at least knows about the stack effect of the
called word. A native code compiler with Anton's ideas implemented might
generate different code when the word is called and when it's '-ed (the
'-ed version needs to conform to a default calling convention).

cLIeNUX user

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
r...@persephone.localhost.localdomain...
>On 18 Jul 2000 16:57:24 GMT, cLIeNUX user <r@your_host.com> wrote:
>
>>OK, I will. This is about batch-compiling Forth right?
>
>Wrong. It's the same sort of technologies as go into MPE's products. Like
>all but the most aggressive optimising compilers, it works at the per-word
>level, and is therefore fine for ordinary Forth systems (IIRC, in MPE's VFX
>compilers, it's implemented as a smart COMPILE, that buffers everything
>until ; and then compiles the whole lot at once).

(This post is also in reply to Bernd telling me to read Anton's papers,
which I did, to the extent I could stand without re-installing X etc.
etc.)

Wrong, eh?

Close enough. Inlining. Valuable. Impressive. Indispensible on most
hardware for many apps. Conceptually, it's not Forth. An important
practical *adjunct* to Forth.

Tell your clients it's the Forth of the future. To most IT managers I'm
sure it's plenty futuristic. They have very real interests in being
mundane, so to speak. What I'm asking is that you please make some
distinction between generic batch-compiler techniques and Forth in
comp.lang.forth. There's a threader, and maybe a compiler. The threader is
the Forth part. Is that so tough? Weird? Is that gonna scare away Big
Brother? You get your clients in here?

Why do I harp on this? Because C-ism is insidious. There's C-ism even in
Ertl's and Koopman's papers. Stack manipulation instructions are described
as useless. How is it possible that they are useless when they allow a
freedom of parameter-passing that simply does not exist in one-stack
languages? It is not possible. What stack operations are is information
that is much more subtle than any in a one-stack language.

That's why Forth-to-whatever is so difficult. It's not easy turning Ingrid
Bergman into Lassie. Yes, thanks, I'm quite sure Lassie runs almost 3
times faster. So I would have assumed. They'll get a nice woof out of it
in comp.lang.dogs. Actually, they won't. They've got a couple dogs over
there a lot faster than Lassie. I, personally, am more interested in Forth
herself, even if she only does about 12 mph in single-stack-heels.

This thread has confirmed in my mind the idea that blurring the
distinction between threading and compiling is not good for Forth as a
whole.


Rick Hohensee
ri...@clienux.com

cLIeNUX user

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
s...@mpeltd.demon.co.uk...
>cLIeNUX user wrote in message <8l229k$5rv$2...@news.smart.net>...
>>OK, I will. This is about batch-compiling Forth right? That ain't
>Forth.
>>It may be important, etc., but it's not "Forth" in the basic sense.
>Why? If you can't tell the difference what is the difference? The only
>difference between Forths with and without optimisation is the
>optimiser.
>
>>I think it's great that it's possible, profitable for a few of you,
>etc.
>>I don't think Forth is going anywhere by being "just as good as C".
>>I admire Forth for the things about Forth itself that are wildly
>superior
>>to batch compilers. All this native code optimizing vanishes on a Forth
>>machine, but it makes widespread use of Forth machines less likely.
>Stack machines like the RTX require an optimiser for Forth to
>obtain best performance. Optimisation is just a way to improve
>performance without changing source syntax. What's wrong with
>that?

Nothing. My gripe is about what that gets _called_ in c.l.f. It's a very
practical thing to do, when the language is not native to the machine.
However, you are talking about Forth, or you are talking about
implementing one on something else. Not the same thing, and only one is
Forth. It's just a distinction that bears emphasizing in
comp.lang.*forth*.

Jeff alluded also to the fact that some stack machines, his, benefit from
optimizing Forth. They have a native instruction set, however, that cannot
be optimized in the systemic sense, by definition. So it would be on a
true Forth machine with Forth source. I am biased to the
"implementation-independant view" of the situation, since I've written a
demo of a virtual machine that is, I hope, more interesting in it's design
than it's implementation. I'm very proud of the implementation of H3sm,
BUT IT'S *^$*#@^ C. IT'S NOT WHAT H3SM IS ABOUT. And I think that
long-term what's really essentially Forth is what's important to most of
us. BUT, I do feel that that view, the Forth-centric view, is appropriate
for comp.lang.forth, and people with great accomplishments in valuable
practical implementations of what I am calling pure Forth combined with
"other", can and should maintain the distinction. I think the Forth
establishment needs to maintain the distinction between threading and
compiling as badly as I do.

Thanks for entertaining this rant.

Rick Hohensee
ri...@clienux.com

Bernd Paysan

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
cLIeNUX user wrote:
> >Stack machines like the RTX require an optimiser for Forth to
> >obtain best performance. Optimisation is just a way to improve
> >performance without changing source syntax. What's wrong with
> >that?
>
> Nothing. My gripe is about what that gets _called_ in c.l.f. It's a very
> practical thing to do, when the language is not native to the machine.
> However, you are talking about Forth, or you are talking about
> implementing one on something else. Not the same thing, and only one is
> Forth. It's just a distinction that bears emphasizing in
> comp.lang.*forth*.

Sorry, optimizing Forths look like Forth, smell like Forth, taste like
Forth. The only difference is an implementation detail. When I rant
about people misunderstanding the implementation details of ~1980
PolyForth presented in Starting Forth as "this is the definition of what
is Forth", I mean people like you. Forth is a language and a virtual
machine. The virtual machine has to be emulated on a real machine, and
whether you do that step by step while execution, or at a whole while
compiling doesn't matter, the only significant difference you can notice
as a user is speed.

Your H3sm is quite different from Forth, much more different than VFX or
RAFTS. You have different syntax, different semantics, even a third
stack for addresses, and you think the way you implement it is the way
every Forth must be implemented to be a Forth?

Forthers encourage exploration, therefore we like you to fiddle with
H3sm and tell us what you gain experience, even though it's not ANS
Forth compatible. But stop telling us what "real Forth" is.

BTW C: The first implementation of C used threading code (ask Dennis
Ritchie if you don't believe, or look on his web-site). Yes, *the* sort
of threading code we Forthers all know well. You can now start to rant
about native C compilers and that they aren't "true C".

Jerry Avins

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
cLIeNUX user wrote:
>
> r...@persephone.localhost.localdomain...
> >On 18 Jul 2000 16:57:24 GMT, cLIeNUX user <r@your_host.com> wrote:
> >
> >>OK, I will. This is about batch-compiling Forth right?
> >

Rick,

You really miss the point. Maybe it's an easy point for me to see
because of my background: squeezing performance out of Z-80 (and 68HC11)
control systems that my colleagues couldn't achieve with faster 8086s.
To do that, I would write my code in high level to "prove" it, and
rewrite the critical words in assembler for speed. The high-level parts
of my code didn't change because I rewrote some of the earlier stuff --
that's another glorious thing about Forth.

It's the source code that makes a program Forth or not. A native code
optimizing compiler just converts all words to assembler, saving me the
trouble. The incremental compilation and interactive console are still
there. It's still Forth, and good Forth, too.

Anton Ertl

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
In article <8kv6nb$qdi$1...@nnrp1.deja.com>,

F...@UltraTechnology.com writes:
>I think that is the point that was being made about Forth and
>register machines. Not that Forth can't compile efficiently
>on register based machines, but rather that Forth does not take
>full advantage of all the features on these machines. Because
>Forth uses the stack notation it is not always the best match to
>register based machines.

In some respects Forth is a better fit on register machines than most
other languages, thanks to its stack.

E.g., In Forth returning several results can happen through the stack,
which can be mapped to registers (the optimizations necessary for this
are inlining or interprocedural register allocation).

In Pascal you can return one cell or FP value in a register and have
to use references to return the other results. I know of no compiler
that can optimize reference accesses to register accesses. In C the
situation is theoretically beter, because you can return structs, but
in practice many compilers return structs through an invisible
call-by-reference parameter, and anyway, many programmers choose to
use a Pascal-like way to deal with this issue.

Back to more general territory:

Other languages are simpler to implement on stack, memory, or
accumulator machines than on machines with many registers (at least if
they want to make good use of the machine). Global register
allocation is a relatively recent development and quite a lot research
has gone into it.

We can also use the results of these research for Forth compilers; the
problem here is that these techniques tend to require quite a bit of
compile time, which is precious in an incremental compiler. The
problem is not the stack notation.

>I think the issue is not so much code generation as the nature
>of expressing algorithms in terms of stack use. Forth machines map

>well to Forth, but Forth does not map well to everything. Register


>machines map well to Forth, but I question if Forth maps as well
>to register based machines.

Both the stack notation and the Algol-like notation are ways to
specify data flow, which is the essential thing in a computation that
implements an algorithm. Many compilers (including RAFTS, and, I
guess, ProForth VFX) use some form of data flow graphs (or something
equivalent) as intermediate representations.

It is theoretically possible to produce any data flow graph from the
stack notation (in the worst case this requires many PICKs and ROLLs,
but IIRC you can implement PICK and ROLL using the return stack, so in
the presence of the return stack they are unnecessary). Of course
nobody would write code in that way, but then, I doubt that all
data-flow graphs are specified in Algol-like languages, either.

So, while there may be some data flow graphs for which the stack
juggling would become excessive, I think that those algorithms that
are straightforward to express in Forth utilize register machines in
the same way in all languages (the data-flow graph is the same),
unless there is some crippling influence like the return value
restrictions of Pascal.

Now, for those algorithms that would require excessive stack juggling,
we tend to use various techniques to conquer them: factoring, putting
data into memory, locals, etc. While putting data into memory will
replace a fast resource on a register machine (a register) with a slow
resource (memory), it's not clear to me that the overall effect of
these techniques is to slow the program down. I don't remember ever
having to resort to putting stuff into memory that I would rather have
kept on the stack/in registers.

- anton
--
M. Anton Ertl Some things have to be seen to be believed
an...@mips.complang.tuwien.ac.at Most things have to be believed to be seen
http://www.complang.tuwien.ac.at/anton/home.html

cLIeNUX user

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
j...@ieee.org...

You're supporting my point. What you do that doesn't effect the source
is irrelevant to "Forth". It's what you do WITH Forth, such as compiling
it, for example. Forth source itself defines a machine, and that machine
uses threaded code.

>A native code
>optimizing compiler just converts all words to assembler, saving me the
>trouble. The incremental compilation and interactive console are still
>there. It's still Forth, and good Forth, too.
>

We disagree.

Rick Hohensee

cLIeNUX user

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
bpa...@mikron.de...
>cLIeNUX user wrote:
>> >Stack machines like the RTX require an optimiser for Forth to
>> >obtain best performance. Optimisation is just a way to improve
>> >performance without changing source syntax. What's wrong with
>> >that?
>>
>> Nothing. My gripe is about what that gets _called_ in c.l.f. It's a very
>> practical thing to do, when the language is not native to the machine.
>> However, you are talking about Forth, or you are talking about
>> implementing one on something else. Not the same thing, and only one is
>> Forth. It's just a distinction that bears emphasizing in
>> comp.lang.*forth*.
>
>Sorry, optimizing Forths look like Forth, smell like Forth, taste like
>Forth. The only difference is an implementation detail.

That's hardly how they're presented. If I saw "OurForth is an ANS Standard
Forth implemented with and implementing typical compiler techniques
adapted to the advanced flexibility of Forth" I wouldn't be commenting.


> When I rant
>about people misunderstanding the implementation details of ~1980
>PolyForth presented in Starting Forth as "this is the definition of what
>is Forth", I mean people like you.

Get a grip.

>Forth is a language and a virtual
>machine. The virtual machine has to be emulated on a real machine, and
>whether you do that step by step while execution, or at a whole while
>compiling doesn't matter, the only significant difference you can notice
>as a user is speed.
>

I've gone to great lengths to differentiate H3sm from the "<C" it's
implemented in. Thanks again for the computed-goto trick.

initial_HERE:

NEXT /* NEXT ourself to the interpreter... */

} /* ...and C is gone. That's my final comment ---> */

>Your H3sm is quite different from Forth, much more different than VFX or
>RAFTS. You have different syntax, different semantics, even a third
>stack for addresses, and you think the way you implement it is the way
>every Forth must be implemented to be a Forth?

Exactly the opposite. H3sm is a demo of a possible machine.
(H3sm syntax is pretty Forthy, BTW. With additions that come in after the
Forth part.)

>
>BTW C: The first implementation of C used threading code (ask Dennis
>Ritchie if you don't believe, or look on his web-site). Yes, *the* sort
>of threading code we Forthers all know well. You can now start to rant
>about native C compilers and that they aren't "true C".
>

B runtimes had a threaded inner address interpreter, but with one stack.
Circa 1972. Thompson wrote B. I think I mentioned this about a month ago.

William Tanksley

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
On 20 Jul 2000 23:53:37 GMT, cLIeNUX user wrote:
>>It's the source code that makes a program Forth or not.

>You're supporting my point. What you do that doesn't effect the source
>is irrelevant to "Forth". It's what you do WITH Forth, such as compiling
>it, for example.

Compiling Forth source doesn't affect the Forth source.

>Forth source itself defines a machine, and that machine uses threaded
>code.

Everyone here disagrees with you. Chuck Moore himself disagrees with you,
and he invented the language.

>>A native code optimizing compiler just converts all words to assembler,
>>saving me the trouble. The incremental compilation and interactive console
>>are still there. It's still Forth, and good Forth, too.

>We disagree.

We all figured that out. I'd like to know *why* we disagree: why are you
taking a position so opposite to all current definitions and
understanding? The only support you've offered is in the vein of the
above discussion, in which you claim that compling Forth source code
changes the source code so that it's not Forth anymore.

Threaded code has a lot of advantages; I'm designing a Forthlike language
which supports the deliberate creation and modification of threaded code.
However, it also compiles and optimises to native code, because that's
faster.

>Rick Hohensee

--
-William "Billy" Tanksley

cLIeNUX user

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
wtan...@dolphin.openprojects.net...
>On 20 Jul 2000 23:53:37 GMT, cLIeNUX user wrote:
>>>It's the source code that makes a program Forth or not.
>
>>You're supporting my point. What you do that doesn't effect the source
>>is irrelevant to "Forth". It's what you do WITH Forth, such as compiling
>>it, for example.
>
>Compiling Forth source doesn't affect the Forth source.
>
>>Forth source itself defines a machine, and that machine uses threaded
>>code.
>
>Everyone here disagrees with you. Chuck Moore himself disagrees with you,
>and he invented the language.
>
>>>A native code optimizing compiler just converts all words to assembler,
>>>saving me the trouble. The incremental compilation and interactive console
>>>are still there. It's still Forth, and good Forth, too.
>
>>We disagree.
>
>We all figured that out. I'd like to know *why* we disagree: why are you
>taking a position so opposite to all current definitions and
>understanding? The only support you've offered is in the vein of the
>above discussion, in which you claim that compling Forth source code
>changes the source code so that it's not Forth anymore.

If I'm so off-the-wall how come you want to know WHY WHY WHY?

I'm flattered actually, but whatever merit lies in what I've said
lies in what I've already said. The prosecution rests.


>
>Threaded code has a lot of advantages; I'm designing a Forthlike language
>which supports the deliberate creation and modification of threaded code.
>However, it also compiles and optimises to native code, because that's
>faster.
>

Sounds interesting.


>>Rick Hohensee RE:
>
>--
>-William "Billy" Tanksley

Mark Humphries

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
wtan...@dolphin.openprojects.net (William Tanksley) wrote:

[snip]


>Everyone here disagrees with you.

[snip]

I don't think I disagree with Rick.
Threading is a fundamental concept to Forth. I think there are
subtle differences between the concepts of threading and native
code compilation.
Optimized native code compilers "simulate threading" only to a
certain degree.
Just as Threaded Forth truly has no syntax, just semantics,
while compiled Forth (and ANS Forth) has predefined syntax bound
to predefined semantics much like other languages.

Cheers,
Mark W. Humphries


-----------------------------------------------------------

Got questions? Get answers over the phone at Keen.com.
Up to 100 minutes free!
http://www.keen.com


Anton Ertl

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
In article <39759B1C...@mikron.de>,

Bernd Paysan <bpa...@mikron.de> writes:
> RAFTS defers some of the
>compilation because then it doesn't need to compile those words that are
>competely inlined (saves code space), but once you ' a word, you get it
>compiled.

Actually RAFTS generates native code for a word when the word is
EXECUTEd. Delaying the compilation that long gives the compiler the
maximum information for possible optimization (e.g., inlining).
Currently RAFTS does not perform any of these optimizations, though.

This is not original with RAFTS, BTW. Such techniques have been used
in, e.g., Smalltalk, Self and JavaVM compilers.

Anton Ertl

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
In article <397620BC...@gmx.de>,

Bernd Paysan <bernd....@gmx.de> writes:
>Anton proposes to use them as registers for leaf functions. I.e. do
>static stack allocation reverse - the leaf routine tells you which
>registers it uses, and the next outer word doesn't use those registers,
>and thus the leaf routine doesn't have to save any registers (you can
>continue the static analysis until all registers are used by called
>words; then you need to start spilling).

An alternative I had considered was to use a classic graph colouring
register allocator, but use an interference graph for the whole
program (at least up to EXECUTE boundaries). The advantage of the
graph colouring register allocator would be that we could optimize
away many MOV instructions that the simpler method would generate.
The question is whether the register allocator would be fast enough to
meet the expectations of Forth users.

> I think 16 registers are fine
>for optimizing within a single Forth word, and 32 are good for global
>optimizing. Also, some fast globals aren't too bad, either.

Given the number of stack items simultaneously alive in a typical
colon definition, I guess that 8 registers should be enough for most
of them (even if we assume that scheduling increases register pressure
by two register). Ok, we also have to deal with three stack pointers,
so eight registers are quite tight.

For interprocedural register allocation, 32 registers should be
plenty. Looking at my stack caching data
(http://www.complang.tuwien.ac.at/misc/stack-caching-data/), a dynamic
data stack cache of 32 items rarely spills. An interprocedural
register allocator should be able to stuff these stack items into less
registers (because several stack items tend to be copies of the same
value); it also can work only on parts of the program bounded by
EXECUTE and other statically unpredictable stuff, which reduces the
number of values it has to fit in at one time. However, it has to fit
in return stack items, and may not be able to get the minimum number
of registers. Overall, I believe 32 registers will be enough for many
Forth programs (and the rest will have little spill overhead.

>Since the Forth compiler has always complete knowledge about the called
>words, it can do theoretically better than an ordinary C compiler, which
>has to follow calling conventions. Only EXECUTE needs tokens with
>standard calling conventions, and Anton already proposed to use a
>variation of EXECUTE that at least knows about the stack effect of the
>called word.

This would allow the EXECUTEing word to have a statically predictable
stack effect instead of poisoning the whole call chain up to the root
word.

>A native code compiler with Anton's ideas implemented might
>generate different code when the word is called and when it's '-ed (the
>'-ed version needs to conform to a default calling convention).

Actually, I also play with the idea of having several possible
versions of code for the word, in the extreme case one for each
EXECUTE, with a calling convention that fits this EXECUTE. The xt
would point to a dispatch table, with each EXECUTE having its own
offset into the table.

F...@ultratechnology.com

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
In article <1306d800...@usw-ex0104-025.remarq.com>,
Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:

> I don't think I disagree with Rick.
> Threading is a fundamental concept to Forth. I think there are
> subtle differences between the concepts of threading and native
> code compilation.
> Optimized native code compilers "simulate threading" only to a
> certain degree.

I know people use different terms for the same thing and
sometimes people use the term "direct threaded" when they
mean what other people call "subroutine threaded" but in
any event the word "threaded" is still there. There is a
difference between subroutine threaded and subroutine
threaded with some optimizations but it is still subroutine
threaded...

The definitions that I use:

IDT Indirect Threaded (address lists with an extra pointer
at the start of each word, making an extra reference
hence indirect. The threading is done by : and ;
nesting return addresses on the return stack and use
an Instruction Pointer in memory or a register.

DT Direct Threaded (address lists that begin with a call
or inlined code to start the threading (no extra pointer
to make it indirect)) The threading is done by : and ;
nesting return addresses on the return stack and use
an instruction pointer in memory or a register.

ST Subroutine Threading does the threading by : and ;
nesting return addresses on the return stack and use
an instruction pointer in a register. The call
and return instructions perform the : and ; in
hardware rather than software and the instruction
pointer in a register is the Program Counter.

TOT Token Threading does the threading by : and ;
nesting return addresses on the return stack and use
an instruction pointer in a memory or a register.
Tokens represent execution vectors through a
table lookup or other mechanism.

BT Bit Threaded does the threading the same way. One
bit is used to distinguish threaded address lists
from code. It is like direct threading but with
one bit to represent nested lists. (has been done
in hardware and software)

(others?)

In some early machines there were no call and return
instructions and Forth made it easy to get threading
with software via : and ; Whether you use a bunch
of code to do the threading or a hardware call and
return there is almost no difference in the threading
that is taking place.

Optimizing native code compilers are basically just
subroutine threaded (yes threaded) Forth that remove
code that cancels out and substitute fast on-chip
registers for slower memory references in a transparent
way. About the only consequence is that tick may
force a new definition if previous instances of the
definition have been inlined or optimized away. This
does mean that you cannot use exactly the same techniques
for manipulating compiled code if you switch from Indirect
Threaded to subroutine or optimized subroutine threading.
This is also true if you switch between direct threading
and indirect threading. The way you manipulate compiled
code is dependent on the way you compile it.

While simplicity and minimalism are considered to be
essential components of Forth by some people a subroutine
threaded implementation need not be any more complicated
than a direct or indirect threaded implementation. They
may even be smaller and simpler than IDT or DT because
the threading is mostly done by two opcodes in hardware
rather than by more code in software.

As most people were introduced to IDT or DT many years
ago they may have scratched their heads when they first
heard about subroutine threading and asked themselves
"Is this really threading? It isn't just address lists!"
Then they look at it and say, "Oh, yeah, sure it is just
using call and return for threading so execution tokens
are in the form of subroutine calls rather than just
addresses.

Adding code optimization makes the threading a tiny
bit harder to see. The introduction of peephole optimization
to a IDT or DT implementation also makes the threading
a tiny bit less visible because it will do more at compile
time and less at runtime and compile code that has a slightly
different relationship to the source. The same is true
when register optimizations are used. The threading is
still there, it is just not quite as visible.

> Just as Threaded Forth truly has no syntax, just semantics,
> while compiled Forth (and ANS Forth) has predefined syntax bound
> to predefined semantics much like other languages.

All the Forths I have ever seen used threading. All of the
Forths had about the same minimal syntax, a few words have
syntax but most are syntax free. Colon, constant, variable,
create (etc.) are followed by a name. Colon is normally
paired with semicolon, THEN normally follows IF etc.
In either case the syntax is in the source not in the compiled
code.

Jerry Avins

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
cLIeNUX user wrote:
>
...

>
> If I'm so off-the-wall how come you want to know WHY WHY WHY?
>
> I'm flattered actually, but whatever merit lies in what I've said
> lies in what I've already said. The prosecution rests.
>
A dog says, "This person feeds me, strokes me, provides a warm place for
me to lie in. He must be a god." A cat says, "This person feeds me,
strokes me, provides a warm place for me to lie in. I must be a god."

You sound catty.

William Tanksley

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
On 22 Jul 2000 07:27:26 GMT, cLIeNUX user wrote:

>If I'm so off-the-wall how come you want to know WHY WHY WHY?

That should be obvious -- because I don't understand you. If I understood
you I wouldn't have to ask WHY WHY WHY. Furthermore, I suspect that there
may be a useful reason for what you've said, and I'd like to understand it.

>I'm flattered actually, but whatever merit lies in what I've said
>lies in what I've already said.

That's a tautology. The things you've said already have insufficient
merit to convince, obviously. The things you've been meaning to say might
be interesting.

>The prosecution rests.

The judge, jury, and executioner declares a mistrial and demands new
evidence.

--
-William "Billy" Tanksley

Jerry Avins

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
Come again? If certain source code compiled on two compilers produces
two executables that behave identically, how can that source have syntax
in one case, but not in the other?

Jerry
--
Engineering is the art of making what you want from things you can get.
-----------------------------------------------------------------------

Mark Humphries wrote:
>
> wtan...@dolphin.openprojects.net (William Tanksley) wrote:
>
> [snip]
> >Everyone here disagrees with you.
> [snip]
>

> I don't think I disagree with Rick.
> Threading is a fundamental concept to Forth. I think there are
> subtle differences between the concepts of threading and native
> code compilation.
> Optimized native code compilers "simulate threading" only to a
> certain degree.

> Just as Threaded Forth truly has no syntax, just semantics,
> while compiled Forth (and ANS Forth) has predefined syntax bound
> to predefined semantics much like other languages.
>

Mark Humphries

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
Jerry Avins <j...@ieee.org> wrote:

> Come again? If certain source code compiled on two compilers
> produces two executables that behave identically, how can that
> source have syntax in one case, but not in the other?

Firstly, compilation in Forth does not produce executables in
the traditionaly understood sense. Compilation in Forth
<I>extends the underlying Forth</I>; such extension dynamicaly
binds meaning/actions/semantics to tokens.

If I use the same source to extend two different Forths, I still
end up with two different extended-Forths :)

In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension has
a consistent, regular form (compiled execution tokens). This
consistency in turn is leveragable by the programmer (in a way
the virtual machine is "deeper" and more reflective due to its
regularity). A native-code optimizing Forth implies a shallower
virtual machine due to the irregularity of its intermediate code.
For example if I know that compiled tokens are always the same
size, I can take advantage of this knowledge in extending my
forth with a decompiler. On an optimizing native code compiler
one can't "see" as deeply into the virtual machine.

Getting back to the question of syntax. Forth has no fixed
syntax to speak of, a word does not <I>represent</I> an action,
it <I>invokes</I> an action (and might be redefined on the fly
to invoke another action). In a traditional non-optimizing
threaded Forth syntax analysis and traditional compiler theory
are mostly irrelevant. With native code optimizing compiler
Forths (and with standard Forths) we now move closer towards the
mainstream where combinations of words represent or denote
actions, code is generated as a by-product of various analysis
rather by "just doing it".

Jerry Avins

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
Mark Humphries wrote:
>
> Jerry Avins <j...@ieee.org> wrote:
>
> > Come again? If certain source code compiled on two compilers
> > produces two executables that behave identically, how can that
> > source have syntax in one case, but not in the other?
>
> Firstly, compilation in Forth does not produce executables in
> the traditionaly understood sense. Compilation in Forth
> <I>extends the underlying Forth</I>; such extension dynamicaly
> binds meaning/actions/semantics to tokens.

I make executables with F-PC and SwiftForth on a PC clone. they have a
.exe file extension.


>
> If I use the same source to extend two different Forths, I still
> end up with two different extended-Forths :)
>
> In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension has
> a consistent, regular form (compiled execution tokens). This
> consistency in turn is leveragable by the programmer (in a way
> the virtual machine is "deeper" and more reflective due to its
> regularity). A native-code optimizing Forth implies a shallower
> virtual machine due to the irregularity of its intermediate code.
> For example if I know that compiled tokens are always the same
> size, I can take advantage of this knowledge in extending my
> forth with a decompiler. On an optimizing native code compiler
> one can't "see" as deeply into the virtual machine.

Decompiling is often a handy thing, but a decompiler that works for one
indirect-threaded interpreter may not work for another, and certainly
won't work on a direct-threaded one. If a decompiler works on only one
"Forth" out of three, does that make the one Forth an impostor?


>
> Getting back to the question of syntax. Forth has no fixed
> syntax to speak of, a word does not <I>represent</I> an action,
> it <I>invokes</I> an action (and might be redefined on the fly
> to invoke another action).

There is a little syntax. : , CREATE , VARIABLE , and other words demand
a name following in the input stream. No definition can start with DOES>

In a traditional non-optimizing
> threaded Forth syntax analysis and traditional compiler theory
> are mostly irrelevant. With native code optimizing compiler
> Forths (and with standard Forths) we now move closer towards the
> mainstream where combinations of words represent or denote
> actions, code is generated as a by-product of various analysis
> rather by "just doing it".

That's right. But it not only saves me the trouble of doing the same
optimizations by hand, it gets it right the first time around. And by
the time I'm through with the hand assembling, my code isn't "just do
it" either.


>
> Cheers,
> Mark W. Humphries
>
> -----------------------------------------------------------

Jerry

cLIeNUX user

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
j...@ieee.org...
>cLIeNUX user wrote:
>>
> ...

>>
>> If I'm so off-the-wall how come you want to know WHY WHY WHY?
>>
>> I'm flattered actually, but whatever merit lies in what I've said
>> lies in what I've already said. The prosecution rests.
>>
>A dog says, "This person feeds me, strokes me, provides a warm place for
>me to lie in. He must be a god." A cat says, "This person feeds me,
>strokes me, provides a warm place for me to lie in. I must be a god."
>
>You sound catty.

You're not tired of this thread?

What kinda critter can't tell who's feeding who? A lamprey?

Rick Hohensee

Mark Humphries

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
> Jerry Avins <j...@ieee.org> wrote:
>> Mark Humphries wrote:

[snip]

>> Firstly, compilation in Forth does not produce executables in
>> the traditionaly understood sense. Compilation in Forth
>> <I>extends the underlying Forth</I>; such extension dynamicaly
>> binds meaning/actions/semantics to tokens.

> I make executables with F-PC and SwiftForth on a PC clone.
> they have a .exe file extension.

So do I, but my .exe is a new Forth, not just a stand-alone
application. A distinction between Forth compilation and
traditional programming language compilation is:

Forth + Source = Extended Forth
.. vs. ...
Program X source processed by Language Y tools outputs
standalone X application executable

This distinction is a major reason why I use Forth.

>> If I use the same source to extend two different Forths, I
>> still end up with two different extended-Forths :)

>> In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension
>> has a consistent, regular form (compiled execution tokens).
>> This consistency in turn is leveragable by the programmer (in
>> a way the virtual machine is "deeper" and more reflective due
>> to its regularity). A native-code optimizing Forth implies a
>> shallower virtual machine due to the irregularity of its
>> intermediate code.

>> For example if I know that compiled tokens are always the same
>> size, I can take advantage of this knowledge in extending my
>> forth with a decompiler. On an optimizing native code compiler
>> one can't "see" as deeply into the virtual machine.

> Decompiling is often a handy thing, but a decompiler that
> works for one indirect-threaded interpreter may not work for
> another, and certainly won't work on a direct-threaded one.

How did portability of source enter the discussion?

> If a decompiler works on only one "Forth" out of three, does
> that make the one Forth an impostor?

There is no One True Forth, none of them are 'impostors'. What's
your point?

>> Getting back to the question of syntax. Forth has no fixed
>> syntax to speak of, a word does not <I>represent</I> an
>> action, it <I>invokes</I> an action (and might be redefined
>> on the fly to invoke another action).

> There is a little syntax. : , CREATE , VARIABLE , and other
> words demand a name following in the input stream. No
> definition can start with DOES>

Yes Forth has the least syntax of any language I know. Prefix
words just consume the next token on the input stream. More
complex syntactical structures are more a question of convention
than formal syntax.

>> In a traditional non-optimizing threaded Forth syntax
>> analysis and traditional compiler theory are mostly
>> irrelevant. With native code optimizing compiler
>> Forths (and with standard Forths) we now move closer towards
>> the mainstream where combinations of words represent or denote
>> actions, code is generated as a by-product of various analysis
>> rather by "just doing it".

> That's right. But it not only saves me the trouble of doing
> the same optimizations by hand, it gets it right the first
> time around. And by the time I'm through with the hand
> assembling, my code isn't "just do it" either.

I did not make value judgements on whether native-code
optimizing Forths are superior or inferior to non-optimizing
threaded Forths. Superiority would be relative to the demands of
the task at hand.

I'm only making the point that IMHO their is a major but subtle
difference in what I call the "depth of the virtual machine"
(for want of a better term) when going from non-optimizing
threaded Forth (whether IDT,DT,TT,SRT) to native-code optimizing
Forth.
I believe this point is relevant to the current discussion.

Cheers,
Mark W. Humphries

-----------------------------------------------------------

Got questions? Get answers over the phone at Keen.com.

Mark Humphries

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:
> Jerry Avins <j...@ieee.org> wrote:
>> Mark Humphries wrote:

Minor clarification:

[snip]

>> I make executables with F-PC and SwiftForth on a PC clone.
>> they have a .exe file extension.

> So do I,

make executables (though not with either F-PC or SwiftForth),

> but my .exe is a new Forth, not just a stand-alone
> application.

[snip]

cLIeNUX user

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
wtan...@dolphin.openprojects.net...
>On 22 Jul 2000 07:27:26 GMT, cLIeNUX user wrote:
>
>The judge, jury, and executioner declares a mistrial and demands new
>evidence.

I un-marked-as-read this post, went offline, and set about the business of
writing a long reply. After several paragraphs it occured to me that I
have a somewhat personal, i.e. useless, definition of "threading".

What is the term for "concatenate Forth words into new Forth words without
any internal manipulations of the resultant words." ?

i.e. what is a term that means, "Without optimizing, make new
definitions, regardless of implementation." ?

I still think, although I have perhaps expressed it poorly, the
distinction between the above and conventional compilation is important.


Rick Hohensee
ri...@clienux.com


>
>--
>-William "Billy" Tanksley

m_l...@my-deja.com

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
Jerry Avins wrote:
>
> Come again? If certain source code compiled on two compilers produces
> two executables that behave identically, how can that source have syntax
> in one case, but not in the other?

Syntax must be attributed to the language, not the source.
E.g. the following text

x:=x+1

may be parsed as

text ::== char | char text

or

asssingm_stmt ::== var ":=" expr
expr ::== ....
....

> > Just as Threaded Forth truly has no syntax, just semantics,
> > while compiled Forth (and ANS Forth) has predefined syntax bound
> > to predefined semantics much like other languages.

That is, in one Forth you can do

: .tail ( c-addr len -- ) 1 -1 D+ TYPE ;

>S" qwerty" .tail
>werty ok

while the other system will tell you there is a type error.

: .tail 1 /STRING TYPE ;

would run on both, but in one case it's typechecked, while in the other it's not.

It's not what usually is called syntax, but there
definitely are some restricting rules.

http://www.dictionary.com/cgi-bin/dict.pl?db=*&term=syntax
>syn·tax
> n.
>...
> 2.Computer Science. The rules governing construction of a machine language.
>...

At least, it's possible to word the algorithm of typechecking so that
it could be called "the Forth grammar". (After some phrases like
"the grammatical type of a Forth word is determined by its stack signature"
anyone will agree that it's grammar.)

Jerry Avins wrote:
>
> Come again? If certain source code compiled on two compilers produces
> two executables that behave identically, how can that source have syntax
> in one case, but not in the other?
>

> Jerry
> --
> Engineering is the art of making what you want from things you can get.
> -----------------------------------------------------------------------

Anton Ertl

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
In article <8lcgae$bst$1...@nnrp1.deja.com>,

F...@UltraTechnology.com writes:
>There is a
>difference between subroutine threaded and subroutine
>threaded with some optimizations but it is still subroutine
>threaded...

No. That's what we call natice code.

>Optimizing native code compilers are basically just
>subroutine threaded (yes threaded) Forth that remove
>code that cancels out and substitute fast on-chip
>registers for slower memory references in a transparent
>way.

Some of them are (say, iForth, and bigForth). For RAFTS (and probably
VFX), I would disagree with the statement above. RAFTS does not even
conceptually go through compiling a subroutine call when compiling a
word like + or SWAP.

I also wouldn't call any of these compilers optimizing (normally this
means globally optimizing, i.e., doing such things as loop-invariant
code motion, strength reduction and induction variable elimination).
AFAIK no currently available Forth compiler does this.

The compilers that start with subroutine threading, then inline and
peephole-optimize can be called peephole-optimizing, though.

Tom Zegub

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
On Sat, 22 Jul 2000 02:27:58 -0700,
Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:

>wtan...@dolphin.openprojects.net (William Tanksley) wrote:
>
>[snip]
>>Everyone here disagrees with you.

But does everyone know what's being said?

>[snip]
>
>I don't think I disagree with Rick.

I'm confused. I'm not sure if people (me mostly,only?) are applying
the same meaning to the terms being used. I'll go with my best guess.
I think Rick is making a distinction between a Forth compiler and a
Forth, period, which he calls a "Threader". The use of this new (?)
coinage is throwing me off. I think the distinction is for the form
of the code produced as oppose to how it is being produced; although,
literal words seem to say otherwise. With this assumption I make the
following case.
When the term "Forth" alone is used to identify a system, it implies
to me that the system is interpretive and produces threaded code.
This would be synonymous with the term "Forth Interpreter". The term
"Forth compiler" implies to me that the system takes a whole program
and produces non-threaded optimized code.
I think Rick used "Threader" to distinguish a "Forth" system from a
"Forth compiler." However logical that may be it's not a common term
and he should stay with "Forth" or "Forth Interpreter" if he means to
imply a system which produces threaded code (provided that this is,
indeed, the common implication.) I'll stop here as I may be too far
off from understanding what Rick has posted.
As I said in a previous post, what is commonly thought of is more
important in communication that what is logical. So I hope responses
will not get hung up on logical arguments. And also, the merits of a
Forth compiler were not being attacked. Rick made that clear but I
think some of the cold responses may have missed that point.

--
Tom Zegub tze...@dhc.net
WasteLand http://www.dhc.net/~tzegub

Jerry Avins

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
Mark Humphries wrote:
>
> > Jerry Avins <j...@ieee.org> wrote:
> >> Mark Humphries wrote:
>
> [snip]
>
> >
> > I make executables with F-PC and SwiftForth on a PC clone.
> > they have a .exe file extension.
>
> So do I, but my .exe is a new Forth, not just a stand-alone
> application. A distinction between Forth compilation and
> traditional programming language compilation is:
>
> Forth + Source = Extended Forth
> .. vs. ...
> Program X source processed by Language Y tools outputs
> standalone X application executable
>
> This distinction is a major reason why I use Forth.

But not me, mostly. There is no way for the user to interact with much
of my stuff except through switch closures.


>
> >> If I use the same source to extend two different Forths, I
> >> still end up with two different extended-Forths :)
>
> >> In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension
> >> has a consistent, regular form (compiled execution tokens).
> >> This consistency in turn is leveragable by the programmer (in
> >> a way the virtual machine is "deeper" and more reflective due
> >> to its regularity). A native-code optimizing Forth implies a
> >> shallower virtual machine due to the irregularity of its
> >> intermediate code.
>
> >> For example if I know that compiled tokens are always the same
> >> size, I can take advantage of this knowledge in extending my
> >> forth with a decompiler. On an optimizing native code compiler
> >> one can't "see" as deeply into the virtual machine.
>
> > Decompiling is often a handy thing, but a decompiler that
> > works for one indirect-threaded interpreter may not work for
> > another, and certainly won't work on a direct-threaded one.
>
> How did portability of source enter the discussion?

I thought you brought it in. It seemed to me that you wrote that the
source was somehow altered if, even though the program functioned
identically, decompilation properties were altered.


>
> > If a decompiler works on only one "Forth" out of three, does
> > that make the one Forth an impostor?
>
> There is no One True Forth, none of them are 'impostors'. What's
> your point?

That there is no One True Forth.


>
> >> Getting back to the question of syntax. Forth has no fixed
> >> syntax to speak of, a word does not <I>represent</I> an
> >> action, it <I>invokes</I> an action (and might be redefined
> >> on the fly to invoke another action).
>
> > There is a little syntax. : , CREATE , VARIABLE , and other
> > words demand a name following in the input stream. No
> > definition can start with DOES>
>
> Yes Forth has the least syntax of any language I know. Prefix
> words just consume the next token on the input stream. More
> complex syntactical structures are more a question of convention
> than formal syntax.

So when you wrote "no fixed syntax to speak of", you meant "not much
syntax"? OK.
>
[snip]



> I did not make value judgements on whether native-code
> optimizing Forths are superior or inferior to non-optimizing
> threaded Forths. Superiority would be relative to the demands of
> the task at hand.
>
> I'm only making the point that IMHO their is a major but subtle
> difference in what I call the "depth of the virtual machine"
> (for want of a better term) when going from non-optimizing
> threaded Forth (whether IDT,DT,TT,SRT) to native-code optimizing
> Forth.
> I believe this point is relevant to the current discussion.
>

It's relevant to the discussion we ought to be having, but Rick H. has
been calling native-code optimizing compilers The Class Of False Forths.
That's what I wanted to refute.

> Cheers,
> Mark W. Humphries
>
> -----------------------------------------------------------

Cheers to you too!

Jerry Avins

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
"m_l...@my-deja.com" wrote:
>
> Jerry Avins wrote:
> >
> > Come again? If certain source code compiled on two compilers produces
> > two executables that behave identically, how can that source have syntax
> > in one case, but not in the other?
>
> Syntax must be attributed to the language, not the source.

[snip]

I need to think long and hard about that. To write correct source -
correct in that the resulting program behaves as intended - there may be
a need to follow certain rules on language we call syntax. How is the
way that the compiler author chooses to analyze the source influence the
rules?

F...@ultratechnology.com

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
In article <8lempg$dko$2...@news.tuwien.ac.at>,

an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:
> In article <8lcgae$bst$1...@nnrp1.deja.com>,
> F...@UltraTechnology.com writes:
> >There is a
> >difference between subroutine threaded and subroutine
> >threaded with some optimizations but it is still subroutine
> >threaded...
>
> No. That's what we call natice code.

Well as I said not everyone uses the same definitions so
there is often confusion. Some people confuse STC with DTC.

But I don't disagree with you. I called it subroutine
threaded code with optimizations (which can replace
the subroutine calls), or I call it native code. We
are talking about the same thing.

> >Optimizing native code compilers are basically just
> >subroutine threaded (yes threaded) Forth that remove
> >code that cancels out and substitute fast on-chip
> >registers for slower memory references in a transparent
> >way.
>

> Some of them are (say, iForth, and bigForth). For RAFTS (and probably
> VFX), I would disagree with the statement above. RAFTS does not even
> conceptually go through compiling a subroutine call when compiling a
> word like + or SWAP.

Again. Only primitive subroutine threaded systems compile + or
SWAP as subroutine calls. On many systems that approach is slower
than IDT or DTC and so it is rarely used. But it opens the door
to a whole list of optimizations.

+ and SWAP and a lot of other words at the bootom are normally
optimized to inline or to combine with other instructions. I
am not talking about the stuff that gets optimized away. Nearer
the top complex Forth words have a different trade off and
do not benefit from inlining or other optimization techniques
in the same way. Even in the VFX examples that were posted
I saw Forth words being compiled as subroutine calls.

For this reason I think it makes sense to say that Forth native
code is STC with various optimizations. But there is no
fixed number that makes a clean distiction between STC with
optimization and native code.

When I see a compiler that has register allocation, code
inlining, combining operations to remove sections of code,
tail recursion, and other tricks I call that optimization.
I am not so quick to say that combination doesn't qualify,
only this product is an optimizer. Sorry there are a
lot of different ways to optimize.

> I also wouldn't call any of these compilers optimizing (normally this
> means globally optimizing, i.e., doing such things as loop-invariant
> code motion, strength reduction and induction variable elimination).
> AFAIK no currently available Forth compiler does this.

Ok, you are applying a definition of optimization that says
normally in other systems optimization means global. Of course
compilation also has a different meaning in Forth than it does
"normally" but that doesn't me that we say that Forth doesn't
compile. Forth isn't "normal" in that way although I realize
that the goal of many people is to normalize it. For Forth
compiling means extending Forth, not what it "normally" means.

> The compilers that start with subroutine threading, then inline and
> peephole-optimize can be called peephole-optimizing, though.

And if they add register allocation?
And if they add tail recursion?
And if they add other optimizations?
And if they add code profiing?
And if they add recursive profiling and recompilation?

When would it become an optimizing compiler? It seems
that the definition of an optimizing compiler is my version
only or maybe one other.

If it isn't a matter of degree but rather a matter of applying
the "normal" definition of optimization then we are not talking
Forth. But I realize that we just have different definitions
for the terms. And these are just my opinions

Tom Zegub

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
#1

On Sat, 22 Jul 2000 12:21:44 -0700,
Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:

>
>In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension has
>a consistent, regular form (compiled execution tokens). This
>consistency in turn is leveragable by the programmer (in a way
>the virtual machine is "deeper" and more reflective due to its
>regularity). A native-code optimizing Forth implies a shallower
>virtual machine due to the irregularity of its intermediate code.
>For example if I know that compiled tokens are always the same
>size, I can take advantage of this knowledge in extending my
>forth with a decompiler. On an optimizing native code compiler
>one can't "see" as deeply into the virtual machine.
>

#2


On Sat, 22 Jul 2000 20:41:05 -0700,
Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:

>I did not make value judgements on whether native-code
>optimizing Forths are superior or inferior to non-optimizing
>threaded Forths. Superiority would be relative to the demands of
>the task at hand.
>
>I'm only making the point that IMHO their is a major but subtle
>difference in what I call the "depth of the virtual machine"
>(for want of a better term) when going from non-optimizing
>threaded Forth (whether IDT,DT,TT,SRT) to native-code optimizing
>Forth.
>I believe this point is relevant to the current discussion.
>

Yes, very much how I see it. My idea of "reflectivity of the
language" is effectively the same as your "depth of the virtual
machine". The point is for communications to have a distinction for
a Forth which leaves a significant part of the VM in the code which
can be utilized at the code level as oppose to a Forth which
optimizes most if not all of the VM away.
Jerry made a point that with respect to portability no distinction is
necessary but you are correct in that this has nothing to do with
portability but with usage of the VM within the code.
And this is not a disparagement of optimizing compilers. It's
simply one of communications to identify a category of Forth that at
least three of us have interest in. I for one would be pleased to
have an optimizing Forth compiler in _addition_ to a "traditional" Forth.
I very much liked the arrangement of the Russian Golden Porcupine
Forth (a 16-bit DOS Forth) which separated its three major aspects
into a compiler, interpreter and optimizer. The main Forth was the
SRT(or DT?) compiler. It could be included in a small wrapper to
become an interpreter. And the output of the compiler could be piped
through the optimizer for code reduction.
So the question at this point is, what is the common term for a Forth
which is not an optimizing compiler but has "depth of VM?" In my
mind "Forth" by itself, "traditional Forth" or "classic Forth"
all communicate that distinction.

cLIeNUX user

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
j...@ieee.org...
>Mark Humphries wrote:
>>
>> > Jerry Avins <j...@ieee.org> wrote:
>> >> Mark Humphries wrote:
>>
>> [snip]
>>
>> >
>> > I make executables with F-PC and SwiftForth on a PC clone.
>> > they have a .exe file extension.
>>
>> So do I, but my .exe is a new Forth, not just a stand-alone
>> application. A distinction between Forth compilation and
>> traditional programming language compilation is:
>>
>> Forth + Source = Extended Forth
>> .. vs. ...
>> Program X source processed by Language Y tools outputs
>> standalone X application executable
>>
>> This distinction is a major reason why I use Forth.
>
>But not me, mostly. There is no way for the user to interact with much
>of my stuff except through switch closures.
>>
>> >> If I use the same source to extend two different Forths, I
>> >> still end up with two different extended-Forths :)
>>
>> >> In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension
>> >> has a consistent, regular form (compiled execution tokens).
>> >> This consistency in turn is leveragable by the programmer (in
>> >> a way the virtual machine is "deeper" and more reflective due
>> >> to its regularity). A native-code optimizing Forth implies a
>> >> shallower virtual machine due to the irregularity of its
>> >> intermediate code.
>>
>> >> For example if I know that compiled tokens are always the same
>> >> size, I can take advantage of this knowledge in extending my
>> >> forth with a decompiler. On an optimizing native code compiler
>> >> one can't "see" as deeply into the virtual machine.
>>
>> I did not make value judgements on whether native-code
>> optimizing Forths are superior or inferior to non-optimizing
>> threaded Forths. Superiority would be relative to the demands of
>> the task at hand.
>>
>> I'm only making the point that IMHO their is a major but subtle
>> difference in what I call the "depth of the virtual machine"
>> (for want of a better term) when going from non-optimizing
>> threaded Forth (whether IDT,DT,TT,SRT) to native-code optimizing
>> Forth.
>> I believe this point is relevant to the current discussion.
>>
>It's relevant to the discussion we ought to be having, but Rick H. has
>been calling native-code optimizing compilers The Class Of False Forths.
>That's what I wanted to refute.

That's a bit of an exaggeration of what I've said. I'm calling native code
compiled Forths "Forth plus other". ANd I don't think they're bad. I just
think people should be clearer about what is what when discussing such
beasts among Forthers. I think the reaction my comments have recieved
supports that notion.

Perhaps a term is needed like "Plain Threaded Forth" or "Plain VM
Forth" or something.

Rick Hohensee
ri...@clienux.com


>
>> Cheers,
>> Mark W. Humphries
>>
>> -----------------------------------------------------------
>Cheers to you too!
>

cLIeNUX user

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
tze...@dhc.net...
>#1
>On Sat, 22 Jul 2000 12:21:44 -0700,
>Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:
>
>>
>>In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension has
>>a consistent, regular form (compiled execution tokens). This
>>consistency in turn is leveragable by the programmer (in a way
>>the virtual machine is "deeper" and more reflective due to its
>>regularity). A native-code optimizing Forth implies a shallower
>>virtual machine due to the irregularity of its intermediate code.
>>For example if I know that compiled tokens are always the same
>>size, I can take advantage of this knowledge in extending my
>>forth with a decompiler. On an optimizing native code compiler
>>one can't "see" as deeply into the virtual machine.
>>
>
>#2
>On Sat, 22 Jul 2000 20:41:05 -0700,
>Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:
>
>>I did not make value judgements on whether native-code
>>optimizing Forths are superior or inferior to non-optimizing
>>threaded Forths. Superiority would be relative to the demands of
>>the task at hand.
>>
>>I'm only making the point that IMHO their is a major but subtle
>>difference in what I call the "depth of the virtual machine"
>>(for want of a better term) when going from non-optimizing
>>threaded Forth (whether IDT,DT,TT,SRT) to native-code optimizing
>>Forth.
>>I believe this point is relevant to the current discussion.
>>

Maybe "Threaded" for what I mean IS correct, but somewhat "classically" or
archaically. Maybe I mean it abstractly, and it's being taken
implementation-wise. Are all non-optimizing Forths a threading scheme?
How about "VM Threaded" ? Or "VM-only Forth". I kinda like "Plain Forth"
actually. Is Forth itself threaded conceptually? I think the first Forth
was, even though it was a text-like scheme.

Even if an optimizer is granular, interpretive, and the optimized words
are regular Forth words, the optimizations are external to the concept of
the Forth VM, even on Forth-like hardware. That's something I, and
apparently we, have trouble keeping track of.

Rick Hohensee
ri...@clienux.com

F...@ultratechnology.com

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
In article <8lfr0i$jf1$3...@news.smart.net>,
r@your_host.com (cLIeNUX user) wrote:

> Maybe "Threaded" for what I mean IS correct, but somewhat
> "classically" or

I usually use the term "traditional" Forth to refer to the
traditional way of doing things for the first half of the
history of Forth. Or I use the term "classical" Forth
trying to express the same idea.

> Is Forth itself threaded conceptually? I think the first
> Forth was, even though it was a text-like scheme.

I am not sure what you mean by a text-like scheme.

I like what Jack Woehr wrote in Seeing Forth on page 83
about this.

'In the Beginning Chuck created Forth and threaded inner interpreter.

After that came the explainers, or as former President Harry S.
Truman was fond of calling academic theorists, the "dejuicers,
experts who were afraid if they learned anything they wouldn't
be experts anymore".

Forth was proclaimed a "threaded interpretive language" (TIL).

And after that, the picture is increasingly less clear. Charles
Moore, inventor of Forth has said, "Forth is more an approach
than a specification for a programming language". Here, as
elsewhere, Moore staked out the highest ground; Forths shall
be described subsequently which posses only the faintest
echo of any such threaded interpreter, less, in fact, than
the later editions of M*cr*S*ft Q**ckB*S*C.'

It has been said, "If you have seen one Forth, you have seen
one Forth." I think there is a very big difference between
"a Forth" and "Forth". A given Forth provides an implementation
example was a corresponding specification. Forth is not A Forth
or even a collection of Forths, it is more an approach than
a specification for a programming language."

Of course ANS Forth is a specification for a programming language
and it can be met by a wide variety of approaches including
direct and indirect threaded and subroutine threaded and
native code implementations. Whether you talk about Forth
as an approach or a Forth specification A Forth can use
a native code compiler and it is still A Forth.

I doubt if anyone would object to your calling what I call
"traditional Forth" meaning threaded interpretive Forth,
"plain old threaded Forth" or whatever. I think the main
objection people have had is that it sounds like you
are saying it should be called "real Forth", "true Forth",
or a name that denies that some modern Forths are really
Forth.

Of course traditionally the term "Forth" meant "traditional
threaded Forth" to most people. Many people saw A Forth
and used its specification for their definition of Forth.
The only problem with that is that they may have a very
narrow definition of Forth which is more of a specification
than an approach.

Mark Humphries

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
Jerry Avins <j...@ieee.org> wrote:

>>> Jerry Avins <j...@ieee.org> wrote:
>>>> Mark Humphries wrote:

[snip]

>>>> In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension


>>>> has a consistent, regular form (compiled execution tokens).
>>>> This consistency in turn is leveragable by the programmer
>>>> (in a way the virtual machine is "deeper" and more
>>>> reflective due to its regularity). A native-code optimizing
>>>> Forth implies a shallower virtual machine due to the
>>>> irregularity of its intermediate code.
>>>> For example if I know that compiled tokens are always the
>>>> same size, I can take advantage of this knowledge in
>>>> extending my forth with a decompiler. On an optimizing
>>>> native code compiler one can't "see" as deeply into the
>>>> virtual machine.

>>> Decompiling is often a handy thing, but a decompiler that


>>> works for one indirect-threaded interpreter may not work for
>>> another, and certainly won't work on a direct-threaded one.

>> How did portability of source enter the discussion?

> I thought you brought it in. It seemed to me that you wrote
> that the source was somehow altered if, even though the
> program functioned identically, decompilation properties were
> altered.

Please read my sentence again (its still contained above in this
message). The example was used to contrast the effect of
threaded vs. native code on the depth of the virtual machine.
Portability of code between the two was not relevant issue.

>>> If a decompiler works on only one "Forth" out of three, does
>>> that make the one Forth an impostor?

>> There is no One True Forth, none of them are 'impostors'.
>> What's your point?

>That there is no One True Forth.

Well at least now we're aware that we agree :)

>>>> Getting back to the question of syntax. Forth has no fixed
>>>> syntax to speak of, a word does not <I>represent</I> an
>>>> action, it <I>invokes</I> an action (and might be redefined
>>>> on the fly to invoke another action).

>>> There is a little syntax. : , CREATE , VARIABLE , and other
>>> words demand a name following in the input stream. No
>>> definition can start with DOES>

>> Yes Forth has the least syntax of any language I know. Prefix
>> words just consume the next token on the input stream. More
>> complex syntactical structures are more a question of
>> convention than formal syntax.

> So when you wrote "no fixed syntax to speak of", you
> meant "not much syntax"? OK.

No I meant "no fixed syntax to speak of", note the
operative "fixed". See also Michael Gassenko's (sp.?) for
clarification on this point.

[snip]

>> Cheers,
>> Mark W. Humphries

>Cheers to you too!

:)

Mark Humphries

unread,
Jul 23, 2000, 3:00:00 AM7/23/00
to
"Tom Zegub" <tze...@dhc.net> wrote:

[snip]

> Yes, very much how I see it. My idea of "reflectivity of the
> language" is effectively the same as your "depth of the virtual
> machine". The point is for communications to have a
> distinction for a Forth which leaves a significant part of the
> VM in the code which can be utilized at the code level as
> oppose to a Forth which optimizes most if not all of the VM
> away.
> Jerry made a point that with respect to portability no
> distinction is necessary but you are correct in that this has
> nothing to do with portability but with usage of the VM
> within the code.
> And this is not a disparagement of optimizing compilers. It's
> simply one of communications to identify a category of Forth
> that at least three of us have interest in.

Thanks Tom for expressing it more clearly than I ever could.

> I for one would be pleased to have an optimizing Forth
> compiler in _addition_ to a "traditional" Forth.

Likewise.

[snip]

> So the question at this point is, what is the common term for
> a Forth which is not an optimizing compiler but has "depth of
> VM?" In my mind "Forth" by itself, "traditional Forth"
> or "classic Forth" all communicate that distinction.

Likewise for me.

But "Classic Forth" has negative connotations for some, sadly
many in clf often disparage classic threaded Forth offhand as
being stuck in the seventies. Perhaps we could find a more
neutral term.
We should at least add to the faq an explanation of the subtle
tradeoffs between optimization and "reflectivity/vm depth" to
assist newcomers in their selection of an appropriate Forth for
their needs.

Cheers,
Mark W. Humphries

cLIeNUX user

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to
F...@UltraTechnology.com...
>In article <8lfr0i$jf1$3...@news.smart.net>,
> r@your_host.com (cLIeNUX user) wrote:

>
>I doubt if anyone would object to your calling what I call
>"traditional Forth" meaning threaded interpretive Forth,
>"plain old threaded Forth" or whatever. I think the main
>objection people have had is that it sounds like you
>are saying it should be called "real Forth", "true Forth",
>or a name that denies that some modern Forths are really
>Forth.

Well, an optimizing Forth is Forth and "other". Conceptually, not
practically. And again, such beasts are great, but I'm most interested in
the un-optimized part.

Rick Hohensee
www.clienux.com

Stephen Pelc

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to comp.lang.forth
Tom Zegub wrote in message
<14899FBA978A2749.DAEF995C...@lp.airnews.net>...

>I for one would be pleased to
>have an optimizing Forth compiler in _addition_ to a "traditional"
Forth.
In ProForth VFX use the switches
unoptimised
optimised
--
Stephen Pelc, s...@mpeltd.demon.co.uk
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)2380 631441, fax: +44 (0)2380 339691
web: http://www.mpeltd.demon.co.uk - free ProForth downloads!


Bernd Paysan

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to
Anton Ertl wrote:
> Actually RAFTS generates native code for a word when the word is
> EXECUTEd. Delaying the compilation that long gives the compiler the
> maximum information for possible optimization (e.g., inlining).

The to-be-inlined words are already available at definition time,
otherwise it won't be Forth (no forward references except RECURSE). If
you introduce forward references (e.g. bigFORTH has them), you can
compile a definition after the last forward reference it contains is
resolved.

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

Jerry Avins

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to
cLIeNUX user wrote:
>
...

> >It's relevant to the discussion we ought to be having, but Rick H. has
> >been calling native-code optimizing compilers The Class Of False Forths.
> >That's what I wanted to refute.
>
> That's a bit of an exaggeration of what I've said. I'm calling native code
> compiled Forths "Forth plus other". ANd I don't think they're bad. I just
> think people should be clearer about what is what when discussing such
> beasts among Forthers. I think the reaction my comments have recieved
> supports that notion.
>
> Perhaps a term is needed like "Plain Threaded Forth" or "Plain VM
> Forth" or something.
>
> Rick Hohensee
> ri...@clienux.com
>
Frankly, I don't see why, but it's ok with me. As for my exaggeration, I
remember you writing something very like "THAT'S NOT FORTH!". Am I
wrong?

Jerry Avins

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to
> -----------------------------------------------------------
>
> Got questions? Get answers over the phone at Keen.com.
> Up to 100 minutes free!
> http://www.keen.com

Too lazy to snip: sorry!

I'm still digesting Michael's response.

I jumped in when Rick said that optimized native-code isn't Forth. If
some kid in the neighborhood brings me some code and asks, "Mr. Avins,
is this Pascal?", I'd feel pretty silly if I had to tell her that the
answer depended on what compiler it ran through. Yet there were (for a
short time) some who said that if no p-code is involved, it isn't
Pascal. My point has been all along that it's the source code that
determines the language, not the compiler or interpreter.

David Mitchell

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to
In article <397C513C...@ieee.org>, Jerry Avins <j...@ieee.org>
writes

>
>Too lazy to snip: sorry!
>

Too lazy to scroll through your posts.

Welcome to my killfile.

--
==========================================================================
David Mitchell ===== Visit: www.thehungersite.com
================================
da...@edenroad.demon.co.uk ===== Feed someone for nothing.
==========================================================================

Tom Zegub

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to
On 23 Jul 2000 22:18:58 GMT,
cLIeNUX user <r@your_host.com > wrote:

>actually. Is Forth itself threaded conceptually? I think the first Forth


>was, even though it was a text-like scheme.
>

It seems that the concept of Forth has evolved. Originally it was
a TIL so yes "threaded" was part of the concept. But at that time
the concept didn't distinguish between the source and realization
and major parts of the concept, threading and VM, are things in the
realization. They have no meaning in source.
Then came compilers that could produce a realization containing no
threading or VM and the concept of Forth shifted emphasis to aspects
of the source which were the same in both compilers and threaded
interpreters--words, dictionary, and grammar. This shift in emphasis
was strengthened by ANS which standardized only the source.
Forth started out as a big comprehensive lump of source and
realization. Today Forth is bifurcated into the Forth language,
aspects of the source, and the Forth model, the aspects of the
realization. The Forth language is pertinent to treaded
interpreters, compilers and ANS. The Forth modle is pertinent to
threaded interpreters but may or may not be to compilers and has no
relevance to ANS.

Tom Zegub

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to
On Sun, 23 Jul 2000 17:23:01 -0700,
Mark Humphries <mwhNO...@intranetsys.com.invalid> wrote:

>
>But "Classic Forth" has negative connotations for some, sadly
>many in clf often disparage classic threaded Forth offhand as
>being stuck in the seventies. Perhaps we could find a more
>neutral term.

Your right. Words like "classic" "traditional" and "modern" are
charged with a latent implication of improvement or lack of and
can mislead the unwary. "Traditional" seems less charged than
"classic." I cringe when I see "modern" freely used. I see an image
of a candy bar, an excited young girl, and a smiling dirty old
marketeer.

>We should at least add to the faq an explanation of the subtle

>tradeoff between optimization and "reflectivity/vm depth" to


>assist newcomers in their selection of an appropriate Forth for
>their needs.
>

Keep the title simple, just call it "VM Depth" or "Depth of VM." Use
the definition you posted last:
"In a non-optimizing threaded Forth (IDT,DT,TT,SRT) extension ...
etc."

This should suffice.

Marcel Hendrix

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to
Tom Zegub wrote in message
<15D2B029D377F6D8.726B2E5B...@lp.airnews.net>...

> It seems that the concept of Forth has evolved. Originally it was
> a TIL so yes "threaded" was part of the concept. But at that time
> the concept didn't distinguish between the source and realization
> and major parts of the concept, threading and VM, are things in the
> realization. They have no meaning in source.


Just a small comment. On the 'old' systems being threaded had a
clear function: it compacted the code by excluding call opcodes.
This theoretically decreases size by 33% on a 16-bit machine.

On current hardware the call sequences have much longer addresses
and the compaction is not so noticeable. IIRC, Anton Ertl found
that (on Alpha) Forth compiled to native code was not any larger
than code translated by more traditional approaches.

-marcel


Leonard Zettel

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to

cLIeNUX user wrote:
>
> wtan...@dolphin.openprojects.net...
> >On 22 Jul 2000 07:27:26 GMT, cLIeNUX user wrote:
> >
> >The judge, jury, and executioner declares a mistrial and demands new
> >evidence.
>
> I un-marked-as-read this post, went offline, and set about the business of
> writing a long reply. After several paragraphs it occured to me that I
> have a somewhat personal, i.e. useless, definition of "threading".
>
> What is the term for "concatenate Forth words into new Forth words without
> any internal manipulations of the resultant words." ?
>

Compile. (though not the only way to compile). If it's good enough
for Brodie it's good enough for me.
-LenZ-

(snip)

Stephen Pelc

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to comp.lang.forth

Marcel Hendrix wrote in message
<9645416...@dibbs3.eur.cis.philips.com>...

>On current hardware the call sequences have much longer addresses
>and the compaction is not so noticeable. IIRC, Anton Ertl found
>that (on Alpha) Forth compiled to native code was not any larger
>than code translated by more traditional approaches.

As an example of this, here is the code produced by ProForth
VFX v3.1 for a simple definition

: n>char \ n -- char
dup 9 >
if 7 + then
[char] 0 +
; ok
ok
dis n>char
N>CHAR
( 00478F98 83FB09 ) CMP EBX, 09
( 00478F9B 7E03 ) JLE/NG 00478FA0
( 00478F9D 83C307 ) ADD EBX, 07
( 00478FA0 83C330 ) ADD EBX, 30
( 00478FA3 ) RET
12 bytes ok

Note that a threaded system will require at least 9 tokens,
without counting literals and branch targets. On a 32 bit target
these will require at least 36 bytes, rather more than the 12
bytes needed by a native code system.

Bruce McFarling

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to
On Tue, 25 Jul 2000 14:59:24 -0400, Leonard Zettel <zet...@acm.org>
wrote:

>cLIeNUX user wrote:
>> I un-marked-as-read this post, went offline, and set about the business of
>> writing a long reply. After several paragraphs it occured to me that I
>> have a somewhat personal, i.e. useless, definition of "threading".

>> What is the term for "concatenate Forth words into new Forth words without
>> any internal manipulations of the resultant words." ?

>Compile. (though not the only way to compile). If it's good enough
>for Brodie it's good enough for me.

Not specific enough -- it doesn't carry the connotation of no internal
manipulations of the resultant words. "Compile without optimisation"
would suffice.

(
----------
Virtually,

Bruce McFarling, Newcastle,
ec...@cc.newcastle.edu.au
)

Elizabeth D. Rather

unread,
Jul 25, 2000, 3:00:00 AM7/25/00
to
Marcel Hendrix wrote:
>
> Tom Zegub wrote in message
> <15D2B029D377F6D8.726B2E5B...@lp.airnews.net>...
>
> > It seems that the concept of Forth has evolved. Originally it was
> > a TIL so yes "threaded" was part of the concept. But at that time
> > the concept didn't distinguish between the source and realization
> > and major parts of the concept, threading and VM, are things in the
> > realization. They have no meaning in source.
>
> Just a small comment. On the 'old' systems being threaded had a
> clear function: it compacted the code by excluding call opcodes.
> This theoretically decreases size by 33% on a 16-bit machine.
>
> On current hardware the call sequences have much longer addresses
> and the compaction is not so noticeable. IIRC, Anton Ertl found
> that (on Alpha) Forth compiled to native code was not any larger
> than code translated by more traditional approaches.

Our experience is that going to direct code compilation on a 32-bit
processor saves significantly (~25%) with some in-place expansion of
primitives but no optimization; adding optimization saves even more.
And of course the performance improvement is very substantial. Even on
16-bit platforms it's more of a break-even in size (slight cost on
8051's).

Among the contributing factors are elimination of code field and NEXT,
use of short calls where possible, and other strategies.

IMO the biggest reason for the ITC's longevity was it's simple and
compact implementation; when your compiler is running in a
resource-constrained target, it pays to keep it simple. When it's
running in today's PC or workstation it pays to use all those resources
to make a faster, smaller target.

Cheers,
Elizabeth

--
===============================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310-372-8493
111 N. Sepulveda Blvd. Fax: +1 310-318-7130
Manhattan Beach, CA 90266
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
===============================================

William Tanksley

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to
On 23 Jul 2000 00:26:53 GMT, cLIeNUX user wrote:

>I un-marked-as-read this post, went offline, and set about the business of
>writing a long reply. After several paragraphs it occured to me that I
>have a somewhat personal, i.e. useless, definition of "threading".

>What is the term for "concatenate Forth words into new Forth words without
>any internal manipulations of the resultant words." ?

I don't have any objection to you using the verbed word "thread" with that
meaning. Just as long as we're clear on what you mean.

>i.e. what is a term that means, "Without optimizing, make new
>definitions, regardless of implementation." ?

You could say "compiling without optimization".

>I still think, although I have perhaps expressed it poorly, the
>distinction between the above and conventional compilation is important.

Okay.

>Rick Hohensee

--
-William "Billy" Tanksley

Jerry Avins

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to
Stephen Pelc wrote:
>
> Marcel Hendrix wrote in message
> <9645416...@dibbs3.eur.cis.philips.com>...
> >On current hardware the call sequences have much longer addresses
> >and the compaction is not so noticeable. IIRC, Anton Ertl found
> >that (on Alpha) Forth compiled to native code was not any larger
> >than code translated by more traditional approaches.
>

How does

: n>char \ n -- char
dup 9 >

7 and +
[char] 0 +
;
compare in length and execution time?

Stephen Pelc

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to comp.lang.forth
cLIeNUX user wrote in message <8lde4d$bo0$1...@news.smart.net>...

>What is the term for "concatenate Forth words into new Forth words
without
>any internal manipulations of the resultant words." ?

Taking this from a different viewpoint, I think what you are asking for
is
a term for compilation that permits accurate decompilation, in other
words there is a one-to-one match between source code and the
object code. Even in traditional threaded code, this can be difficult
because of the use of BRANCH ?BRANCH and LIT compiled tokens.
Preservation of reciprocity, perhaps? This takes us back to systems
such as the Jupiter Ace.

Stephen Pelc

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to comp.lang.forth
Jerry Avins wrote in message <397E69F5...@ieee.org>...

>How does
>: n>char \ n -- char
> dup 9 >
> 7 and +
> [char] 0 +
>;
>compare in length and execution time?

> : n>char \ n -- char


> dup 9 >
> if 7 + then
> [char] 0 +
> ; ok
> ok
> dis n>char
> N>CHAR
> ( 00478F98 83FB09 ) CMP EBX, 09
> ( 00478F9B 7E03 ) JLE/NG 00478FA0
> ( 00478F9D 83C307 ) ADD EBX, 07
> ( 00478FA0 83C330 ) ADD EBX, 30
> ( 00478FA3 ) RET
> 12 bytes ok

: n>char \ n -- char


dup 9 >
7 and +
[char] 0 +

; ok
dis n>char

N>CHAR
( 00478F98 83FB09 ) CMP EBX, 09

( 00478F9B 0F9FC0 ) SETNLE/G AL
( 00478F9E F6D8 ) NEG AL
( 00478FA0 0FBED0 ) MOVSX EDX, AL
( 00478FA3 83E207 ) AND EDX, 07
( 00478FA6 03DA ) ADD EBX, EDX
( 00478FA8 83C330 ) ADD EBX, 30
( 00478FAB ) RET
20 bytes ok

Apart from being larger, this is probably slower on all i32
CPUs.

Leonard Zettel

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to

Stephen Pelc wrote:
>
> cLIeNUX user wrote in message <8lde4d$bo0$1...@news.smart.net>...
> >What is the term for "concatenate Forth words into new Forth words
> without
> >any internal manipulations of the resultant words." ?
>
> Taking this from a different viewpoint, I think what you are asking for
> is
> a term for compilation that permits accurate decompilation, in other
> words there is a one-to-one match between source code and the
> object code. Even in traditional threaded code, this can be difficult
> because of the use of BRANCH ?BRANCH and LIT compiled tokens.
> Preservation of reciprocity, perhaps? This takes us back to systems
> such as the Jupiter Ace.
> --

Good point, which I thought about only after my post on this subject.
The compiler directives and other immediate words always went beyond
"concatenate --- without any internal manipulations".
Pile on state smart words and you are even farther from that, and
you haven't gotten to the pearl of Forth yet.
On reflection, going to native code isn't that big an extension.

Talking about it is probably also exacerbated by the corruption of
the term "optimize" (first in business and then in programming
circles) into a mere fancy-schmancy synonym for "improve".
-LenZ-

cLIeNUX user

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to
s...@mpeltd.demon.co.uk...
>cLIeNUX user wrote in message <8lde4d$bo0$1...@news.smart.net>...
>>What is the term for "concatenate Forth words into new Forth words
>without
>>any internal manipulations of the resultant words." ?
>
>Taking this from a different viewpoint, I think what you are asking for
>is
>a term for compilation that permits accurate decompilation, in other
>words there is a one-to-one match between source code and the
>object code. Even in traditional threaded code, this can be difficult
>because of the use of BRANCH ?BRANCH and LIT compiled tokens.

That's an aspect of it, or perhaps, a good way to define it.

Uh oh.

I think what you are alluding to is that flow control abstractions, words
_other than_ BRANCH, ?BRANCH and LIT, can't be recovered. Branches and
literals can be recovered. That's where Forth is a "true compiler". That's
a bit of a hole in my assertion that Forth isn't a compiler. Words that
use LOOP and other abstractions would still decompile word-to-word though,
but you'd have some fancy heuristics to get LOOP back, yes? SO, a Forth
that does LOOP and so on is still bounded conceptually by the Forth VM,
yes? Simple Forths use the words you mention to do LOOP and so on, yes?
And optimizing Forths use native code? POSTPONE is wierd vis-a-vis SEE too
I think.


H3sm BTW just has the plain branches and stuff. I say in "man H3sm"
that to the extent that Forth has a "compiler", H3sm has an assembler.

>Preservation of reciprocity, perhaps? This takes us back to systems
>such as the Jupiter Ace.

"Simple Forth" ?

What is your optimizer's effect on code size? That's another aspect.

Rick Hohensee
www.clienux.com


>--

Tom Zegub

unread,
Jul 26, 2000, 3:00:00 AM7/26/00
to
On Tue, 25 Jul 2000 22:28:01 GMT,
Elizabeth D. Rather <era...@forth.com> wrote:

>
>IMO the biggest reason for the ITC's longevity was it's simple and
>compact implementation; when your compiler is running in a
>resource-constrained target, it pays to keep it simple. When it's
>running in today's PC or workstation it pays to use all those resources
>to make a faster, smaller target.
>

Forth for many is man-machine. Its interactiveness fits the software
to the user like a glove giving him fluent control of the machine.
The interactiveness of Forth is augmented by ITC because ITC leaves
the binary structured in a way which can be easily manipulated
directly with no special tools. Anyone who has spent years in a smelly
noisy testbed with foot thick maps on his lap trying to match
addresses with code listings will understand how indescribable nice
it is to make a patch simply by:

SEE foo
' bar <address SEEn> !

The patching is not intended for production code. It is just
another dimension of interacting with the computer during production.
For production code, finished and not intended to be manipulated by
patching, the source can be compiled to provide the smallest and
fastest form as a matter of polish. But much of Forth is used in
support roles where polish is less important than interactiveness.
For example, the hardware engineer testing his new board isn't
concerned with how polished his code is; he just wants the
most simple and convenient way to manipulate the software as he focuses
on board issues. Plus he wants a single simple and effective tool; not
a tool that itself needs lots of support.
It may be that ITC is still used because interactiveness and
simplicity are still found convenient and it is of no consequence to
the source what threading type or native code will be used. The same
source can be compiled for polish whenever ready.

Stephen Pelc

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to comp.lang.forth
cLIeNUX user wrote in message <8ln57g$b6d$1...@news.smart.net>...

>I think what you are alluding to is that flow control abstractions,
words
>_other than_ BRANCH, ?BRANCH and LIT, can't be recovered.
The Jupiter Ace and others simply compiled magic tokens for
each control structure directive. That made decompilation easy
at the cost of a few apparently duplicated words.

>What is your optimizer's effect on code size? That's another aspect.

In the main smaller code is faster code, and faster code is smaller
code - as a general rule with some exceptions. VFX gains its
speed in two main ways. Firstly it produces fewer instructions
than other Forth code generators. Secondly it produces less
memory traffic. Once the code generator has passed a certain
point, optimised code is usually smaller than threaded code,
somewhat dependent on coding style and CPU architecture.
But even our VFX ARM compiler produces code that is
smaller than threaded code. My earlier example of the
word N>CHAR showed optimised code that was less
than one third the size of threaded code.

Marcel Hendrix

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Elizabeth D. Rather wrote in message <397E13FF...@forth.com>...
> Marcel Hendrix wrote:

[..]


>> Just a small comment. On the 'old' systems being threaded had a
>> clear function: it compacted the code by excluding call opcodes.
>> This theoretically decreases size by 33% on a 16-bit machine.
>>

>> On current hardware the call sequences have much longer addresses
>> and the compaction is not so noticeable. IIRC, Anton Ertl found
>> that (on Alpha) Forth compiled to native code was not any larger
>> than code translated by more traditional approaches.

[..]


> IMO the biggest reason for the ITC's longevity was it's simple and
> compact implementation; when your compiler is running in a
> resource-constrained target, it pays to keep it simple.

[..]

Compact: OK. Simple? If you are coming from a hardware background
and want to understand what the *CPU* is doing, ITC is not 'simple'.
OTOH, even I can explain to an engineer in two minutes how a
subroutine-"threaded" Forth works. Try that with ITC.

Isn't it strange in hindsight that such a radically simplified
language as Forth started out with a very complicated internal
representation? Or did the first Forth programs all use 100% of
main memory?

-marcel


Bart Lateur

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Marcel Hendrix wrote:

>Compact: OK. Simple? If you are coming from a hardware background
>and want to understand what the *CPU* is doing, ITC is not 'simple'.
>OTOH, even I can explain to an engineer in two minutes how a
>subroutine-"threaded" Forth works. Try that with ITC.

In ITC, a compiled high-level word consists of a sequence of tokens,
each token representing a FORTH word. The interpreter goes through this
list, and executes each word in turn.

The tokens are simply the address of the FORTH words. So, actually, we
have a list of pointers to the words that need to be executed.

Now, FORTH words can be considered as belonging to a class, each having
only one, implicit method. For example, all constants belong to a class
CONSTANT.

The first integer of a FORTH word is simply a pointer to that implicit
method of the class, so executing thet word will make the CPU jump to
that method, which always is native code. What follows is the body, or
contents of the word, and is basically different for each FORTH word.
For variables and constants, it is the value; for high-level words, it
is that famous list of execution tokens.

All high-level words are of the same class, so they all use the same
implicit method. What it does, is store the instruction pointer on a
return stack, and then set it to the body of that word. There is a
counterpart, EXIT, which pops the value from the return stack, back into
the instruction pointer.

Words written in assembler (CODE words) are the only instance of their
very own class, for which the method is the definition in native code,
which usually is stored inside the body of that word. So the method
pointer simply points to the code body.

All variables have a common method, which simply takes the address of
the word body, and ushes it onto the data stack.


That's it. Am I under two minutes?

--
Bart.

Stephen Pelc

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to comp.lang.forth
Tom Zegub wrote in message ...

> The interactiveness of Forth is augmented by ITC because ITC leaves
>the binary structured in a way which can be easily manipulated
>directly with no special tools. Anyone who has spent years in a smelly
>noisy testbed with foot thick maps on his lap trying to match
>addresses with code listings will understand how indescribable nice
>it is to make a patch simply by:
>
> SEE foo
> ' bar <address SEEn> !
There is no reason why you can't do this with STC and optimised
code. We have done this already both with our previous DTC
systems and with our current VFX systems, using a simple API
to hide carnal knowledge.

Marcel Hendrix

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Bart Lateur wrote in message ...

> Marcel Hendrix wrote:
>
>> Compact: OK. Simple? If you are coming from a hardware background
>> and want to understand what the *CPU* is doing, ITC is not 'simple'.
>> OTOH, even I can explain to an engineer in two minutes how a
>> subroutine-"threaded" Forth works. Try that with ITC.

> In ITC, a compiled high-level word consists of a sequence of tokens,
> each token representing a FORTH word. The interpreter goes through this
> list, and executes each word in turn.


[ Starting Forth in 200 words ... :-) ]

> That's it. Am I under two minutes?


How long did it take you to write it?

Now explain what the *CPU* must do. IP, W, RP, SP etc.
And explain *why* it must be done in that way (not the how).

Fire up your DOS debugger and trace through Gforth, pointing
out the interesting and oh so simple happenings to the eager
engineer at your side :-)

-marcel


Andrew Haley

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Marcel Hendrix (m.a.m....@tue.nl) wrote:
: If you are coming from a hardware background and want to understand

: what the *CPU* is doing, ITC is not 'simple'. OTOH, even I can
: explain to an engineer in two minutes how a subroutine-"threaded"
: Forth works. Try that with ITC.

I think you're assuming something untrue; as far as I know, many the
early CPUs did not have a subroutine mechanism, so any form of call
had to be implemented as a series of instructions and a stack had to
be created in memory. ITC isn't very much more complicated than that.

Andrew.

Marcel Hendrix

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Andrew Haley wrote in message <8lp6sr$smk$1...@korai.cygnus.co.uk>...


An insightful answer to my original question why Forth started out with
ITC, but it says nothing on why the mechanism survived so long?

-marcel


Mark Humphries

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
"Marcel Hendrix" <m.a.m....@tue.nl> wrote:

[snip]

>Now explain what the *CPU* must do. IP, W, RP, SP etc.
>And explain *why* it must be done in that way (not the how).

[snip]

BTW
The best comparative explanations of threading mechanisms I have
found are in the book:

Interpretation and Instruction Path Coprocessing
Eddy H. Debaere & Jan M. Van Campenhout
Computer Systems Series
MIT Press

This long out of print book also covers ITC,DTC,SRT,TT, and
other common intermediate encodings such as p-code, and a lisp
intermediate code. The second half of the book on using
coprocessor to accelerate interpreteted languages.

Cheers,
Mark W. Humphries

There is no discontinuity between creation and use with Forth.
-- from FORTH by W.P.Salman et al., Springer-Verlag

Mark Humphries

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Bart Lateur <bart....@skynet.be> wrote:
>Marcel Hendrix wrote:

>>OTOH, even I can explain to an engineer in two minutes how a
>>subroutine-"threaded" Forth works. Try that with ITC.

>In ITC, a compiled high-level word consists of a sequence
[etc... etc... snip]

Good show Bart!

Cheers,
Mark W. Humphries

Jet Thomas

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
"Stephen Pelc" <s...@mpeltd.demon.co.uk> wrote:
>Tom Zegub wrote in message ...

>> The interactiveness of Forth is augmented by ITC because ITC leaves
>>the binary structured in a way which can be easily manipulated
>>directly with no special tools. Anyone who has spent years in a smelly
>>noisy testbed with foot thick maps on his lap trying to match
>>addresses with code listings will understand how indescribable nice
>>it is to make a patch simply by:

>> SEE foo
>> ' bar <address SEEn> !

>There is no reason why you can't do this with STC and optimised
>code. We have done this already both with our previous DTC
>systems and with our current VFX systems, using a simple API
>to hide carnal knowledge.

There's no way to go from optimised code back to the original source code,
short of looking at the source. But if you have a way to go from optimised
code back to Forth, it might be a great teaching tool.

Elizabeth D. Rather

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Marcel Hendrix wrote:
>
> Andrew Haley wrote in message <8lp6sr$smk$1...@korai.cygnus.co.uk>...
> > Marcel Hendrix (m.a.m....@tue.nl) wrote:
> > : If you are coming from a hardware background and want to understand
> > : what the *CPU* is doing, ITC is not 'simple'. OTOH, even I can

> > : explain to an engineer in two minutes how a subroutine-"threaded"
> > : Forth works. Try that with ITC.
>
> > I think you're assuming something untrue; as far as I know, many the
> > early CPUs did not have a subroutine mechanism, so any form of call
> > had to be implemented as a series of instructions and a stack had to
> > be created in memory. ITC isn't very much more complicated than that.
>
> An insightful answer to my original question why Forth started out with
> ITC, but it says nothing on why the mechanism survived so long?

I stand by my previous explanation (simplicity of implementation).
Having explained it to a very large number of people from 1971 thru mid
90's I found it quite simple to understand, even for hardware folks.
You'll surely have noticed that there's a considerable body of ITC fans
still on c.l.f, and the advantages they cite are (1) simplicity of
implementation, and (2) simplicity of explanation (e.g. Dr. Wavrik).

cheers,

Stephen Pelc

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to comp.lang.forth
Jet Thomas wrote in message <8lpgu8$1es...@ix.netcom.com>...

>"Stephen Pelc" <s...@mpeltd.demon.co.uk> wrote:
>There's no way to go from optimised code back to the original source
code,
>short of looking at the source. But if you have a way to go from
optimised
>code back to Forth, it might be a great teaching tool.

Sorry, I was unclear. The point I was making was that it *is*
possible to patch optimised code, but on rereading the original
post it appears that Tom wants to be able to patch anywhere
in the original definition. What we have done is to allow definitions
to be PLUGged with a replacement and all inlining has to be
turned off during the original compilation.

Tom Zegub

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
On Thu, 27 Jul 2000 13:33:16 +0200,
Marcel Hendrix <m.a.m....@tue.nl> wrote:

>
>Now explain what the *CPU* must do. IP, W, RP, SP etc.
>And explain *why* it must be done in that way (not the how).
>

>Fire up your DOS debugger and trace through Gforth, pointing
>out the interesting and oh so simple happenings to the eager
>engineer at your side :-)
>

Why confuse them with superfluous details? I'd be surprised if any
hardware engineer that I know who is using Forth has a clue what IP
and W are; they never see them. What they know is that "." will
show and consume the number they just entered, SEE tick and store will
change a word in memory and for the most part P@ and P! will let them
pound the ports attached to their boards.
There are two positions in Forth, Behind the Wheel and Under the
Hood. Behind the Wheel is just using Forth which is the position for
the engineers in question. This position is characterized as petal to
the metal, blow and go. A few operator instructions and go do. There
may be an occasional surprise like finding an 0BRANCH where an IF was
expected but I don't know of any engineer too dense to figure that out.
Under the Hood is another story. Then it's time to slow way down
and do some head scratching. There will be a learning curve. But who
needs to be under the hood? Not our engineers other than taking a
peek. Under the Hood is for the mechanics who want to screw with
the language; not happy with a DO they want to build a FOR.

Marcel Hendrix

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to

Tom writes:

> Why confuse them with superfluous details? I'd be surprised if
> any hardware engineer that I know who is using Forth has a clue what IP and W
> are; they never see them.

Where I live they make a distinction between engineers and technicians.

-marcel

Jet Thomas

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
"Stephen Pelc" <s...@mpeltd.demon.co.uk> wrote:
>Jet Thomas wrote in message <8lpgu8$1es...@ix.netcom.com>...
:
>>There's no way to go from optimised code back to the original source
>>code, short of looking at the source. But if you have a way to go from
>>optimised code back to Forth, it might be a great teaching tool.

>Sorry, I was unclear. The point I was making was that it *is*
>possible to patch optimised code, but on rereading the original
>post it appears that Tom wants to be able to patch anywhere
>in the original definition. What we have done is to allow definitions
>to be PLUGged with a replacement and all inlining has to be
>turned off during the original compilation.

That makes sense. You just sparked an idea for me. If you can find a way
to go from your optimised code back to Forth, it might often turn out to be
better Forth than the original source code. At the least it would follow a
standard coding practice.

Jerry Avins

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
> --
> Stephen Pelc, s...@mpeltd.demon.co.uk
> MicroProcessor Engineering Ltd - More Real, Less Time
> 133 Hill Lane, Southampton SO15 5AF, England
> tel: +44 (0)2380 631441, fax: +44 (0)2380 339691
> web: http://www.mpeltd.demon.co.uk - free ProForth downloads!

Thank you. It confirms my suspicion, pointing out yet again that
insights from traditional threaded code aren't worth much with optimized
threaded code compilers. Perhaps that's part of the discomfort that some
have with them.

The bag of tricks that we developed over the years seems largely passé
with them. Replacing it isn't much of a chore, though. Avoiding
cleverness, or at least leaving the cleverness to the compiler, seems to
be a good approach.

Jerry Avins

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Bart Lateur wrote:
>
> Marcel Hendrix wrote:
>
> >Compact: OK. Simple? If you are coming from a hardware background

> >and want to understand what the *CPU* is doing, ITC is not 'simple'.
> >OTOH, even I can explain to an engineer in two minutes how a

> >subroutine-"threaded" Forth works. Try that with ITC.
>
> In ITC, a compiled high-level word consists of a sequence of tokens,
> each token representing a FORTH word. The interpreter goes through this
> list, and executes each word in turn.
>
> The tokens are simply the address of the FORTH words. So, actually, we
> have a list of pointers to the words that need to be executed.
>
> Now, FORTH words can be considered as belonging to a class, each having
> only one, implicit method. For example, all constants belong to a class
> CONSTANT.
>
> The first integer of a FORTH word is simply a pointer to that implicit
> method of the class, so executing thet word will make the CPU jump to
> that method, which always is native code. What follows is the body, or
> contents of the word, and is basically different for each FORTH word.
> For variables and constants, it is the value; for high-level words, it
> is that famous list of execution tokens.
>
> All high-level words are of the same class, so they all use the same
> implicit method. What it does, is store the instruction pointer on a
> return stack, and then set it to the body of that word. There is a
> counterpart, EXIT, which pops the value from the return stack, back into
> the instruction pointer.
>
> Words written in assembler (CODE words) are the only instance of their
> very own class, for which the method is the definition in native code,
> which usually is stored inside the body of that word. So the method
> pointer simply points to the code body.
>
> All variables have a common method, which simply takes the address of
> the word body, and ushes it onto the data stack.
>
> That's it. Am I under two minutes?
>
> --
> Bart.

That's beautiful. Really: a wonderful demonstration of the power of
abstraction. But Marcel wrote of explaining to a hardware person what
the _CPU_ does. Likening parts of Forth to OOP constructs doesn't
accomplish that.

Jerry Avins

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
"Elizabeth D. Rather" wrote:
>
> Marcel Hendrix wrote:
> >
> > Andrew Haley wrote in message <8lp6sr$smk$1...@korai.cygnus.co.uk>...
> > > Marcel Hendrix (m.a.m....@tue.nl) wrote:
> > > : If you are coming from a hardware background and want to understand

> > > : what the *CPU* is doing, ITC is not 'simple'. OTOH, even I can
> > > : explain to an engineer in two minutes how a subroutine-"threaded"
> > > : Forth works. Try that with ITC.
> >
> > > I think you're assuming something untrue; as far as I know, many the
> > > early CPUs did not have a subroutine mechanism, so any form of call
> > > had to be implemented as a series of instructions and a stack had to
> > > be created in memory. ITC isn't very much more complicated than that.
> >
> > An insightful answer to my original question why Forth started out with
> > ITC, but it says nothing on why the mechanism survived so long?
>
> I stand by my previous explanation (simplicity of implementation).
> Having explained it to a very large number of people from 1971 thru mid
> 90's I found it quite simple to understand, even for hardware folks.
> You'll surely have noticed that there's a considerable body of ITC fans
> still on c.l.f, and the advantages they cite are (1) simplicity of
> implementation, and (2) simplicity of explanation (e.g. Dr. Wavrik).
>
> cheers,
> Elizabeth
>
> --
> ===============================================
> Elizabeth D. Rather (US & Canada) 800-55-FORTH
> FORTH Inc. +1 310-372-8493
> 111 N. Sepulveda Blvd. Fax: +1 310-318-7130
> Manhattan Beach, CA 90266
> http://www.forth.com
>
> "Forth-based products and Services for real-time
> applications since 1973."
> ===============================================

I agree that the simplicity you cite is there, but it is in the concept,
not the code gyrations (for me at any rate). Clearly, you are much
better at explaining software issues to my hardware brethren than I. (I
enjoy watching you exhibit your expertise.)

Jerry Avins

unread,
Jul 27, 2000, 3:00:00 AM7/27/00
to
Leonard Zettel wrote:

>
> Stephen Pelc wrote:
> >
> > cLIeNUX user wrote in message <8lde4d$bo0$1...@news.smart.net>...
> > >What is the term for "concatenate Forth words into new Forth words
> > without
> > >any internal manipulations of the resultant words." ?
> >
> > Taking this from a different viewpoint, I think what you are asking for
> > is
> > a term for compilation that permits accurate decompilation, in other
> > words there is a one-to-one match between source code and the
> > object code. Even in traditional threaded code, this can be difficult
> > because of the use of BRANCH ?BRANCH and LIT compiled tokens.
> > Preservation of reciprocity, perhaps? This takes us back to systems
> > such as the Jupiter Ace.
> > --
> Good point, which I thought about only after my post on this subject.
> The compiler directives and other immediate words always went beyond
> "concatenate --- without any internal manipulations".
> Pile on state smart words and you are even farther from that, and
> you haven't gotten to the pearl of Forth yet.
> On reflection, going to native code isn't that big an extension.
>
> Talking about it is probably also exacerbated by the corruption of
> the term "optimize" (first in business and then in programming
> circles) into a mere fancy-schmancy synonym for "improve".
> -LenZ-
> > Stephen Pelc, s...@mpeltd.demon.co.uk
> > MicroProcessor Engineering Ltd - More Real, Less Time
> > 133 Hill Lane, Southampton SO15 5AF, England
> > tel: +44 (0)2380 631441, fax: +44 (0)2380 339691
> > web: http://www.mpeltd.demon.co.uk - free ProForth downloads!

"Optimize" means to make as good as possible. I suppose that the
"possible" part can mean "as good as my program can make it", but by
that standard every compiler produces optimized code. It boils down to
being one of those "you know what I mean" words, and that really means
that those who use it don't know either.

At least no one claims to have a compiler that enhances code. "Enhance"
doesn't mean "improve", "enlarge", or "make more encompassing". It means
"heighten" or "intensify" (literally, "raise" or "exalt").

It is loading more messages.
0 new messages