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

new novice package and slide-rule program

84 views
Skip to first unread message

Hugh Aguilar

unread,
Jun 23, 2010, 3:05:19 PM6/23/10
to
I updated my novice package and slide-rule program on the FIG website:
http://www.forth.org/novice.html

ZB

unread,
Jun 23, 2010, 4:09:51 PM6/23/10
to
Dnia 23.06.2010 Hugh Aguilar <hughag...@yahoo.com> napisał/a:

> I updated my novice package and slide-rule program on the FIG website:
> http://www.forth.org/novice.html

There is a remark:

#v+
I didn't use CREATE DOES> at all, in order to provide fast execution speed
on any compiler, including those that lack sophisticated code-optimization.
For example, my FIELD word is about an order of magnitude faster than a
version of FIELD written using CREATE DOES>.
#v-

Does it mean, that "CREATE... DOES>" makes code slow, and generally it should
be avoided, when possible?
--
Zbigniew

Jonah Thomas

unread,
Jun 23, 2010, 4:13:30 PM6/23/10
to

That depends on how it is implemented on your particular system. If you
are concerned that DOES> children might be slow, you should test it and
see.

ZB

unread,
Jun 23, 2010, 4:19:48 PM6/23/10
to
Dnia 23.06.2010 Jonah Thomas <jeth...@gmail.com> napisaďż˝/a:

>> #v+
>> I didn't use CREATE DOES> at all, in order to provide fast execution
>> speed on any compiler, including those that lack sophisticated
>> code-optimization. For example, my FIELD word is about an order of
>> magnitude faster than a version of FIELD written using CREATE DOES>.
>> #v-
>>
>> Does it mean, that "CREATE... DOES>" makes code slow, and generally it
>> should be avoided, when possible?
>
> That depends on how it is implemented on your particular system. If you
> are concerned that DOES> children might be slow, you should test it and
> see.

Well, the first sentence somewhat confirms your statement ("I didn't use


CREATE DOES> at all, in order to provide fast execution speed on any

compiler, including those that lack sophisticated code-optimization."). But
the second one lacks something like: "...when tested on XYZ-Forth".

But I understand, that this is Forth-variant dependent.
--
Zbigniew

Hugh Aguilar

unread,
Jun 23, 2010, 4:36:38 PM6/23/10
to
On Jun 23, 2:13 pm, Jonah Thomas <jethom...@gmail.com> wrote:

> ZB wrote:
> > Does it mean, that "CREATE... DOES>" makes code slow, and generally it
> > should be avoided, when possible?
>
> That depends on how it is implemented on your particular system. If you
> are concerned that DOES> children might be slow, you should test it and
> see.

Poor ZB doesn't know what a hornet's nest he has opened with this
question! This whole subject has been argued at length already --- we
just go around and around, and then leave by the same door as in we
came.

I say that CREATE DOES> is *always* slower than generated colon words.
The reason is that the DOES> code has to fetch the data that was
comma'd in after the CREATE. It can't assume that this data is
constant and compile literals, because the data is not guaranteed to
be constant. Some compilers (MPE, I'm told) have declarations of some
kind with which the programmer who writes the CREATE DOES> can
indicate that his comma'd-in data is constant, and the compiler can
optimize this data into literals within the DOES> code. This is
basically a non-standard work-around to the bad design of CREATE
DOES>. By comparison, *all* of my code in the novice package,
including :NAME, is ANS-Forth standard.

BTW, despite my comment that ZB quoted, I do actually use CREATE DOES>
in one place in the novice package. This is to define DEFER. The
reason is that the data can't be compiled as a literal because it
*isn't* constant --- the IS word can change it. Generally speaking,
unless you are going to change the data later on, you are better off
to use :NAME rather than CREATE DOES> and compile your data as
literals. The <ARY> and <WBUF> definers are examples of how this is
done.

ZB

unread,
Jun 23, 2010, 5:47:00 PM6/23/10
to
Dnia 23.06.2010 Hugh Aguilar <hughag...@yahoo.com> napisał/a:

> I say that CREATE DOES> is *always* slower than generated colon words.

But: "a magnitude slower" indeed?
--
Zbigniew

Jonah Thomas

unread,
Jun 23, 2010, 5:53:09 PM6/23/10
to
Hugh Aguilar wrote:

> I say that CREATE DOES> is *always* slower than generated colon words.
> The reason is that the DOES> code has to fetch the data that was comma'd
> in after the CREATE.

Each DOES> child adds an address to the stack. This can be a trivial
overhead. I don't see how to get the same effect with a colon word that
will be necessarily more efficient.

So, doing it in high-level Forth to show the steps and changing some
things around to make them easier,

: :DOES :NONAME ;

: compute-magic-address
\ get first aligned address after a definition's end
\ it will be this simple but it will vary across Forth systems.
17 ALLOT ALIGN ;

: DOES
>R : compute-magic-address POSTPONE LITERAL R> COMPILE, POSTPONE ; ;

This does not give us CREATE DOES> syntax but it gives the same end
result.

You could make a character array like:

:DOES + ; DOES BARRAY ," testing"

In this particular case you could do

' + DOES BARRAY1 ," more tests"

The child word BARRAY does two things, it puts a literal on the stack,
and it executes a colon definition.

CREATE DOES> is more complicated, but its end result can be just the
same. Put a literal on the stack (giving the address of the start of the
data field) and execute the code after DOES> . I see no way to make a
colon definition that's a lot more efficient. If you put the literal at
the beginning of the colon definition you save one call, but to save that
one call you have to copy the whole colon definition into each child
word. What you gain in speed you lose badly in size.

CREATE DOES> has a lot of complication but it's all compile-time
complication without any obvious inefficiency at the child execution time.

Stephen Pelc

unread,
Jun 23, 2010, 5:52:18 PM6/23/10
to
On 23 Jun 2010 22:09:51 +0200, ZB <zbTH...@ispid.THIS-NOcom.pl>
wrote:

>#v+
> I didn't use CREATE DOES> at all, in order to provide fast execution speed
> on any compiler, including those that lack sophisticated code-optimization.
> For example, my FIELD word is about an order of magnitude faster than a
> version of FIELD written using CREATE DOES>.
>#v-
>
>Does it mean, that "CREATE... DOES>" makes code slow, and generally it should
>be avoided, when possible?

No. Hugh has a particular issue with one implementation and one
problem set. However, to my knowledge he has not posted numbers,
nor has he tried several Forth systems. Our measurements on VFX
Forth indicate perhaps a couple of percent difference. However,
this is completely masked by Hugh's tendency to use the return stack
on an x86, which costs him lots and lots of cclock cycles.

Essentially, Hugh's claim of an order of magnitude (10:1) has been
experimentally disproved. The real difference may be a few percent in
some cases. The differences depend heavily on the compiler being used.

Stephen


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

Hugh Aguilar

unread,
Jun 23, 2010, 5:58:45 PM6/23/10
to
On Jun 23, 3:47 pm, ZB <zbTHIS...@ispid.THIS-NOcom.pl> wrote:
> Dnia 23.06.2010 Hugh Aguilar <hughaguila...@yahoo.com> napisa /a:

>
> > I say that CREATE DOES> is *always* slower than generated colon words.
>
> But: "a magnitude slower" indeed?
> --
> Zbigniew

On SwiftForth, yes --- see the disassembly I provided in novice.txt.
Also, I got similar results with 3ARRAY. Try this for yourself.
Compare a disassembly of a SLOW-3ARRAY word to a disassembly of a
3ARRAY word. All in the novice package.

Hugh Aguilar

unread,
Jun 23, 2010, 6:00:46 PM6/23/10
to

What are you talking about??? The whole point of :NAME is that you
don't have to put a literal address on the stack and then fetch
constants offset from that address. The constants just get compiled as
literals.

Hugh Aguilar

unread,
Jun 23, 2010, 6:01:41 PM6/23/10
to
On Jun 23, 3:52 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> this is completely masked by Hugh's tendency to use the return stack
> on an x86, which costs him lots and lots of cclock cycles.

???

Elizabeth D Rather

unread,
Jun 23, 2010, 6:01:17 PM6/23/10
to

No. Possibly not slower at all, depending on the implementation. Hugh
has produced no evidence to justify this statement, though he has been
frequently asked to. No one else shares this opinion. If I were you,
I'd ignore it.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

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

Jonah Thomas

unread,
Jun 23, 2010, 6:16:45 PM6/23/10
to
Hugh Aguilar wrote:

> What are you talking about??? The whole point of :NAME is that you don't
> have to put a literal address on the stack and then fetch constants
> offset from that address. The constants just get compiled as literals.

I'm talking about writing an array.

If I want to do

2000 0 do i barray c@ . loop

I do not want to compile 2000 literals in place of my array word.

You might be doing something different. If I'm going to have one instance
of a data structure then it makes sense to compute the addresses inside
that data structure once and compile them as literals. If there are two
instances then it's doubtful. If there are three then it's questionable
whether the speed increase from literals outweighs the overhead of three
different sets of definitions. If there are 20 then I'll probably want to
access my different fields as offsets from a base address, and then I
hand the one routine 20 different base addresses.

Have I misunderstood what you're talking about?

Hugh Aguilar

unread,
Jun 23, 2010, 6:51:46 PM6/23/10
to
On Jun 23, 4:16 pm, Jonah Thomas <jethom...@gmail.com> wrote:
> Have I misunderstood what you're talking about?

Yes.

Why don't you just download the novice package and look at it? That is
why I uploaded it!

Krishna Myneni

unread,
Jun 23, 2010, 6:57:43 PM6/23/10
to
On Jun 23, 4:47 pm, ZB <zbTHIS...@ispid.THIS-NOcom.pl> wrote:
> Dnia 23.06.2010 Hugh Aguilar <hughaguila...@yahoo.com> napisa /a:

>
> > I say that CREATE DOES> is *always* slower than generated colon words.
>
> But: "a magnitude slower" indeed?
> --
> Zbigniew


Unless there is any execution speed data to prove otherwise, for a
wide range of problems, I see no need to shy away from using
"CREATE ... DOES>". The late Dr. Julian Noble, in Scientific Forth,
referred to CREATE ... DOES> as the "pearl of Forth".

Krishna

Hugh Aguilar

unread,
Jun 23, 2010, 7:05:03 PM6/23/10
to
On Jun 23, 4:01 pm, Elizabeth D Rather <erat...@forth.com> wrote:
> On 6/23/10 11:47 AM, ZB wrote:
>
> > Dnia 23.06.2010 Hugh Aguilar<hughaguila...@yahoo.com>  napisał/a:
>
> >> I say that CREATE DOES>  is *always* slower than generated colon words.
>
> > But: "a magnitude slower" indeed?
>
> No.  Possibly not slower at all, depending on the implementation.  Hugh
> has produced no evidence to justify this statement, though he has been
> frequently asked to.  No one else shares this opinion.  If I were you,
> I'd ignore it.
>
> Cheers,
> Elizabeth

This is such baloney!

We have covered this before, but here is the SwiftForth (v2)
disassembly again:

2 4 8 16 slow-3array sss ok

see sss
494B3F 47B637 ( slow-3array +78 ) CALL E8F36AFEFF ok

see slow-3array
47B5BF 40DDBF ( CREATE ) CALL E8FB27F9FF
47B5C4 4 # EBP SUB 83ED04
47B5C7 EBX 0 [EBP] MOV 895D00
47B5CA 40828F ( , ) CALL E8C0CCF8FF
47B5CF EBX PUSH 53
47B5D0 0 [EBP] EBX MOV 8B5D00
47B5D3 4 # EBP ADD 83C504
47B5D6 EBX ECX MOV 8BCB
47B5D8 4 [EBP] EBX MOV 8B5D04
47B5DB 0 [EBP] EAX MOV 8B4500
47B5DE EAX 4 [EBP] MOV 894504
47B5E1 ECX 0 [EBP] MOV 894D00
47B5E4 4 # EBP SUB 83ED04
47B5E7 EBX 0 [EBP] MOV 895D00
47B5EA EBX POP 5B
47B5EB 0 [EBP] EAX MOV 8B4500
47B5EE EBX MUL F7E3
47B5F0 EAX EBX MOV 8BD8
47B5F2 4 # EBP ADD 83C504
47B5F5 4 # EBP SUB 83ED04
47B5F8 EBX 0 [EBP] MOV 895D00
47B5FB 40828F ( , ) CALL E88FCCF8FF
47B600 EBX ECX MOV 8BCB
47B602 4 [EBP] EBX MOV 8B5D04
47B605 0 [EBP] EAX MOV 8B4500
47B608 EAX 4 [EBP] MOV 894504
47B60B ECX 0 [EBP] MOV 894D00
47B60E 0 [EBP] EAX MOV 8B4500
47B611 EBX MUL F7E3
47B613 EAX EBX MOV 8BD8
47B615 4 # EBP ADD 83C504
47B618 4 # EBP SUB 83ED04
47B61B EBX 0 [EBP] MOV 895D00
47B61E 40828F ( , ) CALL E86CCCF8FF
47B623 0 [EBP] EAX MOV 8B4500
47B626 EBX MUL F7E3
47B628 EAX EBX MOV 8BD8
47B62A 4 # EBP ADD 83C504
47B62D 4081FF ( ALLOT ) CALL E8CDCBF8FF
47B632 40C2CF ( (;CODE) ) CALL E8980CF9FF
47B637 4 # EBP SUB 83ED04 \ entry point
47B63A EBX 0 [EBP] MOV 895D00
47B63D EBX POP 5B
47B63E EBX PUSH 53
47B63F 8 # EBX ADD 83C308
47B642 0 [EBX] EBX MOV 8B1B
47B644 0 [EBP] EAX MOV 8B4500
47B647 EBX MUL F7E3
47B649 EAX EBX MOV 8BD8
47B64B 4 # EBP ADD 83C504
47B64E 0 [EBP] EAX MOV 8B4500
47B651 EBX 0 [EBP] MOV 895D00
47B654 EAX EBX MOV 8BD8
47B656 4 # EBP SUB 83ED04
47B659 EBX 0 [EBP] MOV 895D00
47B65C 0 [ESP] EBX MOV 8B1C24
47B65F 4 # EBX ADD 83C304
47B662 0 [EBX] EBX MOV 8B1B
47B664 0 [EBP] EAX MOV 8B4500
47B667 EBX MUL F7E3
47B669 EAX EBX MOV 8BD8
47B66B 4 # EBP ADD 83C504
47B66E 0 [EBP] EBX ADD 035D00
47B671 4 # EBP ADD 83C504
47B674 0 [EBP] EAX MOV 8B4500
47B677 EBX 0 [EBP] MOV 895D00
47B67A EAX EBX MOV 8BD8
47B67C 4 # EBP SUB 83ED04
47B67F EBX 0 [EBP] MOV 895D00
47B682 0 [ESP] EBX MOV 8B1C24
47B685 0 [EBX] EBX MOV 8B1B
47B687 0 [EBP] EAX MOV 8B4500
47B68A EBX MUL F7E3
47B68C EAX EBX MOV 8BD8
47B68E 4 # EBP ADD 83C504
47B691 0 [EBP] EBX ADD 035D00
47B694 4 # EBP ADD 83C504
47B697 4 # EBP SUB 83ED04
47B69A EBX 0 [EBP] MOV 895D00
47B69D EBX POP 5B
47B69E C # EBX ADD 83C30C
47B6A1 0 [EBP] EBX ADD 035D00
47B6A4 4 # EBP ADD 83C504
47B6A7 RET C3 ok

And here (drumroll...) is mine (with BOUNDS-CHECK? set to FALSE):

2 4 8 16 3array fff ok

see fff
4958BF EBX 7 # SHL C1E307
4958C2 0 [EBP] EAX MOV 8B4500
4958C5 EBX 0 [EBP] MOV 895D00
4958C8 EAX EBX MOV 8BD8
4958CA EBX 5 # SHL C1E305
4958CD 0 [EBP] EBX ADD 035D00
4958D0 4 # EBP ADD 83C504
4958D3 0 [EBP] EAX MOV 8B4500
4958D6 EBX 0 [EBP] MOV 895D00
4958D9 EAX EBX MOV 8BD8
4958DB EBX 4 # SHL C1E304
4958DE 0 [EBP] EBX ADD 035D00
4958E1 4 # EBP ADD 83C504
4958E4 4954A0 # EBX ADD 81C3A0544900
4958EA RET C3 ok

ZB

unread,
Jun 23, 2010, 7:41:42 PM6/23/10
to
Dnia 23.06.2010 Hugh Aguilar <hughag...@yahoo.com> napisał/a:

>> But: "a magnitude slower" indeed?
>

> On SwiftForth, yes --- see the disassembly I provided in novice.txt.
> Also, I got similar results with 3ARRAY. Try this for yourself.
> Compare a disassembly of a SLOW-3ARRAY word to a disassembly of a
> 3ARRAY word. All in the novice package.

But it would be easier to me - as novice - just to make some speed tests,
and compare the results. Could you propose some simple tests? I'm curious
about the results, so I'll try it even on my old C-64.
--
Zbigniew

Hugh Aguilar

unread,
Jun 23, 2010, 7:47:32 PM6/23/10
to
On Jun 23, 5:41 pm, ZB <zbTHIS...@ispid.THIS-NOcom.pl> wrote:
> Dnia 23.06.2010 Hugh Aguilar <hughaguila...@yahoo.com> napisa /a:
>
> >> But: "a magnitude slower" indeed?
>
> > On SwiftForth, yes --- see the disassembly I provided in novice.txt.
> > Also, I got similar results with 3ARRAY. Try this for yourself.
> > Compare a disassembly of a SLOW-3ARRAY word to a disassembly of a
> > 3ARRAY word. All in the novice package.
>
> But it would be easier to me - as novice - just to make some speed tests,
> and compare the results. Could you propose some simple tests? I'm curious
> about the results, so I'll try it even on my old C-64.
> --
> Zbigniew

You've got a C64? I had one of those! I used SuperForth on it, but
that was Forth-83. Is there even an ANS-Forth implementation for the
C64?

My array words optimize multiplication of powers of two into shifts.
That is going to be a big help on the 65c02 that doesn't have hardware
multiply or divide.

As for a speed test, just put an array access in a big loop. Hopefully
the compiler won't optimize it out when it sees that nothing is being
done with the result, but I doubt that will be a problem on any Forth
system that you are using.

Coos Haak

unread,
Jun 23, 2010, 8:01:54 PM6/23/10
to
Op Wed, 23 Jun 2010 13:36:38 -0700 (PDT) schreef Hugh Aguilar:

<snip>


> Poor ZB doesn't know what a hornet's nest he has opened with this
> question! This whole subject has been argued at length already --- we
> just go around and around, and then leave by the same door as in we
> came.
>

There is no hornet's nest, only a nest of little green men that someone has
built. It's a figment of his imagination. No one other has ever seen
evidence or trace of it.


--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Elizabeth D Rather

unread,
Jun 23, 2010, 8:03:37 PM6/23/10
to

A disassembly isn't the same as a speed test, by any means.

ZB

unread,
Jun 23, 2010, 8:07:30 PM6/23/10
to
Dnia 23.06.2010 Hugh Aguilar <hughag...@yahoo.com> napisaďż˝/a:

> You've got a C64?

Yes, actually, I regret now, that I didn't start to learn Forth that 20
years earlier - but perhaps still "better late than never".

Actually, I made at that time (middle 80's) some attempts - but the main
problem was lack (here in Poland) of related literature, like for example
- excellent for novice - "Starting Forth". Nowadays, during the "Internet
era", it is _very_ much easier to find the needed information and docs.

> I had one of those! I used SuperForth on it,

Yes, I've got SuperForth, FIG-Forth, Forth Datatronic and White Lightning.
There are some more implementations available for C-64.

> but that was Forth-83. Is there even an ANS-Forth implementation for the
> C64?

I don't think so; never heard about Forths created for C-64 after 80's.

> My array words optimize multiplication of powers of two into shifts.
> That is going to be a big help on the 65c02 that doesn't have hardware
> multiply or divide.
>
> As for a speed test, just put an array access in a big loop.

OK, I'll try to "compose" such test, then I'll make some comparison on PC,
- then even on C-64 - and we'll see the results.

> Hopefully the compiler won't optimize it out when it sees that nothing
> is being done with the result, but I doubt that will be a problem on any
> Forth system that you are using.

Wait, why "hopefully"? You see such optimization as something wrong?
--
Zbigniew

ZB

unread,
Jun 23, 2010, 8:11:25 PM6/23/10
to
Dnia 24.06.2010 Elizabeth D Rather <era...@forth.com> napisał/a:

> A disassembly isn't the same as a speed test, by any means.

But of course - I would to test the practical side. This is most important
to me, when I'm pondering: "should I really limit the use of CREATE...DOES>,
or the difference is marginal, and not of `a magnitude' "?

Tomorrow I'll make suggested tests (it is 2 A.M. in my location :), and I'll
publish the results.
--
Zbigniew

ZB

unread,
Jun 23, 2010, 8:28:30 PM6/23/10
to
Dnia 23.06.2010 Krishna Myneni <krishna...@ccreweb.org> napisał/a:

> Unless there is any execution speed data to prove otherwise, for a
> wide range of problems, I see no need to shy away from using
> "CREATE ... DOES>". The late Dr. Julian Noble, in Scientific Forth,
> referred to CREATE ... DOES> as the "pearl of Forth".

Actually, I see it as convenient thing - that's why I'm interested, should
it really be used with that much care - and as "encapsulation" made much
earlier, before OO-programming came into "fashion".
--
Zbigniew

ZB

unread,
Jun 23, 2010, 8:35:22 PM6/23/10
to
Dnia 23.06.2010 Hugh Aguilar <hughag...@yahoo.com> napisał/a:

> You've got a C64? I had one of those! I used SuperForth on it, but
> that was Forth-83. Is there even an ANS-Forth implementation for the
> C64?

BTW - for those interested:

http://www.npsnet.com/danf/cbm/languages.html#FORTH
http://www.c64-wiki.com/index.php/Portal:Coding_languages
http://code.google.com/p/durexforth/

As I can see now, for C-64 Blazin' Forth was very appreciated.
--
Zbigniew

Jerry Avins

unread,
Jun 24, 2010, 12:25:31 AM6/24/10
to
On 6/23/2010 8:07 PM, ZB wrote:

If the compiler optimizes the code away, there is nothing left to be timed.

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

Andrew Haley

unread,
Jun 24, 2010, 5:58:31 AM6/24/10
to
Hugh Aguilar <hughag...@yahoo.com> wrote:

> On Jun 23, 4:01?pm, Elizabeth D Rather <erat...@forth.com> wrote:
>> On 6/23/10 11:47 AM, ZB wrote:
>>
>> > Dnia 23.06.2010 Hugh Aguilar<hughaguila...@yahoo.com> ?napisa?/a:
>>
>> >> I say that CREATE DOES> ?is *always* slower than generated colon words.

>>
>> > But: "a magnitude slower" indeed?
>>
>> No. Possibly not slower at all, depending on the implementation. Hugh
>> has produced no evidence to justify this statement, though he has been
>> frequently asked to. No one else shares this opinion. If I were you,
>> I'd ignore it.

> This is such baloney!

It is correct.

> We have covered this before, but here is the SwiftForth (v2)
> disassembly again:
>
> 2 4 8 16 slow-3array sss ok

That only shows that slow-3array may be slow. You wrote slow-3array,
I believe. The slowness isn't in DOES>, but in the way it is being
used.

Andrew.

Krishna Myneni

unread,
Jun 24, 2010, 6:33:10 AM6/24/10
to
On Jun 23, 7:28 pm, ZB <zbTHIS...@ispid.THIS-NOcom.pl> wrote:
> Dnia 23.06.2010 Krishna Myneni <krishna.myn...@ccreweb.org> napisa /a:

>
> > Unless there is any execution speed data to prove otherwise, for a
> > wide range of problems, I see no need to shy away from using
> > "CREATE ... DOES>". The late Dr. Julian Noble, in Scientific Forth,
> > referred to CREATE ... DOES>  as the "pearl of Forth".
>
> Actually, I see it as convenient thing - that's why I'm interested, should
> it really be used with that much care - ...

Well, you have the guidance of several experts here to go by on that
matter. You can also benchmark your own code which uses CREATE ...
DOES> (and I'd encourage you to do so).

> ... and as "encapsulation" made much


> earlier, before OO-programming came into "fashion".
> --

Yes, CREATE ... DOES> provides for encapsulation of data for defining
something closely resembling an object in more recent languages. I
wouldn't necessarily claim that Forth was the first programming
language to provide such a facility, though.


> Zbigniew

Cheers,
Krishna

Hugh Aguilar

unread,
Jun 24, 2010, 4:17:11 PM6/24/10
to
On Jun 24, 3:58 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

There is no CREATE DOES> array definition that compares with either my
3ARRAY etc. words based on multiplication, or my ARY array definition
based on Iliffe Vectors.

Your Iliffe Vector definer based on CREATE DOES> wasn't any good
because it was limited to word elements. When you did upgrade it to
work with variable-sized elements, you lost the ability to obtain
slices out of the middle due to the fact that CREATE DOES> only allows
for one action and your external word [] assumes word-size elements.

This has been covered already:
http://groups.google.com/group/comp.lang.forth/browse_thread/thread/d3f92215bad2b9df/9f89f5fff53e4fb7

We can cover all of this novice-level programming again though! Write
an array definer that isn't limited either by having a fixed-size
element or to not allowing access to slices of the array in the
middle.

It is obvious that Elizabeth Rather isn't going to write an array
definer (because she's a salesperson), but you can be her brave little
champion and show us that same code again that you showed us before. I
think you're just angling for a job at Forth Inc. by championing
E.R.'s nonsense for her, and never mind the fact that it makes you
look like a fool in front of the rest of the world. Good luck with
that plan!

This is like Groundhog Day --- do you remember this exchange from only
a few days ago?

On Jun 17, 12:41 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Jun 17, 3:01 am, Andrew Haley <andre...@littlepinkcloud.invalid>
> wrote:
>
> > > and it has no way of knowing what the size of the element is.
>
> > It has no need to know the size of the element.
>
> Here is a code snippet that shows how my xxx> word is generated:
>
> name c" >"  get-current :2name   \ runtime: adr index -- element-adr
>     siz lit*,  +,  ;,
>
> Notice that it multiplies by SIZ, which is the size of the element!
>
> By comparison, [] is written like this:
>
> macro: [] ( adr index - element-adr )
>     cells + ;
>
> The CELLS effectively multiplies by the cell size (4). This isn't
> going to work if your element size isn't one cell. Duh!
>
> You really aren't making any sense any more, and I'm getting tired of
> rehashing the obvious over and over again.

Jonah Thomas

unread,
Jun 24, 2010, 8:09:29 PM6/24/10
to
Hugh Aguilar wrote:

> There is no CREATE DOES> array definition that compares with either my
> 3ARRAY etc. words based on multiplication, or my ARY array definition
> based on Iliffe Vectors.

I really do not understand why you make this claim.

CREATE DOES> suffers from a slight inefficiency because the address is
dumped on top of the stack each time, when it might not be convenient,
but if you had a colon definition to replace each DOES> child then that
colon definition could bring in the address whenever it was most
convenient instead of at the beginning where it must be juggled until
needed.

But apart from that, you can do anything with CREATE DOES> that you could
do with colon definitions that include calls to CREATEd data structures.
Anything you can do with colon definitions I can do with CREATE DOES>
definitions. The CREATE DOES> structure may be slightly less efficient
but for multiple copies it will be smaller. It won't be drasticly slower.

If you think you have a particular example of code that can't be done
well with CREATE DOES> you could post your example and when I get around
to it I will show you're wrong or else apologize.

Andrew Haley

unread,
Jun 25, 2010, 5:55:06 AM6/25/10
to
Hugh Aguilar <hughag...@yahoo.com> wrote:
> On Jun 24, 3:58?am, Andrew Haley <andre...@littlepinkcloud.invalid>

> wrote:
>> Hugh Aguilar <hughaguila...@yahoo.com> wrote:
>> > On Jun 23, 4:01?pm, Elizabeth D Rather <erat...@forth.com> wrote:
>> >> On 6/23/10 11:47 AM, ZB wrote:
>>
>> >> > Dnia 23.06.2010 Hugh Aguilar<hughaguila...@yahoo.com> napisa?/a:
>>
>> >> >> I say that CREATE DOES> is *always* slower than generated colon words.

>>
>> >> > But: "a magnitude slower" indeed?
>>
>> >> No. Possibly not slower at all, depending on the implementation. Hugh
>> >> has produced no evidence to justify this statement, though he has been
>> >> frequently asked to. No one else shares this opinion. If I were you,
>> >> I'd ignore it.
>> > This is such baloney!
>>
>> It is correct.
>>
>> > We have covered this before, but here is the SwiftForth (v2)
>> > disassembly again:
>>
>> > 2 4 8 16 slow-3array sss ok
>>
>> That only shows that slow-3array may be slow. You wrote slow-3array,
>> I believe. The slowness isn't in DOES>, but in the way it is being
>> used.
>
> There is no CREATE DOES> array definition that compares with either my
> 3ARRAY etc. words based on multiplication, or my ARY array definition
> based on Iliffe Vectors.
>
> Your Iliffe Vector definer based on CREATE DOES> wasn't any good
> because it was limited to word elements.

No it isn't.

> When you did upgrade it to work with variable-sized elements, you
> lost the ability to obtain slices out of the middle

No I didn't.

> due to the fact that CREATE DOES> only allows
> for one action and your external word [] assumes word-size elements.

No it doesn't. This has all been refuted already.

> We can cover all of this novice-level programming again though! Write
> an array definer that isn't limited either by having a fixed-size
> element or to not allowing access to slices of the array in the
> middle.

I already did, and I presented it, and you ignored it.

> It is obvious that Elizabeth Rather isn't going to write an array
> definer (because she's a salesperson), but you can be her brave little
> champion and show us that same code again that you showed us before.

Elizabeth is a Forth programmer, and she's been one for longer than
anyone else here. She's a good one too. You do yourself no good by
attacking individuals.

> I think you're just angling for a job at Forth Inc. by championing
> E.R.'s nonsense for her, and never mind the fact that it makes you
> look like a fool in front of the rest of the world. Good luck with
> that plan!

Ah, no. I am not angling for a job at Forth, Inc.

> This is like Groundhog Day --- do you remember this exchange from only
> a few days ago?
>

> On Jun 17, 12:41?pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
>> On Jun 17, 3:01?am, Andrew Haley <andre...@littlepinkcloud.invalid>


>> wrote:
>>
>> > > and it has no way of knowing what the size of the element is.
>>
>> > It has no need to know the size of the element.
>>
>> Here is a code snippet that shows how my xxx> word is generated:
>>
>> name c" >" get-current :2name \ runtime: adr index -- element-adr
>> siz lit*, +, ;,
>>
>> Notice that it multiplies by SIZ, which is the size of the element!
>>
>> By comparison, [] is written like this:
>>
>> macro: [] ( adr index - element-adr )
>> cells + ;
>>
>> The CELLS effectively multiplies by the cell size (4). This isn't
>> going to work if your element size isn't one cell. Duh!
>>
>> You really aren't making any sense any more, and I'm getting tired of
>> rehashing the obvious over and over again.

I remember that. Did you mistake the lack of a response to this
insulting nonsense for agreement?

Here's a clue: go back and look at the first version of 6array in
<i-qdncVRgqMCa4XR...@supernews.com>

You will see that

a. It allows elemnts of any size
b. [] can access sub-slices.

There's a useful point here: if you make data self-describing it's
possible to write accessor words that are not tied to the shape of any
particular one.

Andrew.

Hugh Aguilar

unread,
Jun 25, 2010, 12:48:31 PM6/25/10
to
On Jun 24, 6:09 pm, Jonah Thomas <jethom...@gmail.com> wrote:
> If you think you have a particular example of code that can't be done
> well with CREATE DOES> you could post your example and when I get around
> to it I will show you're wrong or else apologize.

<ARY> and ARY in the novice package.

Anton Ertl

unread,
Jun 25, 2010, 1:10:43 PM6/25/10
to
ZB <zbTH...@ispid.THIS-NOcom.pl> writes:
>Dnia 23.06.2010 Hugh Aguilar <hughag...@yahoo.com> napisał/a:
>
>> I say that CREATE DOES> is *always* slower than generated colon words.
>
>But: "a magnitude slower" indeed?

Data from a to-be-published paper where I implemented 1+ as follows:

: colon-def 1 + ;

: my-field3 ( n -- )
create ,
does> ( n1 -- n2 )
@ + ;

1 my-field3 does>-def

On gforth-fast, the results are as follows:

colon-def does>-def
29 36 instructions
19.2 10.5 cycles on Core 2 Duo E8400
26.1 29.8 cycles on Athlon 64 X2 4400+

The cycle counts were strongly influenced by mispredictions, and for
some reason the branch predictor of the Core 2 had more problems with
COLON-DEF than with DOES>-DEF (at least in the context of the
micro-benchmark I used).

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2010: http://www.euroforth.org/ef10/

Hugh Aguilar

unread,
Jun 25, 2010, 1:37:15 PM6/25/10
to
On Jun 24, 6:09 pm, Jonah Thomas <jethom...@gmail.com> wrote:
> If you think you have a particular example of code that can't be done
> well with CREATE DOES> you could post your example and when I get around
> to it I will show you're wrong or else apologize.

<ARY> and ARY in the novice package.

Jonah Thomas

unread,
Jun 25, 2010, 1:38:40 PM6/25/10
to

You don't cut-and-paste them, but just mention them? I guess I'll look at
them when I get the chance.

Marcel Hendrix

unread,
Jun 25, 2010, 2:38:53 PM6/25/10
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: new novice package and slide-rule program

> Data from a to-be-published paper where I implemented 1+ as follows:

[ to avoid dups, see below ]

> On gforth-fast, the results are as follows:

> colon-def does>-def
> 29 36 instructions
> 19.2 10.5 cycles on Core 2 Duo E8400
> 26.1 29.8 cycles on Athlon 64 X2 4400+

[..]

-marcel

-- -------------
ANEW -doesdef

: colon-def 1 + ;
: my-field3 ( n -- ) create , does> ( n1 -- n2 ) @ + ;
1 my-field3 does>-def

: BENCH CR ." \ Try: BENCH"
CR ." \ colon-def : " TIMER-RESET 0 #1000000000 0 DO colon-def LOOP DROP .ELAPSED
CR ." \ does>-def : " TIMER-RESET 0 #1000000000 0 DO does>-def LOOP DROP .ELAPSED ;

[1] iForth x64 server 1.03 (console), Mar 26 2010, 19:59:30.
[2] Stuffed iForth at $00FF4410 [entry: $01000000]
[3] Having a Windows terminal.
[4] Console is active.
ok
FORTH> bench ( Intel Core-2 quad 2.66 GHz )
\ Try: BENCH
\ colon-def : 1.833 seconds elapsed.
\ does>-def : 1.818 seconds elapsed. ok

Hugh Aguilar

unread,
Jun 25, 2010, 6:47:36 PM6/25/10
to
On Jun 25, 3:55 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> > Your Iliffe Vector definer based on CREATE DOES> wasn't any good
> > because it was limited to word elements.
>
> No it isn't.

Here is your code:

: ,rows ( 0 n n n size ... - 0 n n n size ...)
here locals| array size dim |
dim cells allot
dim 0 do
here array i [] !
dup if dup >r size recurse r> else size allot then
loop ;

: dimensions ( 0 n n n size ...) ,rows begin 0= until ;

: 6array ( 0 i j k l m n size)
( aligned)
create dimensions
does>
swap cells + @
swap cells + @
swap cells + @
swap cells + @
swap cells + @
swap cells + @ ;

This is still an array of words, but you stuff the last level with
pointers to your elements. If you are defining an array of chars
(size=1), then you have a cell-sized pointer to *every* char in your
array. That is grossly wasteful of memory.

> > When you did upgrade it to work with variable-sized elements, you
> > lost the ability to obtain slices out of the middle
>
> No I didn't.

Here is your code:

: ,rows ( 0 n ... n n size - 0 n ... n n size)
here locals| array size dim |
dup if dim cells else dim size * then allot
dup if
dim 0 do here array i [] ! dup >r size recurse r> loop
then ;

: dimensions ( 0 n ... n n size) ,rows begin 0= until ;

: 6array ( 0 i j k l m n size)
( aligned)
create , dimensions
does>
dup @ >r cell+
swap cells + @
swap cells + @
swap cells + @
swap cells + @
swap cells + @
swap r> * + ;

Now the last level is an array of records, rather than an array of
pointers. Unfortunately, [] no longer works, because it assumes that
the last level is an array of words.

> Elizabeth is a Forth programmer, and she's been one for longer than
> anyone else here.  She's a good one too.  You do yourself no good by
> attacking individuals.

Prove it --- show me an example of *any* Forth code that she has
*ever* written.

Also, she started this whole thing by attacking me. She supported
Passaniti in stating that my symtab program "sucks," and said that she
would never communicate with me again. That was offensive, and totally
uncalled for. I'm not going to forget about that; she made an enemy
out of me when she slammed my symtab program. I'm going to do
everything I can to destroy Forth Inc. --- nobody says that my code
"sucks" and then walks away and forgets about it! When Forth Inc. goes
bankrupt, she will wish that she had never insulted my symtab program.

Now I post this novice package and she recommends that everybody
ignore it. The bottom line here is that she sees ZB as a potential
customer of Forth Inc.. She is hoping that ZB will abandon his C64,
buy a modern computer, and fork over the $500 to Forth Inc. for
SwiftForth. I expect that this is an unlikely scenario, as I doubt
that ZB has $500 burning a hole in his pocket, but every salesperson
can dream! In the meantime, she sees my novice package as blocking
this from happening. She wants ZB to not know how to write an array
definer, and to think that he needs to purchase SwiftForth in order to
have this kind of code written for him by professionals. The irony
here, is that SwiftForth does *not* provide an array definer, and the
"Forth Programmer's Handbook" is also completely silent on the subject
of arrays. Most likely, nobody at Forth Inc. knows how to write an
array definer, and they just hand-code every array individually.

On the subject of hand-coding, your array definer was pretty crude in
that it is specific to six-dimensional arrays. You have to rewrite
that array definer for a five-dimensional, or whatever, array. By
comparison, my <ARY> and ARY definers work for *any* dimension array.
They also provide *both* variable-sized elements (with reasonable
memory usage) and access to slices, which yours don't. My code is
really the best that there is.

John Passaniti

unread,
Jun 26, 2010, 12:25:38 AM6/26/10
to
On Jun 25, 6:47 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> Also, she started this whole thing by attacking me. She
> supported Passaniti in stating that my symtab program
> "sucks," and said that she would never communicate with
> me again.

Wow, you really think that you can rewrite history in a forum where
search engines have indexed everything everyone has written? Banking
on the laziness of people to not validate your claims might work
elsewhere, but it doesn't work here. You might fool a handful of the
newbies here who lack history, but you're not fooling the rest of us.
I did indeed write that your symtab program sucked-- and I *proved* it
with more analysis than you ever put into it. You didn't like me
calling your baby ugly, so you tried to attack me not by refuting what
I wrote, but by calling me a faggot. I personally didn't mind as I
saw it as just an act of distraction on your part, but others who
found your comments offensive told you so, including Elizabeth.

You can try to minimize how your own actions led to everything here.
I find it sad that you don't take personal responsibility for your
words, but hey, integrity doesn't seem to be a core value with you.

> That was offensive, and totally
> uncalled for. I'm not going to forget about that; she made
> an enemy out of me when she slammed my symtab program. I'm
> going to do everything I can to destroy Forth Inc. --- nobody
> says that my code "sucks" and then walks away and forgets
> about it! When Forth Inc. goes bankrupt, she will wish that
> she had never insulted my symtab program.

Weird, as far as I know, I'm the only one who wrote your code sucked.
You would think the awesome and powerful Hugh would be going after me,
but I guess you pretty much figured out that I find you a fucking
joke, so your idle threats don't work on me. Instead, the mighty Hugh
decided to pretend that Elizabeth attacked him and his precious code.
No, but I'm sure that if we all wait a couple weeks, you'll have
extended this fantasy into entirely new and exciting areas. Pathetic.

> Now I post this novice package and she recommends that everybody
> ignore it.

I didn't see that, but it's reasonable she would. Others have, and I
fully agree with them. I see it as completely counter to Forth nature
to favor giving novices a black box instead of bootstrapping them up
so they are empowered. I see some value in your package for advanced
users looking for a technique to speed up arrays with metaprogramming
and to implement a cheesy "lexical OOP" mechanism. But for novices?
No.

Andrew Haley

unread,
Jun 26, 2010, 5:19:53 AM6/26/10
to
Hugh Aguilar <hughag...@yahoo.com> wrote:
> On Jun 25, 3:55?am, Andrew Haley <andre...@littlepinkcloud.invalid>

> wrote:
>> > Your Iliffe Vector definer based on CREATE DOES> wasn't any good
>> > because it was limited to word elements.
>>
>> No it isn't.
>
> Here is your code:
>
> [ 1st def ]

>
> This is still an array of words, but you stuff the last level with
> pointers to your elements.

Exactly right. As I said, a pointer can point to anything.

> If you are defining an array of chars (size=1), then you have a
> cell-sized pointer to *every* char in your array. That is grossly
> wasteful of memory.

If you have an array of chars, you probably wouldn't do it that way.
In fact, you certainly wouldn't do it that way! It still meets the
spec, though.

>> > When you did upgrade it to work with variable-sized elements, you
>> > lost the ability to obtain slices out of the middle
>>
>> No I didn't.
>
> Here is your code:
>

> [ 2nd def ]


>
> Now the last level is an array of records, rather than an array of
> pointers. Unfortunately, [] no longer works, because it assumes that
> the last level is an array of words.

That is the other definition. I pointed you to the first one.

I'm sick of your trying to move the goalposts. The challenge was to
write an array word using DOES> faster than your ARRAY definers, which
I did. You then changed the challenge to an array word with variable
sized elements, which I also did. You now have changed the challenge
again, to include sub-slices at all levels.

>> Elizabeth is a Forth programmer, and she's been one for longer than
>> anyone else here. She's a good one too. You do yourself no good by
>> attacking individuals.
>
> Prove it --- show me an example of *any* Forth code that she has
> *ever* written.

I can't even prove to you that *I* have written any code.

No. Everyone knows, from the history of Forth Inc., what Elizabeth's
role was.

> Also, she started this whole thing by attacking me. She supported
> Passaniti in stating that my symtab program "sucks," and said that she
> would never communicate with me again. That was offensive, and totally
> uncalled for.

Ah, so that is what this is about.

When you post code, you invite criticism. Elizabeth, as the most
experienced Forth educator in the world, is one of the best people to
do it. I too have been on the sharp end of her criticism, and I know
that it hurts.

The difference between you and me is that I accepted the justified
criticism, learned from it, and I think I became a better programmer
as a consequence.

> I'm not going to forget about that; she made an enemy out of me when
> she slammed my symtab program. I'm going to do everything I can to
> destroy Forth Inc. --- nobody says that my code "sucks" and then
> walks away and forgets about it! When Forth Inc. goes bankrupt, she
> will wish that she had never insulted my symtab program.

And you're prepared to lie, if necessary, to achieve that, right?

[ Arguably libellous nonsense deleted ]

> On the subject of hand-coding, your array definer was pretty crude in
> that it is specific to six-dimensional arrays. You have to rewrite
> that array definer for a five-dimensional, or whatever, array.

It could further be generalized, but that wouldn't be a good idea. It
wouldn't be hard to do: clearly it doesn't take a rocket scientist to
figure out how to do swap cells + @ n times in a loop. But the
question is whether it *should* be done.

> By comparison, my <ARY> and ARY definers work for *any* dimension
> array. They also provide *both* variable-sized elements (with
> reasonable memory usage) and access to slices, which yours don't.

You say that as though it's a good thing. I don't doubt that your
array definers have every feature possible, whether the application
needs it or not.

Andrew.

Hugh Aguilar

unread,
Jun 26, 2010, 1:02:38 PM6/26/10
to
On Jun 26, 3:19 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> > If you are defining an array of chars (size=1), then you have a
> > cell-sized pointer to *every* char in your array. That is grossly
> > wasteful of memory.
>
> If you have an array of chars, you probably wouldn't do it that way.
> In fact, you certainly wouldn't do it that way!  It still meets the
> spec, though.

So you're saying that the programmer has to have different defining
words using different algorithms, depending upon the data type? One
algorithm for char arrays, another for word arrays, another for record
arrays, etc..

Wouldn't it be so much simpler for the programmer just to use my array
definer that generates efficient code for any size of element? I'm
assuming that the programmer wants to focus his effort on getting his
application to run, rather than muddle around with the intricacies of
array internals, and he just needs a defining word for arrays that he
can use in any application that he writes.

My own experience has been that arrays are pretty simple and it is
easy to write an array definer that works efficiently for all arrays
in regard to both memory usage and speed, and which provides access to
slices within the array, as well as access to the elements given all
of the indices at once. I think any intermediate-level programmer
would agree with me that arrays are simple to implement. The fact that
you find arrays to be complicated, seems to imply that you are not an
intermediate-level programmer.

> I'm sick of your trying to move the goalposts.  The challenge was to
> write an array word using DOES> faster than your ARRAY definers, which
> I did.  You then changed the challenge to an array word with variable
> sized elements, which I also did.  You now have changed the challenge
> again, to include sub-slices at all levels.

You're DOES> word isn't faster than mine. Not only is it a huge waste
of memory to have an extra level of pointers, but it is also slower
because you have an extra level of pointers that your code has to work
its way through. Also, I was never convinced that these Iliffe Vector
arrays are any faster than my original multiplication-based algorithm,
despite their heavy use of memory. This is only assuming that
multiplication is slower than memory access, which isn't necessarily
true anymore.

You were the one who introduced the idea of providing access to slices
of the array, which my original multiplication-based algorithm didn't
do. That was the whole point of using Iliffe Vectors rather than
multiplication. Then, your algorithm failed to provide access to
slices! I'm not moving the goalposts, you're setting up your own
goalposts and then failing to put the ball through them. If you don't
know how to write an array definer that does this, then why did you
bring up the topic in the first place?

> >> Elizabeth is a Forth programmer, and she's been one for longer than
> >> anyone else here.  She's a good one too.  

> ...


> When you post code, you invite criticism.  Elizabeth, as the most
> experienced Forth educator in the world, is one of the best people to
> do it.  I too have been on the sharp end of her criticism, and I know
> that it hurts.

That was a smooth mid-stream change of terminology --- from "Forth
programmer" to "Forth educator." Pretty soon you will get to the
truth, which is: "Forth Inc. salesperson."

> The difference between you and me is that I accepted the justified
> criticism, learned from it, and I think I became a better programmer
> as a consequence.

The "sharp end of her criticism" is being told that my program
"sucks." That isn't exactly a positive contribution that is going to
make me a better programmer. That is just vulgar and mean.

> > I'm not going to forget about that; she made an enemy out of me when
> > she slammed my symtab program. I'm going to do everything I can to
> > destroy Forth Inc. --- nobody says that my code "sucks" and then
> > walks away and forgets about it! When Forth Inc. goes bankrupt, she
> > will wish that she had never insulted my symtab program.
>
> And you're prepared to lie, if necessary, to achieve that, right?

I'm not lying. Read the whole thing yourself:

http://groups.google.com/group/comp.lang.forth/browse_thread/thread/c37b473ec4da66f1

> It could further be generalized, but that wouldn't be a good idea.  It
> wouldn't be hard to do: clearly it doesn't take a rocket scientist to
> figure out how to do  swap cells + @  n times in a loop.  But the
> question is whether it *should* be done.

You're talking about a loop that executes at *run-time.* It doesn't
take a rocket scientist to figure out that this is going to be
abysmally slow. By comparison, my definer executes its loop at compile-
time and generates unwound inline code that executes at run-time.

John Passaniti

unread,
Jun 26, 2010, 3:06:37 PM6/26/10
to
On Jun 26, 1:02 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> I'm not lying. Read the whole thing yourself:
>
> http://www.google.com/url?sa=D&q=http://groups.google.com/group/comp.lang.forth/browse_thread/thread/c37b473ec4da66f1&usg=AFQjCNGC2kkoSVLgI_2FMjJ7IUYA1vL5-Q

Your claim that Elizabeth stated symtab sucked is now officially
disproved-- with your own reference! Elizabeth wrote *one* message in
the thread you cited, and she says *nothing* about the quality of your
code. She only commented on your words and your behavior-- just like
others did, and continue to do. To my knowledge, although others did
comment on symtab's various weaknesses, I am the only one who summed
it up by saying it sucked. And specifically, it sucked for the
intended purpose-- as a symbol table. It may have other applications
where it doesn't suck.

I don't understand why you would lie about what Elizabeth wrote, but
hey, you've shown a variety of character defects and this is just
another to add to the list. But lying *and* providing a reference
that proves you're lying? Man, that's taking it to a whole new
level.

Andrew Haley

unread,
Jun 27, 2010, 9:47:18 AM6/27/10
to
Hugh Aguilar <hughag...@yahoo.com> wrote:
> On Jun 26, 3:19?am, Andrew Haley <andre...@littlepinkcloud.invalid>

> wrote:
>> > If you are defining an array of chars (size=1), then you have a
>> > cell-sized pointer to *every* char in your array. That is grossly
>> > wasteful of memory.
>>
>> If you have an array of chars, you probably wouldn't do it that way.
>> In fact, you certainly wouldn't do it that way! It still meets the
>> spec, though.
>
> So you're saying that the programmer has to have different defining
> words using different algorithms, depending upon the data type? One
> algorithm for char arrays, another for word arrays, another for record
> arrays, etc..

That's right. Arrays of many different kinds are super-easy to write
in Forth, so you can just define what you need.

> Wouldn't it be so much simpler for the programmer just to use my
> array definer that generates efficient code for any size of element?

I don't think so, because you'd end up with a general-purpose set of
array words that aren't ideal for any application. "One size fits
all" is not the Forth way to do it.

> My own experience has been that arrays are pretty simple and it is
> easy to write an array definer that works efficiently for all arrays
> in regard to both memory usage and speed, and which provides access
> to slices within the array, as well as access to the elements given
> all of the indices at once. I think any intermediate-level
> programmer would agree with me that arrays are simple to
> implement. The fact that you find arrays to be complicated, seems to
> imply that you are not an intermediate-level programmer.

I completely reject this notion of "novice", "intermediate",
"advanced", and so on. The real question is "What does this
*application* require?"

>> I'm sick of your trying to move the goalposts. ?The challenge was to


>> write an array word using DOES> faster than your ARRAY definers, which
>> I did. You then changed the challenge to an array word with variable
>> sized elements, which I also did. You now have changed the challenge
>> again, to include sub-slices at all levels.
>
> You're DOES> word isn't faster than mine.

It was when I measured it.

> You were the one who introduced the idea of providing access to
> slices of the array, which my original multiplication-based
> algorithm didn't do.

Indeed, that's something that is often needed.

> That was the whole point of using Iliffe Vectors rather than
> multiplication.

No it wasn't.

Let's try to remember how this started. Your claim was

> My arrays are at least twice as fast as any array written using
> CREATE DOES>, using any compiler.

and I replied

> And, on my system at least, its speed is slightly faster the 6array in
> novice.4th with bounds checking disabled.

>> >> Elizabeth is a Forth programmer, and she's been one for longer than
>> >> anyone else here. She's a good one too.
>> ...
>> When you post code, you invite criticism. Elizabeth, as the most
>> experienced Forth educator in the world, is one of the best people to
>> do it. I too have been on the sharp end of her criticism, and I know
>> that it hurts.
>
> That was a smooth mid-stream change of terminology --- from "Forth
> programmer" to "Forth educator."

She's both. It is possible, you know.

> Pretty soon you will get to the truth, which is: "Forth
> Inc. salesperson."
>
>> The difference between you and me is that I accepted the justified
>> criticism, learned from it, and I think I became a better programmer
>> as a consequence.
>
> The "sharp end of her criticism" is being told that my program
> "sucks." That isn't exactly a positive contribution that is going to
> make me a better programmer. That is just vulgar and mean.

I thought that was someone else.

>> > I'm not going to forget about that; she made an enemy out of me when
>> > she slammed my symtab program. I'm going to do everything I can to
>> > destroy Forth Inc. --- nobody says that my code "sucks" and then
>> > walks away and forgets about it! When Forth Inc. goes bankrupt, she
>> > will wish that she had never insulted my symtab program.
>>
>> And you're prepared to lie, if necessary, to achieve that, right?
>
> I'm not lying. Read the whole thing yourself:
>
> http://groups.google.com/group/comp.lang.forth/browse_thread/thread/c37b473ec4da66f1

I have, and I can't see what you're objecting to.

>> It could further be generalized, but that wouldn't be a good idea. It
>> wouldn't be hard to do: clearly it doesn't take a rocket scientist to
>> figure out how to do swap cells + @ n times in a loop. But the
>> question is whether it *should* be done.
>
> You're talking about a loop that executes at *run-time.*

Yes.

> It doesn't take a rocket scientist to figure out that this is going
> to be abysmally slow.

So, let's not write an "any number of dimensions" array definer, then.
It would be a pretty extraordinary application that actually needed
such a thing.

Andrew.

Jerry Avins

unread,
Jun 27, 2010, 3:29:56 PM6/27/10
to
On 6/27/2010 9:47 AM, Andrew Haley wrote:
> Hugh Aguilar<hughag...@yahoo.com> wrote:
>> On Jun 26, 3:19?am, Andrew Haley<andre...@littlepinkcloud.invalid>
>> wrote:
>>>> If you are defining an array of chars (size=1), then you have a
>>>> cell-sized pointer to *every* char in your array. That is grossly
>>>> wasteful of memory.
>>>
>>> If you have an array of chars, you probably wouldn't do it that way.
>>> In fact, you certainly wouldn't do it that way! It still meets the
>>> spec, though.
>>
>> So you're saying that the programmer has to have different defining
>> words using different algorithms, depending upon the data type? One
>> algorithm for char arrays, another for word arrays, another for record
>> arrays, etc..
>
> That's right. Arrays of many different kinds are super-easy to write
> in Forth, so you can just define what you need.
>
>> Wouldn't it be so much simpler for the programmer just to use my
>> array definer that generates efficient code for any size of element?
>
> I don't think so, because you'd end up with a general-purpose set of
> array words that aren't ideal for any application. "One size fits
> all" is not the Forth way to do it.

To be consistent, Hugh should agitate for overloaded + , @ , ! - , / ,
and * . It would be easy easy if Forth were typed. Maybe we should ass
CAST words, too.

Alex McDonald

unread,
Jun 27, 2010, 11:03:13 PM6/27/10
to
On 27 June, 12:29, Jerry Avins <j...@ieee.org> wrote:
> On 6/27/2010 9:47 AM, Andrew Haley wrote:
>
>
>
> > Hugh Aguilar<hughaguila...@yahoo.com>  wrote:

Perhaps StrongForth might be of interest in that case;
http://home.vrweb.de/~stephan.becher/ and a cclf discussion here
http://groups.google.com/group/comp.lang.forth/browse_frm/thread/4252a1f1281b0c78/52d398327a344617

Hugh Aguilar

unread,
Jun 28, 2010, 3:06:36 PM6/28/10
to
On Jun 27, 7:47 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> > The "sharp end of her criticism" is being told that my program
> > "sucks." That isn't exactly a positive contribution that is going to
> > make me a better programmer. That is just vulgar and mean.
>
> I thought that was someone else.

I see the situation here as being very similar to the situation that
commonly arises in prison. Often there will be a faggot who makes a
practice of annoying everybody. He endlessly gets in people's faces,
criticizes them, uses vulgar scatological language, and generally
makes a nuisance of himself. The reason why he does this is because he
has a patron to do his fighting for him. In this situation, if you
want to make the annoyance stop --- you fight the patron, not the
faggot.

When Elizabeth Rather defended John Passaniti, she established herself
as his patron (actually matron because she's a woman, but the concept
is the same either way). Elizabeth Rather has committed herself to
being Passaniti's defender. Now when Passaniti flings words like
"suck" and "fuck," that is the same as if Elizabeth Rather said all of
that herself --- Passaniti is E.R.'s stooge. He is making a nuisance
of himself because he knows that E.R. will *always* defend him. My
complaint at the time was that Passaniti belonged to a community that
had no place in decent society. E.R. essentially stated that she not
only belongs to this community herself, but she is the queen of this
community, and she is willing to personally defend everything that
this community does. Elizabeth Rather is the problem. Passaniti is
just doing what his nature requires. Elizabeth Rather has taken
responsibility for all of this though. If she were removed from
c.l.f., Passaniti would just fade away --- he would go find some other
group of people to annoy, and he would find somebody in that group to
be his patron --- he would become somebody else's problem.

Jerry Avins

unread,
Jun 28, 2010, 3:27:17 PM6/28/10
to

I usually don't deign to dispute with you, but I need to point out that
you are not only a vulgar bigot, you are laughably wrong. John and
Elizabeth frequently disagree, but they do it civilly, so of course you
wouldn't notice.

How do you know so much about conditions in a typical jail?

Jerry
--

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Hugh Aguilar

unread,
Jun 28, 2010, 4:09:00 PM6/28/10
to
On Jun 27, 9:03 pm, Alex McDonald <b...@rivadpm.com> wrote:
> On 27 June, 12:29, Jerry Avins <j...@ieee.org> wrote:
> > > That's right.  Arrays of many different kinds are super-easy to write
> > > in Forth, so you can just define what you need.
>
> > >> Wouldn't it be so much simpler for the programmer just to use my
> > >> array definer that generates efficient code for any size of element?
>
> > > I don't think so, because you'd end up with a general-purpose set of
> > > array words that aren't ideal for any application.  "One size fits
> > > all" is not the Forth way to do it.

It seems reasonable to me that I should write an array definer that
works for any array, and provides both user-specified record sizes and
access to slices within the array. I think that Forth programmers
spend way too much time dinking around with low-level code such as
array definers, and not enough time writing applications. That is
pretty much the point of my novice package --- to provide people with
infrastructure code such as arrays, records, lists, and so forth, so
they can actually write some applications. Also, I don't know of any
application in which my array definer is sub-optimal. Arrays aren't
very complicated --- it is not difficult to make an array definer that
pretty much nails the subject. All of this talk about hand-optimizing
code for the application would make a lot more sense if we were
talking about somewhat higher level code than arrays, records, lists,
and so forth.

> > To be consistent, Hugh should agitate for overloaded + , @ , ! - , / ,
> > and * . It would be easy easy if Forth were typed. Maybe we should ass
> > CAST words, too.

You're putting words in my mouth. Writing an OOP package is somewhat
beyond the scope of this thread --- all I did was write a couple of
array definers.

And btw Jerry, what is up with your use of the word "ass?" Are you
trying to become another one of Elizabeth Rather's pets, joining
Passaniti in this less-than-illustrious community?

> Perhaps StrongForth might be of interest in that case;http://home.vrweb.de/~stephan.becher/

I'll look into this StrongForth. I'm always interested in learning new
things from people who write code. I learned about Illife Vectors from
Andrew Haley, after all. My own implementation was superior to his,
but that is just the way that it goes.

Marc Olschok

unread,
Jun 28, 2010, 4:34:48 PM6/28/10
to
[sorry for the OT. But he starts top be a nuisance]

Hugh Aguilar <hughag...@yahoo.com> wrote:
>[...]

> When Elizabeth Rather defended John Passaniti, she established herself
> as his patron (actually matron because she's a woman, but the concept
> is the same either way). Elizabeth Rather has committed herself to
> being Passaniti's defender. Now when Passaniti flings words like
> "suck" and "fuck," that is the same as if Elizabeth Rather said all of
> that herself --- Passaniti is E.R.'s stooge. He is making a nuisance
> of himself because he knows that E.R. will *always* defend him. My
> complaint at the time was that Passaniti belonged to a community that
> had no place in decent society.

Man, why don't you just crawl back into the swamp you came from.

> E.R. essentially stated that she not
> only belongs to this community herself, but she is the queen of this
> community, and she is willing to personally defend everything that
> this community does.

She just took offence with your stupid attempt to use homophobic
attitudes against him; quite rightly so in my opinion.
Your attempt obviously backfired anyway.
Unless you just had your spelling wrong <http://de.wikipedia.org/wiki/Fagott>.

> Elizabeth Rather is the problem. Passaniti is
> just doing what his nature requires. Elizabeth Rather has taken
> responsibility for all of this though. If she were removed from
> c.l.f., Passaniti would just fade away --- he would go find some other
> group of people to annoy, and he would find somebody in that group to
> be his patron --- he would become somebody else's problem.

If I have to choose someone to annoy this group, I prefer John.
At least he does it in an intelligent way most of the time.
You are not only wrong, but also boring.

--
M.O.

Jerry Avins

unread,
Jun 28, 2010, 4:43:24 PM6/28/10
to
On 6/28/2010 4:09 PM, Hugh Aguilar wrote:

...

> And btw Jerry, what is up with your use of the word "ass?" Are you
> trying to become another one of Elizabeth Rather's pets, joining
> Passaniti in this less-than-illustrious community?

A typo that passed the spell checker. It should have been "add".

...

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Hugh Aguilar

unread,
Jun 28, 2010, 5:37:52 PM6/28/10
to

Here is the code of <ARY> and ARY. Note that you need the novice
package loaded to compile this, because there is a lot of
infrastructure code (such as :NAME, {, and LIT*,) in the novice
package that is used by <ARY> and ARY. Given this infrastructure code,
it is actually pretty easy to write definers such as <ARY> and ARY. I
have spent a lot more time defending/explaining this code than I did
to write it. Given good infrastructure code, everything becomes easy.

Note that I have removed most of the comments here to prevent word-
wrap from making a mess of the listing:

macro: [] ( adr index - element-adr )
cells + ;

macro: -> ( adr index -- element )
[] @ ;

: ,rows ( size 0 dims... -- size 0 dims... )
here locals| array dim |
dup if w else over then \ -- element-size
dim * zallot
dup if
dim 0 do here array I [] ! dup >r recurse r> loop
then ;

: dimensions ( size 0 dims... size )
,rows
begin 0= until ;

: <ary> ( size 0 dims... name -- )
>r
non-zeros >r r@ 0 = abort" *** ARY needs some dimensions ***"
align here >r dimensions >r
r> r> r> r> { siz adr cnt name -- }
name get-current :name \ runtime: indices... -- element-adr
adr lit,
cnt 1 ?do swap, postpone -> loop
swap, siz lit*, +, ;,
c" <" name get-current :2name \ runtime: -- base-adr
adr lit, ;,


name c" >" get-current :2name \ runtime: adr index -- element-
adr
siz lit*, +, ;,

;

: ary ( size 0 dims... -- )
bl word hstr dup >r <ary> r> dealloc ;

Message has been deleted

Alex McDonald

unread,
Jun 29, 2010, 6:39:37 AM6/29/10
to

Criticism can be painful, especially if it's robustly made, but that
doesn't excuse this execrable piece of bigoted bilge.

This is not the place you think it is. This is the place on the
internet where Forth is discussed. There are people here -- real
people, not just pixels on a monitor -- that have met and know each
other well. Others have never met except here. All robustly exchange
ideas and largely agree to disagree, and do so without resorting to
unpleasantness. Yes, arguments get heated and there's a raised voice
or two. It doesn't last long; no-one keeps track of points scored or
arguments won and lost.

But the overwhelming majority here do not answer criticism by
questioning someone's race, creed, background or sexuality. Leave your
prejudices at the door when you enter here, because this is a place
for discussing Forth. There are plenty of other dark places on the
internet where you can pleasure yourself posting homophobic rants.

Alex McDonald

unread,
Jun 29, 2010, 9:55:20 AM6/29/10
to

On my Intel Core 2 Duo T9600 (2.80GHz, 1066MHz FSB, 6MB Cache) laptop.

The STC version of Win32Forth (some optimisations, COLON-DEF inlines);

\ Try: BENCH
\ colon-def : Elapsed time: 00:00:02.453
\ does>-def : Elapsed time: 00:00:03.672 ok

ITC Win32Forth version 6.14;

\ Try: BENCH
\ colon-def : Elapsed time: 00:00:10.750
\ does>-def : Elapsed time: 00:00:09.375 ok

The answer seems to be; "it depends".

rickman

unread,
Jun 29, 2010, 12:29:59 PM6/29/10
to

What is going on in this group? I have seen a lot of acrimonious
exchanges from some of the more odd personalities here, but this is
one of the worse! Hugh, you are going off the deep end! It is very
seldom that anyone finds anything negative to say about Elizabeth
Rather and I can't remember the last time I read a personal attack on
her like this.

What is going on in your head, dude? Take a look at yourself and
figure out why you are responding like this.

Rick

Hugh Aguilar

unread,
Jun 29, 2010, 4:10:31 PM6/29/10
to

Forth has been a huge failure. I remember back in the 1980s that Forth
was a serious contender against C. Now Forth is considered to be a
joke. I have put a big investment into learning Forth and I have
worked as a professional Forth programmer, but now I can't
realistically mention any of this on a resume. I found that mentioning
work experience as a Forth programmer was considered to be a negative
rather than a positive. The whole business of being a Forth programmer
has been a big disaster. I don't think this is because I'm an
incompetent programmer who is incapable of even understanding basic
concepts such as records, arrays and lists. My own software is
something that I take pride in.

I blame Forth Inc. for giving Forth a bad reputation. Forth Inc.
literally owns the name "Forth" and, in most people's minds, Forth
Inc. represents the best of Forth. The general assumption is that
Forth Inc. is *professional* Forth programming. This is all just
marketing though. Elizabeth Rather is not a computer programmer. Forth
Inc. is a purely sales-driven company with a bad reputation for
delivering garbage software.

I really believe that E.R. is purposely trying to drag the Forth
community down. I think it is likely that she is paying Passaniti to
turn c.l.f. into cesspit. From her point of view, there are only two
kinds of Forth programmers: those who work for Forth Inc. and those
who compete against Forth Inc.. Everybody on c.l.f. is in the latter
category. She wants everybody on c.l.f. to be saying that each other's
code "sucks" and that we consider each other "to be a fucking joke"
--- because this makes Forth Inc. look like a bastion of
professionalism by comparison. For her, it is all about image --- the
idea of writing quality software is unknown at Forth Inc. --- the
company is selling the sizzle and not the steak.

When I mention Forth in a job interview, the people just nod and say:
"We tried SwiftForth and we weren't impressed. There is almost no code
optimization being done. There are no facilities for basic data
structures such as records, arrays and lists. It is roughly comparable
to Qbasic. We don't think that this background qualifies you to work
as a C programmer; you wouldn't understand any of what we do around
here."

All this talk about how Elizabeth Rather is a "Forth educator" is an
insult to people who actually program in Forth. Take a look at the
following SwiftForth code. This is one of the more egregious examples
of horrible Forth programming because we have a function here that
returns its result on the return stack rather than the parameter
stack. All of SwiftForth is full of bad code though. It is not
factored properly, there is widespread use of magic numbers, it pretty
much violates Forth philosophy in *every* way. It blows my mind that
E.R. would make so much source-code available when it is so bad.
Apparently she is not even aware of how incompetent this makes her
look. She spends a lot of time bragging about that parcel-tracking
program that Forth Inc. did for FedEx. That is not even real-time
code. Like most programmers, I've worked with those wands that swipe
bar-codes --- they just deliver the number in ascii on an RS-232 line
--- this is not the kind of thing that real programmers brag about.
This is software that could have just as well been written in Basic.

Anyway, here is some code from SwiftForth, the flagship software of
Forth Inc.. I have removed the comments to prevent word-wrap from
messing up the listing. The words that you don't recognize are
available using LOCATE.

LABEL R-GO-ON2
EDX PUSH
EAX JMP
END-CODE

CODE R-BUF ( -- )
EAX POP
ESP ECX MOV
MAX_PATH # ESP SUB
ESP EDX MOV
ECX PUSH
R-GO-ON2 CALL
ECX POP
ECX ESP MOV
RET END-CODE

: WID-HEADER ( c-addr u wid -- )
OVER 0= -16 ?THROW ?UNIQUE
-ROT 254 MIN R-BUF R@ PLACE
HERE 13 + R@ C@ + 15 AND 16 SWAP - ALLOT
LOCATION , R@ COUNT ROT LINKED
$FF C, 0 C,
R> COUNT EMPLACE
HERE 1+ HERE LAST CELL+ 2! 0 C, ;

Paul Rubin

unread,
Jun 29, 2010, 8:29:33 PM6/29/10
to
Hugh Aguilar <hughag...@yahoo.com> writes:
> Forth has been a huge failure. I remember back in the 1980s that Forth
> was a serious contender against C. Now Forth is considered to be a
> joke. I have put a big investment into learning Forth and I have
> worked as a professional Forth programmer, but now I can't
> realistically mention any of this on a resume. I found that mentioning
> work experience as a Forth programmer was considered to be a negative
> rather than a positive.

Hugh, I don't think mentioning Forth is a negative, if it's part of a
well-rounded collection of skills. But, IMHO, Forth is pretty low-tech
by today's standards. That's not the fault of anybody's mis-management
of it or anything like that. It's just that Forth was designed in the
1960's to solve problems of that era that don't exist any more, except
in some rare situations. If those are the applications you're working
in, then being a Forth expert is great. In the wider field of
programming, having some Forth experience in your bag of tools is a
positive. But if you have a Forth-centric view of programming where you
think Forth is the right approach to every problem, it can make you come
across like a dinosaur. You could probably widen your capabilities by
quite a bit by switching to other languages for a while.

Hugh Aguilar

unread,
Jun 29, 2010, 9:20:51 PM6/29/10
to
On Jun 29, 6:29 pm, Paul Rubin <no.em...@nospam.invalid> wrote:

> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> Hugh, I don't think mentioning Forth is a negative, if it's part of a
> well-rounded collection of skills.  But, IMHO, Forth is pretty low-tech
> by today's standards.  

The same was true of C in the 1980s, and C is still a viable skill
today, and not just used for low-level work such as device drivers.
Lots of applications are still written in C despite its lack of OOP,
and there is always C++ or Objective C for applications that require
OOP. This could have been Forth (and Forth++ and Objective Forth). C
really wasn't that tough of a competitor to beat; it is a pretty
horrible language. The fact that C became the standard really says a
lot about the lack of effort from the Forth community. It is like
having a wide-open goal in soccer, and missing. Arg!

> It's just that Forth was designed in the
> 1960's to solve problems of that era that don't exist any more, except
> in some rare situations.  

I don't think this is true. Forth was always strong at providing
interactive development (interpretive mode) and encouraging bottom-up
programming with a heavy emphasis on testing each function immediately
after it was written so that the program *always* works, but it
evolves from simple to complex. Does this sound familiar? That is
pretty much what Agile development is all about. All of the popular
modern languages are embracing this style of programming and C/C++ is
finally (hooray!) getting phased out --- but not by Forth, which could
have done the same thing a quarter of a century ago. Also, the modern
languages that embrace this style of programming are all inferior to
Forth in regard to efficiency. As an example, Slava told me that the
smallest processor he could foresee implementing Factor on was the
ColdFire. Meanwhile, Forth runs fine on 8-bit and 16-bit processors.
There is still no better choice than Forth for micro-controller
development --- but everybody uses GCC and they don't even consider
Forth.

> You could probably widen your capabilities by
> quite a bit by switching to other languages for a while.

It would certainly benefit my mental health. This business of trying
to introduce records, arrays and lists --- and getting criticized for
it --- is seriously getting on my nerves. I went into a horrible slump
in Go and nearly got demoted because I lost a lot of games that I
should have won, and that was all stress that caused that. It is the
year 2010 after all --- my efforts to save Forth are a little bit late
--- I should just give up.

There are a lot of interesting languages in use nowadays that I could
delve into; it is not like the 1980s when the choices were Forth or C
or (worse) Pascal --- and most of the serious work was done in 65c02
or Z80 assembly anyway, so language design wasn't even an important
issue.

Paul Rubin

unread,
Jun 29, 2010, 10:39:41 PM6/29/10
to
Hugh Aguilar <hughag...@yahoo.com> writes:
> The same was true of C in the 1980s, and C is still a viable skill
> today, and not just used for low-level work such as device drivers.

It's sort of the same situation as Forth; C is a useful tool but
a programmer who uses it for everything has a limited perspective.

> C really wasn't that tough of a competitor to beat; it is a pretty
> horrible language. The fact that C became the standard really says a
> lot about the lack of effort from the Forth community.

It seems to me (based on very limited exposure to Forth, I admit) that C
maps more closely to machine operations than Forth does. Writing a
large-platform program completely in C these days would generally be a
poor idea in my opinion.

I don't have much exposure to Forth so maybe I'm wrong about this, but
it seems to me that Forth's big virtue was being able to run a complete
development environment (compiler and interpreter) on a small embedded
target computer. In the 1970's and 1980's when computers were
expensive, that mattered a lot. These days, cross-development is a lot
easier, you can simulate most embedded targets on a laptop, and so
forth. So there's not much need to poke at code directly on the target
without any intermediate tools (like a cross-debugger) running on a
bigger host. So a lot of Forth's previous advantage is negated.

Then looking at the target platform itself, we can arbitrarily divide
them into about 3 classes, depending on amount of ram available (which
also usually corresponds with code space):

1. Very tiny targets (small PIC or Atmel), up to a few hundred bytes of
ram. I think Forth can't really run usefully on these, so they have to
be programmed in C or assembler. The Forth dictionary and the need for
two stacks burns too much space, etc.

2. Smallish targets, let's say 1k up to 32k or so: Forth can be useful
here, and knowing it might be helpful for rapid prototyping, but C has
more creature comforts, and again, once you have a cross-debugger and
simulator, Forth doesn't seem to gain you that much.

3. Larger targets that can handle garbage collected languages. Most
mobile phones these days are programmed in Java, a clumsy language in my
opinion, but much less error-prone than C or Forth because of its
pointer safety and automatic storage management. The benefit of Java is
not OO (which is nowhere near as important as it's sometimes cracked up
to be) but in runtime safety (no malloc/free errors and no uncaught
stray pointers) compared with C.

> I don't think this is true. Forth was always strong at providing

> interactive development ... Does this sound familiar? That is


> pretty much what Agile development is all about.

Not really, because that style of development generally relies on making
it easy to find and fix problems, through pointer and datatype safety,
and runtime support for quickly identifying the exact line of code and
call chain where your program crashed. Forth is untyped (C is almost as
bad) so it's much easier for programs to clobber memory than in Java or
Lisp or whatever. I've actually been interested in Ada as an
alternative to C for very small targets because of its greater safety,
but I haven't tried it yet, so I can't say from personal experience
whether that's a good idea or not.

>> by switching to other languages for a while.

> There are a lot of interesting languages in use nowadays that I could


> delve into; it is not like the 1980s when the choices were Forth or C
> or (worse) Pascal ---

You mentioned being interested in Scheme a while back. That will give a
really different perspective from Forth, I think. You might also like
Lua, which is designed for midsized embedded targets. I think its
runtime is around 50k of code. That's a comparable footprint to J2ME,
so I think it's become popular among mobile phone programmers who don't
like Java.

More to the point though, it's becoming more and more necessary to be
clueful about a larger software ecosystem involving components like
databases, network services, etc, rather than expecting to work entirely
inside systems small enough to have been completely developed by one or
two people. I looked at some of your discussions with John Passaniti
(sp?) where the two of you get in disagreements, but it seems to me that
for the most part (from the little I've seen) that he is very sensible.

ron

unread,
Jun 29, 2010, 11:46:34 PM6/29/10
to
On Jun 29, 11:10 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:

> Forth has been a huge failure.

Why, because it isn't used everywhere? Do you think one tool is right
for every job???

> Now Forth is considered to be a joke.

Em, no it is not.

> I have put a big investment into learning Forth and I have worked as a
> professional Forth programmer, but now I can't realistically mention any of
> this on a resume.

Ah, and here's the meat!

> I found that mentioning work experience as a Forth programmer was considered
> to be a negative rather than a positive.

And I've found quite the opposite; even though I have never been
*paid* to do Forth work, my employers have always been interested in
my Forth experience. At the least it has been a conversation starter
with them, and put me "one up" on the competition in their minds, in
terms of hard-core knowledge. Curious you've not had that
experience. But if you exhibit the same hubris when interviewing that
you do here in the newsgroup, it is not at all surprising.

> My own software is something that I take pride in.

The word you are looking for is, indeed, "hubris".

> We don't think that this background qualifies you to work as a C programmer;
> you wouldn't understand any of what we do around here."

And did you think that maybe acquiring C programming skill would be
germane to a C programming job? Why would anyone hire you to program
in C if you are not at least comfortable in that language?


Remainder of diatribe snipped to save electrons...

Andrew Haley

unread,
Jun 30, 2010, 6:15:53 AM6/30/10
to
Paul Rubin <no.e...@nospam.invalid> wrote:

> Then looking at the target platform itself, we can arbitrarily divide
> them into about 3 classes, depending on amount of ram available (which
> also usually corresponds with code space):
>
> 1. Very tiny targets (small PIC or Atmel), up to a few hundred bytes of
> ram. I think Forth can't really run usefully on these, so they have to
> be programmed in C or assembler. The Forth dictionary and the need for
> two stacks burns too much space, etc.

With all due respect, you're out of your depth here. Since chipFORTH
some 20+ years ago (and maybe before then; I don't know) it has been
possible to do full interactive development on very small targets.
This is done by using a powerful host computer to store dictionary
headers, do command-line interaction, and so on.

The need for two stacks is a red herring, since all that does is
separate control information from parameters: it doesn't take any more
space than a unified stack.

> 2. Smallish targets, let's say 1k up to 32k or so: Forth can be useful
> here, and knowing it might be helpful for rapid prototyping, but C has
> more creature comforts, and again, once you have a cross-debugger and
> simulator, Forth doesn't seem to gain you that much.

This is more a matter of taste, I think. As long as you're prepared
to use a ton of complex tools such as linkers, make, compilers,
assemblers, and so on, they you can do it that way. I'm not at all
sure these are "creature comforts", though: I have to question whether
they're part of the problem or part of the solution.

Andrew.

rickman

unread,
Jun 30, 2010, 8:32:01 AM6/30/10
to
On Jun 29, 4:10 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Jun 29, 10:29 am, rickman <gnu...@gmail.com> wrote:
>
> > What is going on in your head, dude?  Take a look at yourself and
> > figure out why you are responding like this.
>
> > Rick
>
>
> I blame Forth Inc. for giving Forth a bad reputation. Forth Inc.
> literally owns the name "Forth" and, in most people's minds, Forth
> Inc. represents the best of Forth.


You blame Forth Inc for how your career has gone... Just give that
some thought and compare that to clinical definitions of paranoid.

I'm not going to debate this with you. I'm just going to suggest that
you put the bomb making materials away and find another way to express
yourself.

Rick

Fanzo

unread,
Jun 30, 2010, 1:36:12 PM6/30/10
to

IMHO maybe forth has been designed in the 60's but the idea, elegance,
power are still there.
What C has more than forth is wide spread use i think. For sure no
bigger power

-- Cristiano

Paul Rubin

unread,
Jun 30, 2010, 3:07:02 PM6/30/10
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
> With all due respect, you're out of your depth here. Since chipFORTH
> some 20+ years ago (and maybe before then; I don't know) it has been
> possible to do full interactive development on very small targets.
> This is done by using a powerful host computer to store dictionary
> headers, do command-line interaction, and so on.

OK, I guess that helps, so you're running the outer interpreter (I hope
that's the right term) on the host computer. Would you still be sending
tokenized Forth words to the target, to be executed by an inner
interpreter on the target? That burns code space for the inner
interpreter and RAM for the code tokens. I'm thinking of the type of
microcontroller where there are several kbytes of read-only code space
(flash programmable) but very little ram, so almost all of the ram has
to be used for application data.

Chipforth looks interesting. There is also something called Staapl that
I read about last night but didn't understand very well, targeted for
the PIC18.

> The need for two stacks is a red herring, since all that does is
> separate control information from parameters: it doesn't take any more
> space than a unified stack.

Two stack pointers, and software instructions to push and pop them,
instead of using hardware registers and the hardware subroutine stack.

>> C has more creature comforts...


> This is more a matter of taste, I think. As long as you're prepared
> to use a ton of complex tools such as linkers, make, compilers,
> assemblers, and so on, they you can do it that way. I'm not at all
> sure these are "creature comforts", though: I have to question whether
> they're part of the problem or part of the solution.

I mean creature comforts in the language, like having names for
variables instead of making you remember the stack contents, automatic
checking that functions are called with the right number of args, some
semblance of a type system (though a weak one in C's case), etc. There
are of course lots of very smart Forth programmers getting by without
this stuff, but IMO it's tying up a certain amount of their brainpower
that could be deployed to other parts of the problem, if bookkeeping of
that sort were left to the compiler.

Elizabeth D Rather

unread,
Jun 30, 2010, 3:47:24 PM6/30/10
to
On 6/29/10 4:39 PM, Paul Rubin wrote:
...

> I don't have much exposure to Forth so maybe I'm wrong about this, but
> it seems to me that Forth's big virtue was being able to run a complete
> development environment (compiler and interpreter) on a small embedded
> target computer. In the 1970's and 1980's when computers were
> expensive, that mattered a lot. These days, cross-development is a lot
> easier, you can simulate most embedded targets on a laptop, and so
> forth. So there's not much need to poke at code directly on the target
> without any intermediate tools (like a cross-debugger) running on a
> bigger host. So a lot of Forth's previous advantage is negated.

You are correct that running an entire development environment on a
resource-constrained system was a big advantage early on, and is less so
now. But Forth has evolved, along with the rest of the computing world.
Nowadays we have sophisticated Forth cross-development systems that
run on PCs and maintain a fully-interactive development environment with
a wide variety of target hosts.

And I must emphasize that interactive development in Forth goes far
beyond "poking at code directly on the target." It includes the ability
to execute any word on the target directly, supplying appropriate
arguments; typing in definitions and executing them directly; and much
more. And being able to do this with an actual target is much better
than running a simulator, because you have the actual timings, can see
real I/O ports, etc.

For more information on cross-development in Forth, see
http://www.forth.com/embedded/index.html and the draft standard for
Forth cross-compilers, see links here
http://newsgroups.derkeiler.com/Archive/Comp/comp.lang.forth/2007-06/msg00283.html.

> Then looking at the target platform itself, we can arbitrarily divide
> them into about 3 classes, depending on amount of ram available (which
> also usually corresponds with code space):
>
> 1. Very tiny targets (small PIC or Atmel), up to a few hundred bytes of
> ram. I think Forth can't really run usefully on these, so they have to
> be programmed in C or assembler. The Forth dictionary and the need for
> two stacks burns too much space, etc.

Forth cross-compilers can and do support many of these small targets.
Although it's nice to have more RAM during development, in a target
program typically the executable part of definitions can reside in ROM
or flash; the headers exist only during development, in the host. And
stacks in Forth are typically quite small; we have developed programs
that ran on targets with as few as 64 bytes on each stack.

> 2. Smallish targets, let's say 1k up to 32k or so: Forth can be useful
> here, and knowing it might be helpful for rapid prototyping, but C has
> more creature comforts, and again, once you have a cross-debugger and
> simulator, Forth doesn't seem to gain you that much.

You should try a modern Forth cross-development system in order to make
a useful comparison about "creature comforts". Free evaluation versions
of FORTH, Inc.'s SwiftX are available, and I assume evaluation versions
of MPE's cross compilers are available as well.

> 3. Larger targets that can handle garbage collected languages. Most
> mobile phones these days are programmed in Java, a clumsy language in my
> opinion, but much less error-prone than C or Forth because of its
> pointer safety and automatic storage management. The benefit of Java is
> not OO (which is nowhere near as important as it's sometimes cracked up
> to be) but in runtime safety (no malloc/free errors and no uncaught
> stray pointers) compared with C.

In my experience, dynamic memory manage schemes can have reliability
issues. Forth is used in a number of safety-critical applications
because its modularity and interactive development style make it easier
to thoroughly validate code.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

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

Stephen Pelc

unread,
Jun 30, 2010, 4:20:40 PM6/30/10
to
On Wed, 30 Jun 2010 12:07:02 -0700, Paul Rubin
<no.e...@nospam.invalid> wrote:

>Chipforth looks interesting. There is also something called Staapl that
>I read about last night but didn't understand very well, targeted for
>the PIC18.

There was a Rochester Forth conference in the 1980s at which three
different people/organisations presented what is now usually called
by MPE an Umbilical Forth, or by Forth Inc a chipFORTH.

What has changed since then are code generation techniques and the
functionality. Native code generation with optimisation is the
norm for the commercial compilers. The Developer edition of our
cross compilers ship with a USB stack, a FAT file system and a GUI
framework. A TCP/IP stack is an option.

Stephen


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

Jerry Avins

unread,
Jun 30, 2010, 4:52:08 PM6/30/10
to
On 6/30/2010 3:07 PM, Paul Rubin wrote:

...

> I mean creature comforts in the language, like having names for


> variables instead of making you remember the stack contents, automatic
> checking that functions are called with the right number of args, some
> semblance of a type system (though a weak one in C's case), etc. There
> are of course lots of very smart Forth programmers getting by without
> this stuff, but IMO it's tying up a certain amount of their brainpower
> that could be deployed to other parts of the problem, if bookkeeping of
> that sort were left to the compiler.

I find that passing parameters on the stack frees me from needing to
think of pointless variable names. Some people complain about postfix
notation which mirrors the way i think about operations. To each his own!

Paul Rubin

unread,
Jun 30, 2010, 5:33:18 PM6/30/10
to
Elizabeth D Rather <era...@forth.com> writes:
> And I must emphasize that interactive development in Forth goes far
> beyond "poking at code directly on the target." It includes the
> ability to execute any word on the target directly, supplying
> appropriate arguments; typing in definitions and executing them
> directly; and much more. And being able to do this with an actual
> target is much better than running a simulator, because you have the
> actual timings, can see real I/O ports, etc.

Point taken, I can see how this could sometimes be nicer than even a
fairly fast compile-and-upload cycle in a typical C environment. Still,
gdb lets you call arbitrary C functions with arbitrary args in the
target (it uses a simple wire-line protocol for that), and you can
define macros on the host side which can (to an extent) substitute for
being able to create new client-side functions on the fly.

On the host side, of course it's a partly a matter of preference and
familiarity, but C and Forth both seem like anachronisms to me at this
point. I do most of my host-side stuff in Python these days, which is
similar in spirit to Lisp in some regards. I can generally code
something in Python several times faster than I can code it in C.

John Passaniti

unread,
Jun 30, 2010, 6:16:01 PM6/30/10
to
On Jun 30, 4:52 pm, Jerry Avins <j...@ieee.org> wrote:
> I find that passing parameters on the stack frees me from
> needing to think of pointless variable names. Some people
> complain about postfix notation which mirrors the way i
> think about operations. To each his own!

Odd... the fact that it is a parameter to a function, a part of an
expression, or the control variable on a loop certainly suggests the
value itself isn't pointless. Otherwise, why would you be passing
it? So chances are excellent that the value represents something that
can easily be named. This "I don't have to give names to values on
the stack" argument for Forth has never been one I've been comfortable
with. It doesn't make sense; every value on the stack represents
*something* to the program, but more importantly to *you*. So in your
brain that item on the stack is a concept, and when you read code and
your inner voice is echoing back the meaning of that code, that
concept has a name. So what's the problem in coming up with a name?

The usual examples of this are things like this:

for (int i = 0; i < 8; i++)
do_something();

Okay, sure, you might say that "i" in this is pointless, since we're
not using the value of "i" in the loop. But I would argue that the
programmer didn't just wake up and say, "for no reason at all, I want
to loop eight times." The reason for the loop is an opportunity to
name the variable something meaningful that will communicate intent to
others (and to the programmer several months later, when they revisit
the code). Say for example that you're bit-banging a serial
transmission and each time through the loop, you've output another
bit. Hmmm, I guess that index variable has some meaning after all,
and a name certainly suggests itself:

for (int bit = 0; bit < 8; bit++)
next_bit();

Certainly, if the language you're using doesn't require you to name
things like index variables used for counted loops, that's fine.
Three languages that allow this are Forth, Smalltalk, and Perl:

8 0 do next_bit loop
8 timesRepeat: [next_bit].
next_bit() foreach(1..8);

But if you're using a language like C that needs a name for loop
variables, stopping to think about what the loop is doing should
suggest to you a valid, non-pointless name that may actually help
document what each iteration is. And if that fails you, then you're
free get all Forthy and invent new syntax that others will have to
decypher:

#define REPEAT(n) for (int i = 0; i < n; i++)

REPEAT(8)
next_bit();

Or if macros get you down, get functional:

void repeat(int count, void (*func)(void)) {
while (count--)
func();
}

repeat(8, next_bit);

Now, if you (or anyone) can come up with a case other than index
variables used for loops-- where the index variable isn't used in the
loop-- that forces you to invent *pointless* variable names, I'd like
to hear it. Keep in mind that the reasons why Forth programmers like
to have anonymous values on the stack are usually because you're
juggling items on the stacks. In other languages that do the juggling
for you, this isn't a problem.


Elizabeth D Rather

unread,
Jun 30, 2010, 6:40:51 PM6/30/10
to
On 6/30/10 9:07 AM, Paul Rubin wrote:
> Andrew Haley<andr...@littlepinkcloud.invalid> writes:
>> With all due respect, you're out of your depth here. Since chipFORTH
>> some 20+ years ago (and maybe before then; I don't know) it has been
>> possible to do full interactive development on very small targets.
>> This is done by using a powerful host computer to store dictionary
>> headers, do command-line interaction, and so on.
>
> OK, I guess that helps, so you're running the outer interpreter (I hope
> that's the right term) on the host computer. Would you still be sending
> tokenized Forth words to the target, to be executed by an inner
> interpreter on the target? That burns code space for the inner
> interpreter and RAM for the code tokens. I'm thinking of the type of
> microcontroller where there are several kbytes of read-only code space
> (flash programmable) but very little ram, so almost all of the ram has
> to be used for application data.

The "text interpreter" is the current term for the code that processes a
text input stream, from the terminal, source file, or wherever. The
original Forths had an "address interpreter" that processed previously
compiled addresses of called words; that architecture is referred to as
Indirect Threaded Code (ITC) or the less-common Direct Threaded Code
(DTC). Nowadays many Forths, including all the commercial ones,
generate optimized machine code, as Stephen has described, so the
"address interpreter" doesn't exist.

> Chipforth looks interesting. There is also something called Staapl that
> I read about last night but didn't understand very well, targeted for
> the PIC18.

chipFORTH is now succeeded by SwiftX, described in the link in my
previous post on this subject.

>> The need for two stacks is a red herring, since all that does is
>> separate control information from parameters: it doesn't take any more
>> space than a unified stack.
>
> Two stack pointers, and software instructions to push and pop them,
> instead of using hardware registers and the hardware subroutine stack.

Actually, hardware registers and subroutine stack (when there is one)
are definitely used. Any professional-quality implementation is
carefully tuned to take maximum advantage of the target hardware. In
general, managing the data stack involves less overhead than processing
calling sequences in languages such as C, and management of the return
stack is mostly transparent.

>>> C has more creature comforts...
>> This is more a matter of taste, I think. As long as you're prepared
>> to use a ton of complex tools such as linkers, make, compilers,
>> assemblers, and so on, they you can do it that way. I'm not at all
>> sure these are "creature comforts", though: I have to question whether
>> they're part of the problem or part of the solution.
>
> I mean creature comforts in the language, like having names for
> variables instead of making you remember the stack contents, automatic
> checking that functions are called with the right number of args, some
> semblance of a type system (though a weak one in C's case), etc. There
> are of course lots of very smart Forth programmers getting by without
> this stuff, but IMO it's tying up a certain amount of their brainpower
> that could be deployed to other parts of the problem, if bookkeeping of
> that sort were left to the compiler.

It's a different style of programming. I have taught many, many Forth
courses over the last 35-or-so years. It takes a little practice to
become really comfortable with stack-based programming, but in my
courses after a couple of days of working problems, programmers are
pretty comfortable. It's like learning to ride a bicycle: wobbly at
first, but at some point a switch gets thrown in the brain, and after
that it's perfectly natural.

Cheers,
Elizabrth

Krishna Myneni

unread,
Jun 30, 2010, 7:01:53 PM6/30/10
to
On Jun 30, 5:16 pm, John Passaniti <john.passan...@gmail.com> wrote:
> On Jun 30, 4:52 pm, Jerry Avins <j...@ieee.org> wrote:
>
> > I find that passing parameters on the stack frees me from
> > needing to think of pointless variable names. Some people
> > complain about postfix notation which mirrors the way i
> > think about operations. To each his own!
>
> Odd... the fact that it is a parameter to a function, a part of an
> expression, or the control variable on a loop certainly suggests the
> value itself isn't pointless.  Otherwise, why would you be passing
> it?  So chances are excellent that the value represents something that
> can easily be named.  This "I don't have to give names to values on
> the stack" argument for Forth has never been one I've been comfortable
> with.  It doesn't make sense; every value on the stack represents
> *something* to the program, but more importantly to *you*.  ...

It's pretty easy to come up with an example to illustrate what Jerry
was getting at:

: add ( operand1 operand2 -- result ) + ;

Now, why would I want to write the following?

: add LOCALS| op2 op1 | op1 op2 + ;

Sure, the items on the stack have meaning, but so what? The
manipulation is trivial and the code is easily followed.

There are less trivial examples, for example,

: arg ( f: x y -- arg[x+iy] ) FSWAP fatan2 ;

In C, you might write the above as,

double arg( double x, double y )
{
return( fatan2( y, x );
}

Do I really need to assign names to the stack arguments, other than in
the stack comment, for my code to be comprehensible?

Of course, if there are more than two arguments, or if there is a lot
of stack manipulation, names are helpful.

Krishna


Albert van der Horst

unread,
Jun 30, 2010, 7:53:35 PM6/30/10
to
In article <4cWdncgP_qTEhLbR...@supernews.com>,
Andrew Haley <andr...@littlepinkcloud.invalid> wrote:
>Paul Rubin <no.e...@nospam.invalid> wrote:
<SNIP>

>
>> 2. Smallish targets, let's say 1k up to 32k or so: Forth can be useful
>> here, and knowing it might be helpful for rapid prototyping, but C has
>> more creature comforts, and again, once you have a cross-debugger and
>> simulator, Forth doesn't seem to gain you that much.
>
>This is more a matter of taste, I think. As long as you're prepared
>to use a ton of complex tools such as linkers, make, compilers,
>assemblers, and so on, they you can do it that way. I'm not at all
>sure these are "creature comforts", though: I have to question whether
>they're part of the problem or part of the solution.

Cross-debuggers and simulators. Nice tools but they are an effort
to develop. If they are not buggy, they cost you an arm and a leg,
if they are, they cost you your hair.

I was soooo relieved, when I could run Forth on my Renesas board.
Now I can pick a single thing I want accomplished like setting
1.5 V on a D/A pin and experiment until it works instead of working
through an ide to get the right C-include file for the chip
and combine it with the right library. The edit, compile, link, power
on, connect, fail cycle.

I'm not yet that far with a new 32 bit Renesas I have.
Its Renesas tools don't work on Linux Wine.
I suspect they try to do nasty things to my disk for copy
protection. (On Windows those nasty things probably succeed,
which is hardly reassuring, but my XP drive is out of space anyway.)
I only need an assembler that runs under MSDOS, but it may be
less of an effort to write a Forth assembler than extract that
from the tools cd :-(

To tap the power of the chip you need to study the data sheet,
otherwise you can't understand what happens in the c-routines
anyway.

$FF port12 1+ C! \ port12 on output
$F7 port12 C!
Jee, a zero on the seven segment display, with the decimal point on .

It is much less comforting then to see it on the simulator, or
is it?

>
>Andrew.

Groetjes Albert

--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Paul Rubin

unread,
Jun 30, 2010, 7:31:51 PM6/30/10
to
Albert van der Horst <alb...@spenarnc.xs4all.nl> writes:
> Cross-debuggers and simulators. Nice tools but they are an effort
> to develop. If they are not buggy, they cost you an arm and a leg,
> if they are, they cost you your hair.

Well, for debugging, gdb has been around forever, it's reliable and it's
free. Simulators may be a different matter but they are generally well
worth the development effort, since you can get them going before the
target hardware even exists.

> I'm not yet that far with a new 32 bit Renesas I have.
> Its Renesas tools don't work on Linux Wine.

I'm not familiar with Renesas but it wouldn't occur to me to use
anything but native Linux tools, to the point that it would control my
target hardware selection, unless something requiring Windows had
absolutely overwhelming advantages in some other regard.

> $FF port12 1+ C! \ port12 on output
> $F7 port12 C!
> Jee, a zero on the seven segment display, with the decimal point on .
>
> It is much less comforting then to see it on the simulator, or is it?

Right, it's necessary to make sure the simulator matches the hardware by
testing that those low level things work properly. In other regards a
simulator can you give much more flexibility, e.g. you can simulate the
user inputs too, allowing completely automatic testing. You can also
run as many instances of it as you want, without having to replicate
unique or expensive special hardware, etc.

Paul Rubin

unread,
Jun 30, 2010, 8:49:35 PM6/30/10
to
Elizabeth D Rather <era...@forth.com> writes:
> Nowadays many Forths, including all the commercial ones,
> generate optimized machine code, as Stephen has described, so the
> "address interpreter" doesn't exist.

That is cool to know; I'd heard of it being done but didn't know that it
was widespread in practice. But, what happens with AVR-style cpu's
where the code and data space are separate, and you can't change the
code without re-flashing the part? It doesn't seem to get the same
level of interactivity, if re-flashing wipes out the ram contents (I'm
not sure if it does).

> chipFORTH is now succeeded by SwiftX, described in the link in my
> previous post on this subject.

I looked at that and it seems nice, though the AVR stuff is much cheaper
(Arduino boards start at about US$ 20, with free development tools).

> In general, managing the data stack involves less overhead than
> processing calling sequences in languages such as C, and management of
> the return stack is mostly transparent.

I guess I can believe that.

>> I mean creature comforts in the language, like having names for

>> variables instead of making you remember the stack contents,...


>
> It takes a little practice to become really comfortable with
> stack-based programming, but in my courses after a couple of days of
> working problems, programmers are pretty comfortable.

I think writing stack-based code isn't too big a problem but I'm less
sure what happens when you try to debug it, since any Forth word can
manipulate the stack in unpredictable ways. In C, the debugger can
usually show you the complete call stack including the args to all the
functions in the call chain, since (assuming you compile with a frame
pointer) it knows the stack contents received by each of those
functions. Also, in normal Forth, apparently nothing stops you from
popping the wrong number of items from the stack, or passing args of the
wrong type, both of which sound like good good sources of bugs. There
is something called StrongForth which statically enforces the stack
diagrams on words, but it doesn't sound like it ever caught on.

Does Forth have anything like function pointers? I.e. if I want to pass
a function as a parameter to another function, like in C. This wasn't
obvious from the tutorials I looked at, but maybe I didn't read far
enough.

Elizabeth D Rather

unread,
Jun 30, 2010, 9:21:27 PM6/30/10
to
On 6/30/10 2:49 PM, Paul Rubin wrote:
> Elizabeth D Rather<era...@forth.com> writes:
>> Nowadays many Forths, including all the commercial ones,
>> generate optimized machine code, as Stephen has described, so the
>> "address interpreter" doesn't exist.
>
> That is cool to know; I'd heard of it being done but didn't know that it
> was widespread in practice. But, what happens with AVR-style cpu's
> where the code and data space are separate, and you can't change the
> code without re-flashing the part? It doesn't seem to get the same
> level of interactivity, if re-flashing wipes out the ram contents (I'm
> not sure if it does).

SwiftX supports most of the AVR parts, as well as 8051's that have
Harvard architecture and others. Where appropriate, the cross-compiler
can re-flash the program. It's not quite as convenient as being able to
compile to RAM, but current flash doesn't have as severe re-write
limitations like some years ago. We make it pretty seamless (with most
parts you don't have to deal with a separate utility, for example).

>> chipFORTH is now succeeded by SwiftX, described in the link in my
>> previous post on this subject.
>
> I looked at that and it seems nice, though the AVR stuff is much cheaper
> (Arduino boards start at about US$ 20, with free development tools).

Yeah, companies that sell primarily hardware have free development
tools. That hasn't thrown us, Keil and a lot of other software
developers out of business, because generally you get what you pay for.

...


>>> I mean creature comforts in the language, like having names for
>>> variables instead of making you remember the stack contents,...
>>
>> It takes a little practice to become really comfortable with
>> stack-based programming, but in my courses after a couple of days of
>> working problems, programmers are pretty comfortable.
>
> I think writing stack-based code isn't too big a problem but I'm less
> sure what happens when you try to debug it, since any Forth word can
> manipulate the stack in unpredictable ways.

Unpredictable? Gosh, I hope not! Forth words in any half-way decently
written code have a stack diagram that exactly describes their stack
behavior.

> In C, the debugger can
> usually show you the complete call stack including the args to all the
> functions in the call chain, since (assuming you compile with a frame
> pointer) it knows the stack contents received by each of those
> functions.

That sounds pretty complicated. The better Forths have ways to help you
monitor what's on the stack, but that's rarely more than a few items.
We have done analyses on some pretty complex applications that showed
the stack rarely getting more than a half-dozen items deep, including
words called by layers of outer words, etc. A single word rarely has to
handle more than two or three things (counting things like a double
integer or a two-vector as "a thing").

> Also, in normal Forth, apparently nothing stops you from
> popping the wrong number of items from the stack, or passing args of the
> wrong type, both of which sound like good good sources of bugs.

Not a "source" of bugs, those *are* bugs. Fortunately, they're
extremely easy to detect.

> There
> is something called StrongForth which statically enforces the stack
> diagrams on words, but it doesn't sound like it ever caught on.

Most people think that's overkill. It's extremely easy to include code
to check stack depth on entry to words when debugging if you want to,
but most people find it's so easy to just supply parameters, execute a
word, and look at the resulting stack that extra tools just aren't needed.

These are typical of the kinds of worries people have before learning
Forth. A couple of days of serious practice writing and testing code
will get you beyond trying to visualize difficulties. It's like trying
to visualize swimming without getting wet.

> Does Forth have anything like function pointers? I.e. if I want to pass
> a function as a parameter to another function, like in C. This wasn't
> obvious from the tutorials I looked at, but maybe I didn't read far
> enough.

Absolutely. The Forth term is "execution tokens". You can pass them as
parameters, store them in single variables used as vectors, or put them
in an array accessed by a computed index, for example. There are good
examples in my books, and probably other places.

Cheers,
Elizabeth

Krishna Myneni

unread,
Jun 30, 2010, 10:26:47 PM6/30/10
to
On Jun 30, 6:01 pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:

> ...


> : arg     ( f: x y -- arg[x+iy] )  FSWAP fatan2 ;
>
> In C, you might write the above as,
>
> double arg( double x, double y )
> {
>     return( fatan2( y, x );

> ...

Notice the error with unmatched parentheses in the above example. I
didn't do it on purpose, but the mistake actually serves to highlight
an advantage of Forth's stack-based computation over named arguments
in a language like C. The parentheses are syntactical baggage imposed
by C and other languages, resulting from the requirement to use named
arguments. Forth demonstrates that such baggage is truly unneeded in a
programming language.

Have you ever written a line of C code with so many parentheses that
you weren't quite sure how many and where to add the closing
parentheses? I've seen intermediate C programmers guess about the
number and location of the matching parentheses, and then compile and
run the program to see if they were right! Yeah, the compiler will
catch most such errors, but you've wasted several clock cycles of your
life trying to match the parentheses correctly. Forth has its own
issues, but being basically syntax free, the language avoids such
pitfalls as the nested parentheses.

Krishna


John Passaniti

unread,
Jun 30, 2010, 10:32:26 PM6/30/10
to
On Jun 30, 7:01 pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> It's pretty easy to come up with an example to illustrate what Jerry
> was getting at:
>
> : add ( operand1 operand2 -- result )  + ;
>
> Now, why would I want to write the following?
>
> : add LOCALS| op2 op1 |  op1 op2 + ;

I wasn't aware there was a pressing need in Forth to create synonyms
for existing words that don't provide additional functionality. And
yes, in this silly example, you're probably right-- there is no need
to provide names for a trivial function that has little value in the
first place.

> Sure, the items on the stack have meaning, but so what? The
> manipulation is trivial and the code is easily followed.

The point I got from Jerry's message was that Forth was spiffy-keen
because you don't need to invent pointless names like you do in other
languages. I'm not suggesting that Forth programmers suddenly start
going against the grain and naming everything. I'm pointing out that
in other languages where variables are named, the idea that there is
difficulty in naming variables is foreign to me, because values have
meaning, and meanings can usually translate to names.

> There are less trivial examples, for example,
>
> : arg     ( f: x y -- arg[x+iy] )  FSWAP fatan2 ;
>
> In C, you might write the above as,
>
> double arg( double x, double y )
> {
>     return( fatan2( y, x );
> }

Again, I'm not suggesting Forth programmers come up with names. I'm
saying that in other languages, coming up with names isn't difficult,
and can be used as part of the documentation. I'm not sure what the
point of your example is. In Forth, position is terribly important.
In C, because variables are named, position isn't. The C programmer
wouldn't need your example because they would just swap the order of
arguments.

> Do I really need to assign names to the stack arguments, other than in
> the stack comment, for my code to be comprehensible?

Do you really need to translate position-dependent code in Forth to
position-dependent code in C? And sure, I can write C code that makes
artificial requirements about argument position. But it isn't natural
or common.

Jerry Avins

unread,
Jun 30, 2010, 11:07:57 PM6/30/10
to
On 6/30/2010 10:32 PM, John Passaniti wrote:
> On Jun 30, 7:01 pm, Krishna Myneni<krishna.myn...@ccreweb.org> wrote:
>> It's pretty easy to come up with an example to illustrate what Jerry
>> was getting at:
>>
>> : add ( operand1 operand2 -- result ) + ;
>>
>> Now, why would I want to write the following?
>>
>> : add LOCALS| op2 op1 | op1 op2 + ;
>
> I wasn't aware there was a pressing need in Forth to create synonyms
> for existing words that don't provide additional functionality. And
> yes, in this silly example, you're probably right-- there is no need
> to provide names for a trivial function that has little value in the
> first place.
>
>> Sure, the items on the stack have meaning, but so what? The
>> manipulation is trivial and the code is easily followed.
>
> The point I got from Jerry's message was that Forth was spiffy-keen
> because you don't need to invent pointless names like you do in other
> languages. I'm not suggesting that Forth programmers suddenly start
> going against the grain and naming everything. I'm pointing out that
> in other languages where variables are named, the idea that there is
> difficulty in naming variables is foreign to me, because values have
> meaning, and meanings can usually translate to names.

Do you like naming index variables? Why?

>> There are less trivial examples, for example,
>>
>> : arg ( f: x y -- arg[x+iy] ) FSWAP fatan2 ;
>>
>> In C, you might write the above as,
>>
>> double arg( double x, double y )
>> {
>> return( fatan2( y, x );
>> }
>
> Again, I'm not suggesting Forth programmers come up with names. I'm
> saying that in other languages, coming up with names isn't difficult,
> and can be used as part of the documentation. I'm not sure what the
> point of your example is. In Forth, position is terribly important.
> In C, because variables are named, position isn't. The C programmer
> wouldn't need your example because they would just swap the order of
> arguments.
>
>> Do I really need to assign names to the stack arguments, other than in
>> the stack comment, for my code to be comprehensible?

Try calling the C function arg defined as above with arg(y,x) then hunt
down the bug (after you notice strange results.) Just as on Forth's
stack, order is important.

> Do you really need to translate position-dependent code in Forth to
> position-dependent code in C? And sure, I can write C code that makes
> artificial requirements about argument position. But it isn't natural
> or common.

I must be missing something.

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

ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

Paul Rubin

unread,
Jun 30, 2010, 11:38:14 PM6/30/10
to
Jerry Avins <j...@ieee.org> writes:
> Try calling the C function arg defined as above with arg(y,x) then
> hunt down the bug (after you notice strange results.) Just as on
> Forth's stack, order is important.

In C++ or Ada, I think it's possible to define, say, Width and Height
types, so arg would have a signature like

Angle arg(Width x, Height y)

Then the compiler would signal an error if you got the args in the wrong
order, but otherwise generate the same code (i.e. no runtime overhead)
as if you had just used doubles for x, y, and angle.

Programming without variables is sometimes called "point-free style" and
it's handy for simple cases, but unreadable for complex ones.

Jerry Avins

unread,
Jul 1, 2010, 12:14:08 AM7/1/10
to

I thought the subject was C.

jerry

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Paul Rubin

unread,
Jul 1, 2010, 1:33:32 AM7/1/10
to
Elizabeth D Rather <era...@forth.com> writes:
> We have done analyses on some pretty complex applications that
> showed the stack rarely getting more than a half-dozen items deep,...

> These are typical of the kinds of worries people have before learning
> Forth. A couple of days of serious practice writing and testing code
> will get you beyond trying to visualize difficulties.

I guess that makes sense. I'm used to bigger systems and programs where
there's usually a lot more stuff on the stack and elsewhere, but in the
typical microcontroller application I guess it's feasible in practice to
use a "bare hands" approach.

> Absolutely. The Forth term is "execution tokens".

Ah, cool, now I know what to look for. Thanks.

Elizabeth D Rather

unread,
Jul 1, 2010, 3:33:52 AM7/1/10
to
On 6/30/10 7:33 PM, Paul Rubin wrote:
> Elizabeth D Rather<era...@forth.com> writes:
>> We have done analyses on some pretty complex applications that
>> showed the stack rarely getting more than a half-dozen items deep,...
>> These are typical of the kinds of worries people have before learning
>> Forth. A couple of days of serious practice writing and testing code
>> will get you beyond trying to visualize difficulties.
>
> I guess that makes sense. I'm used to bigger systems and programs where
> there's usually a lot more stuff on the stack and elsewhere, but in the
> typical microcontroller application I guess it's feasible in practice to
> use a "bare hands" approach.

Bigger systems don't necessarily have more on the stack. I'm thinking of
the control system for an airport in Saudi Arabia that I worked on some
years ago that involved a network of 512 8086-based computers plus 8
PDP-ll's (yeah, it was quite a few years ago) managing real-time control
of >32,000 points over 500 square miles via a huge central database.
Most of those systems were running multiple tasks. But stack depth was
rarely great. In fact, it was something of a shock to some of the
programmers working with Windows for the first time in the 90's to see
the size of the calling sequences to the C routines we dealt with. It's
really just a very different style of programming.

The major difference is that Forth programs are factored into much
smaller, simpler individual components.

Paul Rubin

unread,
Jul 1, 2010, 4:02:45 AM7/1/10
to
Elizabeth D Rather <era...@forth.com> writes:
> Bigger systems don't necessarily have more on the stack....

> The major difference is that Forth programs are factored into much
> smaller, simpler individual components.

I guess I don't understand this. I'm aware that Forth programs tend to
be factored into even smaller functions than C programs. That would
seem to mean many layers of words calling other words. So doesn't that
put MORE stuff on the stack rather than less?

Yes, in large C programs it's common to have 100's of levels of function
calls from ordinary (non-recursive) control flow. Also in some
algorithms (not C specific) one sometimes uses 1000's of levels of
recursion. I think Forth is not usually used for those sorts of
purposes. With Java it is even worse, because instead of function
calls, it's class dispatch, so it's difficult to tell from reading the
code where the code might be reached from.

Tell me, on small microcontrollers, does compiled native code tend to be
smaller or larger than threaded Forth code from the same source? I
could see it being either way.

Elizabeth D Rather

unread,
Jul 1, 2010, 4:22:19 AM7/1/10
to
On 6/30/10 10:02 PM, Paul Rubin wrote:
> Elizabeth D Rather<era...@forth.com> writes:
>> Bigger systems don't necessarily have more on the stack....
>> The major difference is that Forth programs are factored into much
>> smaller, simpler individual components.
>
> I guess I don't understand this. I'm aware that Forth programs tend to
> be factored into even smaller functions than C programs. That would
> seem to mean many layers of words calling other words. So doesn't that
> put MORE stuff on the stack rather than less?

No, actually it doesn't. In the first place, there *are* variables and
other data structures that contain important data being worked on,
particularly data being worked on by different tasks. The stack is used
to pass parameters through a succession of processes, during which time
there isn't typically much stack growth. It's hard to explain in the
abstract; easier with examples that you can work on.

> Yes, in large C programs it's common to have 100's of levels of function
> calls from ordinary (non-recursive) control flow. Also in some
> algorithms (not C specific) one sometimes uses 1000's of levels of
> recursion. I think Forth is not usually used for those sorts of
> purposes. With Java it is even worse, because instead of function
> calls, it's class dispatch, so it's difficult to tell from reading the
> code where the code might be reached from.

Recursion is possible in Forth, but is much less commonly used than in
some other languages.

> Tell me, on small microcontrollers, does compiled native code tend to be
> smaller or larger than threaded Forth code from the same source? I
> could see it being either way.

That's an extremely interesting question. For many years it was assumed
that ITC would be smaller. In the mid-90's, when we first started
working with optimized native code compilation we were delighted to find
that, on average, program sizes on 32-bit processors shrank
significantly, as much as 40% on one fairly large program, while on
8-bit and 16-bit processors it stayed about the same or grew slightly
(but performance improved enough to justify some growth).

When one is severely pressed for space, some form of tokenizing is the
best approach. We did a project once on an AVR with 8K bytes of code
space and 128K of paged data space. We developed a 6K kernel (leaving
enough space for some added code functions) supporting a token system
that could operate entirely in data space. It was agreeably fast,
faster than an earlier prototype on an 8051.

Andrew Haley

unread,
Jul 1, 2010, 5:28:59 AM7/1/10
to
Paul Rubin <no.e...@nospam.invalid> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>> With all due respect, you're out of your depth here. Since chipFORTH
>> some 20+ years ago (and maybe before then; I don't know) it has been
>> possible to do full interactive development on very small targets.
>> This is done by using a powerful host computer to store dictionary
>> headers, do command-line interaction, and so on.
>
> OK, I guess that helps, so you're running the outer interpreter (I
> hope that's the right term) on the host computer. Would you still
> be sending tokenized Forth words to the target, to be executed by an
> inner interpreter on the target?

Basically, yes, unless you're generating native code.

> That burns code space for the inner interpreter and RAM for the code
> tokens. I'm thinking of the type of microcontroller where there are
> several kbytes of read-only code space (flash programmable) but very
> little ram, so almost all of the ram has to be used for application
> data.

If using tokenized code, you save space: tokenized code is very small,
and pays for the space taken by the inner interpreter very quickly.
The break-even point for bytecode is pretty low, certainly less than
4k. The code tokens are in read-only code space, of course.

>> The need for two stacks is a red herring, since all that does is
>> separate control information from parameters: it doesn't take any more
>> space than a unified stack.
>
> Two stack pointers, and software instructions to push and pop them,
> instead of using hardware registers and the hardware subroutine stack.

There's no reason not to use the hardware subroutine stack, if it
fits.

>>> C has more creature comforts...
>> This is more a matter of taste, I think. As long as you're prepared
>> to use a ton of complex tools such as linkers, make, compilers,
>> assemblers, and so on, they you can do it that way. I'm not at all
>> sure these are "creature comforts", though: I have to question whether
>> they're part of the problem or part of the solution.
>
> I mean creature comforts in the language, like having names for
> variables instead of making you remember the stack contents,
> automatic checking that functions are called with the right number
> of args, some semblance of a type system (though a weak one in C's
> case), etc. There are of course lots of very smart Forth
> programmers getting by without this stuff, but IMO it's tying up a
> certain amount of their brainpower that could be deployed to other
> parts of the problem, if bookkeeping of that sort were left to the
> compiler.

I understand that, but it's necessary to point out the dwnsides of
this approach too. Besides, as I said, the language issues are a
matter of taste.

Andrew.

Stephen Pelc

unread,
Jul 1, 2010, 5:30:16 AM7/1/10
to
On Thu, 01 Jul 2010 01:02:45 -0700, Paul Rubin
<no.e...@nospam.invalid> wrote:

>Elizabeth D Rather <era...@forth.com> writes:
>> Bigger systems don't necessarily have more on the stack....
>> The major difference is that Forth programs are factored into much
>> smaller, simpler individual components.
>
>I guess I don't understand this. I'm aware that Forth programs tend to
>be factored into even smaller functions than C programs. That would
>seem to mean many layers of words calling other words. So doesn't that
>put MORE stuff on the stack rather than less?

Yes, there may be more return addresses, but there will be far less
frame construction. Yes, I know about C compilers and locals storage
mechanisms. On balance, there's less on the Forth data stack than
on C's frames, but there may be more traffic on the Forth data stack.

That having been said, native code Forth compilers are quite capable
of reducing a collection of stack operations to register traffic
only.

Just as C has a virtual machine, so does Forth. The difference is that
the Forth VM is directly exposed to the programmer. However, Forth
compiler writers regard that as a conceptual VM. What the compiler
produces is code that has the same effect as code for for the VM.

>Tell me, on small microcontrollers, does compiled native code tend to be
>smaller or larger than threaded Forth code from the same source? I
>could see it being either way.

It all depends.

Our VFX desktop Forths have compilers that are tuned for run-time
performance. Out of the box, the code is a little bigger than
that for a DTC implementation.

Our VFX compilers for embedded systems often have switches that
affect speed/space trade-offs. Over a decade ago, we ported a 68xxx
app from our old DTC compiler to a then new VFX native code compiler.
The native code version was a few per cent smaller.

In current embedded apps on 32 bit CPUs, code size is not the problem.
Most people run out of RAM long before they run out of code space.

Doug Hoffman

unread,
Jul 1, 2010, 6:27:55 AM7/1/10
to
On 6/30/10 8:49 PM, Paul Rubin wrote:

> I think writing stack-based code isn't too big a problem but I'm less
> sure what happens when you try to debug it, since any Forth word can
> manipulate the stack in unpredictable ways. In C, the debugger can
> usually show you the complete call stack including the args to all the
> functions in the call chain, since (assuming you compile with a frame
> pointer) it knows the stack contents received by each of those
> functions. Also, in normal Forth, apparently nothing stops you from
> popping the wrong number of items from the stack, or passing args of the
> wrong type, both of which sound like good good sources of bugs.

Debugging in Forth is simple and can be done many ways. Here is one way
using a trivial example:

: square ( n -- n*n )
dup * ;

trace on \ enable trace just for the word QUAD
: quad ( a b c x -- ax2+bx+c )
>r \ a b c
swap \ a c b
r@ \ a c b x
* + \ a bx+c
swap \ bx+c a
r> square \ bx+c a x2
* + ;
trace off

\ execute QUAD normally:
3 4 5 2 quad . 25 ok

\ now execute it using debug:
debug on
3 4 5 2 quad .
( 4 ) \ 3 \ 4 \ 5 \ 2
: quad ( 4 ) \ 3 \ 4 \ 5 \ 2
>r ( 3 ) \ 3 \ 4 \ 5
swap ( 3 ) \ 3 \ 5 \ 4
r@ ( 4 ) \ 3 \ 5 \ 4 \ 2
* ( 3 ) \ 3 \ 5 \ 8
+ ( 2 ) \ 3 \ 13
swap ( 2 ) \ 13 \ 3
r> ( 3 ) \ 13 \ 3 \ 2
square ( 3 ) \ 13 \ 3 \ 4
* ( 2 ) \ 13 \ 12
+ ( 1 ) \ 25
; 25 ok

Note that square is not traced because we didn't ask for it. Also,
experienced Forth programmers may not define QUAD using the vertical
format with line-by-line stack comments. It's a matter of personal
preference.

-Doug

Andrew Haley

unread,
Jul 1, 2010, 6:55:47 AM7/1/10
to
Doug Hoffman <glid...@gmail.com> wrote:

> : quad ( a b c x -- ax2+bx+c )
> >r \ a b c
> swap \ a c b
> r@ \ a c b x
> * + \ a bx+c
> swap \ bx+c a
> r> square \ bx+c a x2
> * + ;

I know it's just an example, but yeuch! You can't post code like
that, surely, not even as an example.

: quad ( a b c x - ax^2+bx+c)
>r \ a b c
rot r@ * \ b c ax
rot + \ c ax+b
r> * \ c (ax+b)x
+ \ c+(ax+b)x
;

or, better:

: quad ( c b a x - ax^2+bx+c)
>r
r@ * + \ c b+ax
r> * + \ c+(b+ax)x
;

or maybe even a local instead of r@:

: quad ( c b a x - ax^2+bx+c)
locals| x |
x * +
x * + ;

Andrew.

Doug Hoffman

unread,
Jul 1, 2010, 7:34:49 AM7/1/10
to
On 7/1/10 6:55 AM, Andrew Haley wrote:

> I know it's just an example, but yeuch! You can't post code like
> that, surely, not even as an example.

Apparently I can. ;-)

> : quad ( a b c x - ax^2+bx+c)
> >r \ a b c
> rot r@ * \ b c ax
> rot + \ c ax+b
> r> * \ c (ax+b)x
> + \ c+(ax+b)x
> ;
>
> or, better:
>
> : quad ( c b a x - ax^2+bx+c)
> >r
> r@ * + \ c b+ax
> r> * + \ c+(b+ax)x
> ;
>
> or maybe even a local instead of r@:
>
> : quad ( c b a x - ax^2+bx+c)
> locals| x |
> x * +
> x * + ;

But I needed to show a subservient word that was not traced, which was
the whole point of defining square. Your definitions lose that ability.

Like you say, it was just an example to illustrate a point (about
debugging), not to show an optimized example of the quadratic. Sorry if
it caused you heartache.

-Doug

Krishna Myneni

unread,
Jul 1, 2010, 7:52:54 AM7/1/10
to
On Jul 1, 5:55 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
...

> or, better:
>
> : quad ( c b a x - ax^2+bx+c)
>    >r
>    r@ * +      \ c b+ax
>    r> * +      \ c+(b+ax)x
>    ;
>
> or maybe even a local instead of r@:
>
> : quad ( c b a x - ax^2+bx+c)
>    locals| x |
>    x * +
>    x * + ;
>
> Andrew.

The locals version, above, is ok, but relating to the previous
discussion about pointless variable names, I would have used your
previous example, although I might have chosen to write,

: quad ( c b a x - ax^2+bx+c)

dup >r


* + \ c b+ax
r> * + \ c+(b+ax)x
;

All of the above are examples of applying Horner's method for
evaluating polynomials.

Krishna

Andrew Haley

unread,
Jul 1, 2010, 7:57:50 AM7/1/10
to

It's not that, exactly, it's that there can be examples that have
subservient words that are also good Forth code. This is important
when talking with people who don't know Forth well, isn't it?

Andrew.

Andrew Haley

unread,
Jul 1, 2010, 8:05:25 AM7/1/10
to
Krishna Myneni <krishna...@ccreweb.org> wrote:
> On Jul 1, 5:55?am, Andrew Haley <andre...@littlepinkcloud.invalid>

> wrote:
> ...
>> or, better:
>>
>> : quad ( c b a x - ax^2+bx+c)
>> >r
>> r@ * + \ c b+ax
>> r> * + \ c+(b+ax)x
>> ;
>>
>> or maybe even a local instead of r@:
>>
>> : quad ( c b a x - ax^2+bx+c)
>> locals| x |
>> x * +
>> x * + ;
>
> The locals version, above, is ok, but relating to the previous
> discussion about pointless variable names, I would have used your
> previous example, although I might have chosen to write,
>
> : quad ( c b a x - ax^2+bx+c)
> dup >r
> * + \ c b+ax
> r> * + \ c+(b+ax)x
> ;

Sorry Krishna, you lost me, I don't know which "previous example" you
mean. I guess you mean the first of these two?

Re replacing

>r
r@ * + \ c b+ax

with

dup >r
* + \ c b+ax

fair enough, that's a matter of taste. For what it's worth, I thought
of the second form and after a moment of thought replaced it with the
first, which IMO is clearer.

Andrew.

Krishna Myneni

unread,
Jul 1, 2010, 8:21:01 AM7/1/10
to
On Jun 30, 9:32 pm, John Passaniti <john.passan...@gmail.com> wrote:
> On Jun 30, 7:01 pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
>
> > It's pretty easy to come up with an example to illustrate what Jerry
> > was getting at:
>
> > : add ( operand1 operand2 -- result )  + ;
>
> > Now, why would I want to write the following?
>
> > : add LOCALS| op2 op1 |  op1 op2 + ;
>
> I wasn't aware there was a pressing need in Forth to create synonyms
> for existing words that don't provide additional functionality.  And
> yes, in this silly example, you're probably right-- there is no need
> to provide names for a trivial function that has little value in the
> first place.
>

Yes, it may be a silly example, but coding such a trivial example as a
C function can't be done without named references to the arguments,
like 'op1' and 'op2' or 'x' and 'y'.

> > Sure, the items on the stack have meaning, but so what? The
> > manipulation is trivial and the code is easily followed.
>
> The point I got from Jerry's message was that Forth was spiffy-keen
> because you don't need to invent pointless names like you do in other
> languages.  I'm not suggesting that Forth programmers suddenly start
> going against the grain and naming everything.  I'm pointing out that
> in other languages where variables are named, the idea that there is
> difficulty in naming variables is foreign to me, because values have
> meaning, and meanings can usually translate to names.
>

Jerry made a good point: Forth doesn't require you to assign names to
arguments. Good Forth programmers usually *do* give names to
arguments, but those names are mostly just used inside of a stack
comment and many times do not need to be carried around as baggage
inside of a definition. Jerry was talking about creating pointless
named references to the arguments for use inside the code, e.g.
variables, values, or locals. He was not suggesting that he doesn't
document the stack arguments and results for his words.

> > There are less trivial examples, for example,
>
> > : arg     ( f: x y -- arg[x+iy] )  FSWAP fatan2 ;
>
> > In C, you might write the above as,
>
> > double arg( double x, double y )
> > {
> >     return( fatan2( y, x );
> > }
>

> Again, I'm not suggesting Forth programmers come up with names. ...

Names are necessary for documentation, and Forth programmers do need
to come up with names. They are just freed from the restriction of
having to use those names for anything else other than comments.
Andrew's code for evaluating a quadratic expression is a nice example.

: quad ( c b a x - ax^2+bx+c)
>r
r@ * + \ c b+ax
r> * + \ c+(b+ax)x
;


> ... I'm


> saying that in other languages, coming up with names isn't difficult,
> and can be used as part of the documentation.  I'm not sure what the
> point of your example is.  In Forth, position is terribly important.
> In C, because variables are named, position isn't.  The C programmer
> wouldn't need your example because they would just swap the order of
> arguments.
>

As Jerry points out, there is position dependence in C as well, when
you call the function. You have to be as equally well aware of the
order of args you pass on the stack to a Forth word as to the arg list
of a C function.

> > Do I really need to assign names to the stack arguments, other than in
> > the stack comment, for my code to be comprehensible?
>
> Do you really need to translate position-dependent code in Forth to
> position-dependent code in C?  And sure, I can write C code that makes
> artificial requirements about argument position.  But it isn't natural
> or common.


Krishna

Krishna Myneni

unread,
Jul 1, 2010, 8:23:56 AM7/1/10
to
On Jul 1, 7:05 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> > On Jul 1, 5:55?am, Andrew Haley <andre...@littlepinkcloud.invalid>
> > wrote:
> > ...
> >> or, better:
>
> >> : quad ( c b a x - ax^2+bx+c)
> >>    >r
> >>    r@ * +      \ c b+ax
> >>    r> * +      \ c+(b+ax)x
> >>    ;
>
> >> or maybe even a local instead of r@:
>
> >> : quad ( c b a x - ax^2+bx+c)
> >>    locals| x |
> >>    x * +
> >>    x * + ;
>
> > The locals version, above, is ok, but relating to the previous
> > discussion about pointless variable names, I would have used your
> > previous example, although I might have chosen to write,
>
> > : quad ( c b a x - ax^2+bx+c)
> >   dup >r
> >      * +      \ c b+ax
> >   r> * +      \ c+(b+ax)x
> > ;
>
> Sorry Krishna, you lost me, I don't know which "previous example" you
> mean.  I guess you mean the first of these two?

Yes.

>
> Re replacing
>
>     >r
>     r@ * +      \ c b+ax
>
> with
>
>    dup >r
>       * +      \ c b+ax
>
> fair enough, that's a matter of taste.  For what it's worth, I thought
> of the second form and after a moment of thought replaced it with the
> first, which IMO is clearer.
>
> Andrew.

Ok. It's a matter of taste.

Krishna

Jerry Avins

unread,
Jul 1, 2010, 8:32:02 AM7/1/10
to
On 6/30/2010 10:32 PM, John Passaniti wrote:

...

> Again, I'm not suggesting Forth programmers come up with names. I'm
> saying that in other languages, coming up with names isn't difficult,
> and can be used as part of the documentation. I'm not sure what the
> point of your example is. In Forth, position is terribly important.
> In C, because variables are named, position isn't. The C programmer
> wouldn't need your example because they would just swap the order of
> arguments.

To belabor this a bit. Calculations often require intermediate results.
Names for those don't normally convey much meaning. When doing a
register-to-register or register-to-memory data transfer in assembly
language, would you want to name the datum each time?

Long ago, machine instructions had many addresses: the source of each of
two operands, the destination of the result, and the address of the next
instruction. Then someone invented the program counter, and the last of
those became superfluous (but the jump instruction had to be invented).
A large advance was the accumulator. It serves as the applied source of
one operand and also the implied destination of the result. The
accumulator was a GOOD THING. I think of the (parameter) stack as a
layered accumulator, the implied destination of results and also the
implied source of as many operands as needed.

...

Jerry

�����������������������������������������������������������������������

Doug Hoffman

unread,
Jul 1, 2010, 9:00:17 AM7/1/10
to
On 7/1/10 7:57 AM, Andrew Haley wrote:
> Doug Hoffman<glid...@gmail.com> wrote:
>> On 7/1/10 6:55 AM, Andrew Haley wrote:

...

>>> : quad ( c b a x - ax^2+bx+c)
>>> locals| x |
>>> x * +
>>> x * + ;
>>
>> But I needed to show a subservient word that was not traced, which
>> was the whole point of defining square. Your definitions lose that
>> ability.
>>
>> Like you say, it was just an example to illustrate a point (about
>> debugging), not to show an optimized example of the quadratic.
>> Sorry if it caused you heartache.
>
> It's not that, exactly, it's that there can be examples that have
> subservient words that are also good Forth code.

OK. I'll let you do that. I already made my point about debugging.

> This is important
> when talking with people who don't know Forth well, isn't it?

I've been told that beginning Forthers should not use locals.

-Doug

John Passaniti

unread,
Jul 1, 2010, 9:43:45 AM7/1/10
to
On Jun 30, 11:07 pm, Jerry Avins <j...@ieee.org> wrote:
> Do you like naming index variables? Why?

What an odd question. I don't like or dislike having to come up with
variable names. If the language I'm using requires a name, I have no
problem coming up with one. It isn't "pointless." It's an
opportunity to document intent. The fact you're writing a loop means
you're iterating over *something* and whatever that something is
likely has a clear, obvious, and useful name. Yes, in languages where
the loop variable doesn't need to be named, that represents 0.000001%
of my time that I save. Whoopie.

Further, I would say that the tiny fraction of time you spend not
coming up with a variable name on a loop is easily matched by the need
of documenting your Forth words with stack effect diagrams. I've
always found it funny when Forth programmers complain about things
like function prototypes in C, but have no problem coming up with a
stack effect diagram for their words. They delight in not having to
provide types for items on the stack because Forth is an untyped
language, yet decorate their stack effect diagrams with "c" and "u"
and "a" and "xt". It's just another example of conservation of
complexity-- you can come up with a language that requires you
decorate variables with types and names, or you can come up with a
simpler language that doesn't require this, but which practically
needs you to do the same amount of work in comments. I see it as a
wash in terms of effort.

> I must be missing something.

Me too. Citing that you don't need to name stack items, the only
examples that have been generated of how this is any great big win are
loops where the index variable isn't used in the body of a loop, and
toy, artificial examples where synonyms are created or where arguments
are swapped isn't exactly compelling to me.

John Passaniti

unread,
Jul 1, 2010, 9:53:35 AM7/1/10
to
On Jul 1, 12:14 am, Jerry Avins <j...@ieee.org> wrote:
> I thought the subject was C.

No, actually, I thought the subject was how Forth was way-cool over
other, unnamed, languages because you have difficulty coming up with
names for things that actually have clear meaning. C is an example
language where you're forced against you will to go through the
arduous process of coming up with a name for loop variables. It's
tough, I know, but here's a crazy suggestion if you find yourself
stuck with a blinking cursor, begging you to name something that you
have a clear concept of in your head, but for which a name is lacking:

int i;

And get ready for this. If you have two nested loops and can't think
of a name for the inner loop variable...

int j;

John Passaniti

unread,
Jul 1, 2010, 10:14:06 AM7/1/10
to
On Jul 1, 8:21 am, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> Yes, it may be a silly example, but coding such a trivial
> example as a C function can't be done without named
> references to the arguments, like 'op1' and 'op2' or
> 'x' and 'y'.

And in my experience, the same amount of effort in naming function
parameters is taken up in shuffling items on the stack and coming up
with stack effect diagrams. You aren't saving anything, you're just
moving where the effort is placed. In C, you're documenting for the
compiler. In Forth, you're documenting for the programmer who is
acting as the compiler. In both cases, you're doing roughly the same
amount of work.

> Jerry made a good point: Forth doesn't require you to assign names to
> arguments. Good Forth programmers usually *do* give names to
> arguments, but those names are mostly just used inside of a stack
> comment and many times do not need to be carried around as baggage
> inside of a definition.

And the value of not having to name items on the stack is diminished
each time you have to swap, rot, over, etc. Again, I see it as a
wash.

> Jerry was talking about creating pointless
> named references to the arguments for use inside the code, e.g.
> variables, values, or locals. He was not suggesting that he doesn't
> document the stack arguments and results for his words.

The effort is similar. The supposed superiority of Forth because of
this is not demonstrated.

> Names are necessary for documentation, and Forth programmers do need
> to come up with names. They are just freed from the restriction of
> having to use those names for anything else other than comments.
> Andrew's code for evaluating a quadratic expression is a nice example.
>
> : quad ( c b a x - ax^2+bx+c)
>    >r
>    r@ * +      \ c b+ax
>    r> * +      \ c+(b+ax)x
>    ;

How is this a nice example? The effort placed in documenting intent--
the stack effect diagram and the running stack comments-- is easily
*more* work than the C equivalent.

Jerry Avins

unread,
Jul 1, 2010, 10:19:35 AM7/1/10
to

That's fine, as long as I'm sure that j isn't used elsewhere in the same
scope. That can make an insidious bug, at least in some compiler's I've
used. One rarely makes this mistake with fresh code. Reusing code makes
the mistake much more likely.

I have no trouble naming things. I enjoy the freedom of not always
needing to.

Jerry


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

ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

Jerry Avins

unread,
Jul 1, 2010, 10:22:56 AM7/1/10
to

I told the OP what I like about Forth. I didn't ask you to like the same
things. What is this sub thread about?

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Andrew Haley

unread,
Jul 1, 2010, 10:44:34 AM7/1/10
to
John Passaniti <john.pa...@gmail.com> wrote:

>> : quad ( c b a x - ax^2+bx+c)
>> >r
>> r@ * + \ c b+ax
>> r> * + \ c+(b+ax)x
>> ;
>
> How is this a nice example? The effort placed in documenting intent--
> the stack effect diagram and the running stack comments-- is easily
> *more* work than the C equivalent.

In this case, because it generalizes nicely from

: quad ( c b a x - ax^2+bx+c)
>r
r@ * + \ c b+ax
r> * + \ c+(b+ax)x
;

to

: cube ( d c b a x - ax^2+bx+c)
>r
r@ * + \ d c b+ax
r@ * + \ d c+(b+ax)x
r> * + \ d+(c+(b+ax)x)x
;

to

: powerseries ( coeffs order x - result)
swap 0 do
dup >r * + r>
loop drop ;

or, if you like locals, ;-)

: powerseries ( coeffs order x - result)
locals| x |
0 do
x * +
loop ;

Andrew.

It is loading more messages.
0 new messages