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

Small, understandable Forth

164 views
Skip to first unread message

deech

unread,
Dec 24, 2009, 6:47:53 PM12/24/09
to
Hi all,
I am a long time reader, but first time poster. I have been fascinated
by Forth since I read JonesForth [1]. I was wondering if there are
other small, understandable Forth implementations, perhaps ones that
are being used for real work. I am looking into making my own small
Forth and want to compare/contrast different implementations.
Something like GForth [2] is too big!

Thanks!
-deech

[1] http://www.annexia.org/forth
[2] http://www.jwdt.com/~paysan/gforth.html

Aleksej Saushev

unread,
Dec 24, 2009, 6:56:17 PM12/24/09
to
deech <aditya...@gmail.com> writes:

> I am a long time reader, but first time poster. I have been fascinated
> by Forth since I read JonesForth [1]. I was wondering if there are
> other small, understandable Forth implementations, perhaps ones that
> are being used for real work. I am looking into making my own small
> Forth and want to compare/contrast different implementations.
> Something like GForth [2] is too big!

You don't use small implementation for real work.
Even gforth, the one you call "too big", is underpowered.


--
HE CE3OH...

P.M.Lawrence

unread,
Dec 24, 2009, 10:01:39 PM12/24/09
to
deech wrote:
> Hi all,
> I am a long time reader, but first time poster. I have been fascinated
> by Forth since I read JonesForth [1]. I was wondering if there are
> other small, understandable Forth implementations, perhaps ones that
> are being used for real work. I am looking into making my own small
> Forth and want to compare/contrast different implementations.
> Something like GForth [2] is too big!
>

I would suggest you start by looking at eforth (or its relative
hforth) and maybe Pygmy Forth until you are comfortable with the
basics and some of the internals - use tutorials and primers you can
find with google too. Then get to grips with the "real work"
implementations by exploring the review versions from Forth Inc. and
MicroProcessor Engineering, that Elizabeth Rather and Stephen Pelc
respectively have posted about around here. FICL will also provide an
interesting contrast. P.M.Lawrence.

ron

unread,
Dec 25, 2009, 4:45:45 AM12/25/09
to
On Dec 25, 1:47 am, deech <aditya.si...@gmail.com> wrote:
> Hi all,
> ... I was wondering if there are

> other small, understandable Forth implementations, perhaps ones that
> are being used for real work.

Reva ( http://ronware.org/reva/ ) is on the small side, and I use it
for real work. Another user has written a dialect of APL in it. There
are smaller Forths, and whether or not you understand a particular
Forth depends to a large extent on how well the code is documented.
Reva has an active and helpful user community, and so if you don't
care about ANS compatibility, it's worth a look.

MarkWills

unread,
Dec 25, 2009, 6:14:40 AM12/25/09
to
On Dec 24, 11:56 pm, Aleksej Saushev <a...@inbox.ru> wrote:

What a total load of crap. You really do talk some utter shit.

The very essence of Forth is compactness and simplicity. Your
thoughtless and idiotic comments run counter to everything that Forth
is.

Maybe you are just a stupid troll? If so, congratulations. I hope I
made your day.

W. James

unread,
Dec 25, 2009, 6:38:25 AM12/25/09
to
MarkWills wrote:

> The very essence of Forth is compactness and simplicity. Your
> thoughtless and idiotic comments run counter to everything that Forth
> is.

Did God tell you that?
Did Forth tell you that?
No?
Then it's just your idiotic opinion.
Then it just means that you want Forth to be that way.
You would be dismayed if Forth could do more than flush a toilet.


--

Albert van der Horst

unread,
Dec 25, 2009, 7:17:55 AM12/25/09
to
In article <2dc47086-a913-497d...@d21g2000yqn.googlegroups.com>,

deech <aditya...@gmail.com> wrote:
>Hi all,
>I am a long time reader, but first time poster. I have been fascinated
>by Forth since I read JonesForth [1]. I was wondering if there are
>other small, understandable Forth implementations, perhaps ones that
>are being used for real work. I am looking into making my own small
>Forth and want to compare/contrast different implementations.
>Something like GForth [2] is too big!

ciforth (see site below).

echo WORDS | lina | wc -w
358

2 files (lina & forth.lab), documentation and your code.

Examples codes : ciasdis, manx2.

>
>Thanks!
>-deech

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

Mat

unread,
Dec 25, 2009, 7:27:26 AM12/25/09
to
Hello,

A minimalistic and simple forth system is:
www.retroforth.com

The Versions < 10 are subroutine threaded, the current system was
written completely from scratch on top of a small stack, based VM.

You can play with an extended and faster vm in progress, which offers
an (in this stage rudimentary) AOT compiler for native code
generation:

http://github.com/Mat2/extended-ngaro

4p is a fast forth system with JIT compiler:
http://maschenwerk.de/

This forth, as I know, is used for years in productive work.

That's also true for Reva:
http://ronware.org/reva/

All above aren't ANS compatible but in some way related together.

ANS compatible:

If you want to learn in a fail save enviroment you can try:
http://home.arcor.de/a.s.kochenburger/minforth.html

Other forths you may be interested in are:
http://www.gnu.org/software/gforth/
http://home.hccnet.nl/a.w.m.van.der.horst/ciforth.html
http://code.google.com/p/fina-forth/

If you want to experiment with something non conformistic but
innovative:

http://rainbowforth.sourceforge.net/
http://www.colorforth.com/
http://muforth.nimblemachines.com/
http://christophe.lavarenne.free.fr/ff/

-Mat.

deech

unread,
Dec 25, 2009, 11:17:13 AM12/25/09
to
On Dec 25, 6:27 am, Mat <damb...@web.de> wrote:
> Hello,
>
> A minimalistic and simple forth system is:www.retroforth.com
>
> The Versions < 10 are subroutine threaded, the current system was
> written completely from scratch on top of a small stack, based VM.
>
> You can play with an extended and faster vm in progress, which offers
> an (in this stage rudimentary) AOT compiler for native code
> generation:
>
> http://github.com/Mat2/extended-ngaro
>
> 4p is a fast forth system with JIT compiler:http://maschenwerk.de/
>
> This forth, as I know, is used for years in productive work.
>
> That's also true for Reva:http://ronware.org/reva/
>
> All above aren't ANS compatible but in some way related together.
>
> ANS compatible:
>
> If you want to learn in a fail save enviroment you can try:http://home.arcor.de/a.s.kochenburger/minforth.html
>
> Other forths you may be interested in are:http://www.gnu.org/software/gforth/http://home.hccnet.nl/a.w.m.van.der.horst/ciforth.htmlhttp://code.google.com/p/fina-forth/

Thank you! That is a wonderful list. Google could not have come up
with it! Is there some systematic way (besides writing some code) of
diving in to an implementation?

-deech

MarkWills

unread,
Dec 25, 2009, 11:28:28 AM12/25/09
to

Nope. Because I wouldn't use Forth to flush a toilet. I'd use 555
timer.

I plan to use to forth for field re-programmable RTU's connected via
low-bandwidth satellite (TSAT). Instead of the software being written
over a period of 3 years by a team of 40 people, resulting in a scary,
un-maintainable mess, it will be developed by one person, and
documented. Instead of needing an operating system like Linux or
VXWorks to do *anything at all* (like some controllers on the market
today) and needing >60 seconds to start work, it will boot and be
operational in ~1 second. Instead of having a memory footprint of
around 8MB, it will have a memory footprint measured in kilobytes.

>Did God tell you that?
>Did Forth tell you that?
>No?
>Then it's just your idiotic opinion.

Just let me get this straight. Are you actually saying that Forth is
NOT compact, nor simple, as I stated in my post?

No. It is not my idiotic opinion. It is the opinion of Moore, Rather,
Fox, Brodie, and many other Forth luminaries. It is an opinion
constantly re-iterated on just about every Forth. It is the principle
reason for using Forth. It is the very reason that Forth was invented/
evolved by Moore himself. Have you been on the Christmas sherry or
something?

Since I doubt you can be bothered to go look for yourself, and for the
benefit of others, I offer a few examples:

http://www.ultratechnology.com/forth.htm
http://forth.com/resources/evolution/evolve_2.html#1.2 (have a look at
2.4.3)
http://www.complang.tuwien.ac.at/anton/euroforth2005/papers/ceballos05.pdf
http://dec.bournemouth.ac.uk/forth/forth.html

A nice quote from the last link above: "Forth has four primitive
virtues: (a) Intimacy, (b) Immediacy, (c) Extensibility, and (d)
Economy. It has two derived virtues: Total Comprehension, and
Symbiosis."

Interestingly, I tried googling your name in connection with Forth,
and, somewhat un-surprisingly, nothing turned up.

Strange that.

Aleksej Saushev

unread,
Dec 25, 2009, 12:15:45 PM12/25/09
to
MarkWills <markrob...@yahoo.co.uk> writes:

> On Dec 24, 11:56О©╫pm, Aleksej Saushev <a...@inbox.ru> wrote:
>> deech <aditya.si...@gmail.com> writes:
>> > I am a long time reader, but first time poster. I have been fascinated
>> > by Forth since I read JonesForth [1]. I was wondering if there are
>> > other small, understandable Forth implementations, perhaps ones that
>> > are being used for real work. I am looking into making my own small
>> > Forth and want to compare/contrast different implementations.

>> > Something like GForth [2] О©╫is too big!


>>
>> You don't use small implementation for real work.
>> Even gforth, the one you call "too big", is underpowered.
>

> What a total load of crap. You really do talk some utter shit.
>
> The very essence of Forth is compactness and simplicity. Your
> thoughtless and idiotic comments run counter to everything that Forth
> is.
>
> Maybe you are just a stupid troll? If so, congratulations. I hope I
> made your day.

You're just stupid, everyone knows that pretty well already.
So would you be kind enough to shut up and go play with your toys?

Forth is compact only when it is incapable of doing elementary things,
otherwise it is neither compact nor simple, that's the fact of the day.

Ah, I forgot another alternative, Forth is compact when it is broken,
pForth and FICL are nice examples of this kind. If you don't know where
they're broken, you didn't use them for anything more than calculator.


--
HE CE3OH...

Elizabeth D Rather

unread,
Dec 25, 2009, 2:10:52 PM12/25/09
to
deech wrote:
> On Dec 25, 6:27 am, Mat <damb...@web.de> wrote:
...

>
> Thank you! That is a wonderful list. Google could not have come up
> with it! Is there some systematic way (besides writing some code) of
> diving in to an implementation?
>
> -deech

Well, there are books. I wrote two, that are available from Amazon and
FORTH, Inc www.forth.com. There are several others out there. One of
my books, Forth Application Techniques, is a tutorial with a lot of
exercises designed to build your vocabulary and stack management skills,
an important prerequisite for serious programming.

But, ultimately, you do need to write some code. Otherwise, it's like
trying to learn swimming without getting wet.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310-491-3356
5155 W. Rosecrans Ave. #1018 Fax: +1 310-978-9454
Hawthorne, CA 90250
http://www.forth.com

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

Elizabeth D Rather

unread,
Dec 25, 2009, 2:19:03 PM12/25/09
to
Aleksej Saushev wrote:
> MarkWills <markrob...@yahoo.co.uk> writes:
>
>> On Dec 24, 11:56 pm, Aleksej Saushev <a...@inbox.ru> wrote:
>>> deech <aditya.si...@gmail.com> writes:
>>>> I am a long time reader, but first time poster. I have been fascinated
>>>> by Forth since I read JonesForth [1]. I was wondering if there are
>>>> other small, understandable Forth implementations, perhaps ones that
>>>> are being used for real work. I am looking into making my own small
>>>> Forth and want to compare/contrast different implementations.
>>>> Something like GForth [2] is too big!

>>> You don't use small implementation for real work.
>>> Even gforth, the one you call "too big", is underpowered.
>> What a total load of crap. You really do talk some utter shit.
>>
>> The very essence of Forth is compactness and simplicity. Your
>> thoughtless and idiotic comments run counter to everything that Forth
>> is.
>>
>> Maybe you are just a stupid troll? If so, congratulations. I hope I
>> made your day.
>
> You're just stupid, everyone knows that pretty well already.
> So would you be kind enough to shut up and go play with your toys?
>
> Forth is compact only when it is incapable of doing elementary things,
> otherwise it is neither compact nor simple, that's the fact of the day.
>
> Ah, I forgot another alternative, Forth is compact when it is broken,
> pForth and FICL are nice examples of this kind. If you don't know where
> they're broken, you didn't use them for anything more than calculator.

All this name calling (on both sides) is unnecessary, unproductive, and
unpleasant.

Alexei, you are misinformed. I have worked with many compact Forths
that are running very significant real-world applications. I have
written of many of them here. I do not know why you keep posting such
uninformed opinions.

Aleksej Saushev

unread,
Dec 25, 2009, 4:00:47 PM12/25/09
to
Elizabeth D Rather <era...@forth.com> writes:

> Aleksej Saushev wrote:
>> MarkWills <markrob...@yahoo.co.uk> writes:
>>
>>> On Dec 24, 11:56 pm, Aleksej Saushev <a...@inbox.ru> wrote:
>>>> deech <aditya.si...@gmail.com> writes:
>>>>> I am a long time reader, but first time poster. I have been fascinated
>>>>> by Forth since I read JonesForth [1]. I was wondering if there are
>>>>> other small, understandable Forth implementations, perhaps ones that
>>>>> are being used for real work. I am looking into making my own small
>>>>> Forth and want to compare/contrast different implementations.
>>>>> Something like GForth [2] is too big!
>>>> You don't use small implementation for real work.
>>>> Even gforth, the one you call "too big", is underpowered.

...

>> Forth is compact only when it is incapable of doing elementary things,
>> otherwise it is neither compact nor simple, that's the fact of the day.
>>
>> Ah, I forgot another alternative, Forth is compact when it is broken,
>> pForth and FICL are nice examples of this kind. If you don't know where
>> they're broken, you didn't use them for anything more than calculator.
>

> Alexei, you are misinformed. I have worked with many compact
> Forths that are running very significant real-world
> applications. I have written of many of them here. I do not
> know why you keep posting such uninformed opinions.

Past tense again? Your "King Khaled International Airport" time is gone,
the world is much more complex these days. If you want to keep up in
pace with time, you have to use lots of complex tools. Otherwise you
are not productive enough. Sure, you can roll your own binary protocol
for each and every case you need to establish data flow across network,
or you can store raw PCM or even unprocessed G.729a, but...

What do you give off to user? Do you support custom client?
Do you write sound output yourself?
For all operating systems in widespread use?

User expects MPEG-1 and nice HTML pages. Perhaps with ECMAScript.
This is even in case analogous to your KKIA.

It isn't a problem to raise hardware demands.
Can you buy 1 GB industrial CF cards for a reasonable price today?
No, you have to buy 2 GB ones.
Can you buy memory units of capacity less than 256 MB?
Same, you have to use those you can get for a reasonable price.

And all of those make enough space for a full-blown NetBSD or FreeBSD
installation with X server and more. There's no need to save octets,
there's need to save development time instead.

And almost any home-grown solution doesn't pay off while there's free
implementation. And you have ready or half-ready libraries for almost
anything, only... in C! Or C++. Or Perl. Or Python. Or Ruby. In many
cases those are reasonably fast and they give you faster development
cycle. It is easier to brush up your Common Lisp and adapt ready library
than to roll your own in Forth. Even when you have carte blanche on
tools to use because of time constraints.

Note that you don't need to pay anything to anyone outside your
company just to use compiler and bundled libraries. Look! It is there!
Free of charge, free to use for any purpose. And almost bug free.
I don't meet bugs in GCC, I meet bugs in Gforth instead, and I do it
regularly. I know bugs in PFE, in FICL, in pForth, but not in GCC,
even though it is more complex and bugs should be more probable to meet
there a priori.

Another part of the problem is that you kindly "forget" the existence
of development tools. Sure, there may be some need to program memory
constrained system, but you don't have the single choice of rolling
your own small Forth for those. You can strip down big Forth instead.
Or you can cross-build everything you need. And the latter approach
means that you use _large_ system rather than the tiny one.
For many side observers (I'm not alone) you sound like stuck to past,
everyone else cross-builds and feels happier than if using tiny Forth
to build anything around it.

BTW, how do you develop programs with your tiny Forth?
REPL and save what succeded? This assumes major aid from host side,
related tools are to be considered as part of your Forth.


--
HE CE3OH...

Bernd Paysan

unread,
Dec 25, 2009, 5:26:21 PM12/25/09
to
Aleksej Saushev wrote:
> I don't meet bugs in GCC, I meet bugs in Gforth instead, and I do it
> regularly. I know bugs in PFE, in FICL, in pForth, but not in GCC,
> even though it is more complex and bugs should be more probable to
> meet there a priori.

Not finding bugs in a program you don't really use doesn't count. Or do
you really use GCC? Since if, you'd notice that it is full of bugs. So
many of them that we spent significant effort to get Gforth compiling
properly again on almost any change of a minor GCC version number.

We are looking for other alternatives to GCC, because it's getting worse
over time. GCC is complex code, no doubt, and it has its fair share of
bugs. The many-eyes principle works on GCC, as well, so a program like
GCC which is used by lots and lots of projects will have more bugs found
than a niche language like Gforth.

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

Aleksej Saushev

unread,
Dec 25, 2009, 6:19:20 PM12/25/09
to
Bernd Paysan <bernd....@gmx.de> writes:

> Aleksej Saushev wrote:
>> I don't meet bugs in GCC, I meet bugs in Gforth instead, and I do it
>> regularly. I know bugs in PFE, in FICL, in pForth, but not in GCC,
>> even though it is more complex and bugs should be more probable to
>> meet there a priori.
>
> Not finding bugs in a program you don't really use doesn't count. Or do
> you really use GCC? Since if, you'd notice that it is full of bugs. So
> many of them that we spent significant effort to get Gforth compiling
> properly again on almost any change of a minor GCC version number.
>
> We are looking for other alternatives to GCC, because it's getting worse
> over time. GCC is complex code, no doubt, and it has its fair share of
> bugs. The many-eyes principle works on GCC, as well, so a program like
> GCC which is used by lots and lots of projects will have more bugs found
> than a niche language like Gforth.

I use GCC more frequently than Gforth, still I don't encounter bugs in it.
Perhaps that's because I don't use its esoteric features. Meanwhile I run
into major issues with standard features in Gforth. E.g. I hit another
marker or, probably, dictionary bug, when after several hundreds of
"marker smth ... smth" iterations marker invocation simply doesn't
restore dictionary. For instance I see that ' smth returns the same
execution token for the marker after the point it was to be removed.
I've implemented a workaround and don't try to diagnose it further for now.

Concerning "many-eyes" principle. There's no doubt that community factor
is important, maybe the most important for a language, natural or artificial.
"C" and "C++" provides a good deal of high-quality code, it also provides
tools and development models. All you can see with Forth is that it "works
the best for closed source software only."


--
HE CE3OH...

Josh Grams

unread,
Dec 26, 2009, 8:19:08 AM12/26/09
to
Elizabeth D Rather wrote:

> Aleksej Saushev wrote:
>> Forth is compact only when it is incapable of doing elementary things,
>> otherwise it is neither compact nor simple, that's the fact of the day.
>>
>> Ah, I forgot another alternative, Forth is compact when it is broken,
>> pForth and FICL are nice examples of this kind. If you don't know where
>> they're broken, you didn't use them for anything more than calculator.
>
> Alexei, you are misinformed. I have worked with many compact Forths
> that are running very significant real-world applications. I have
> written of many of them here. I do not know why you keep posting such
> uninformed opinions.

But how much of the language do those applications exercise? Do they
use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
extensive test suite using MARKER to restore the dictionary between
sections? Each of these things is buggy on at least one supposedly
standard Forth system.

If you stick to a basic subset of the language, you're usually safe.
But the sad fact is that you simply can't rely on the free systems to
behave in a standard fashion, or be free from serious bugs. So if you
want to use the whole language, you always have to be looking over your
shoulder and wondering whether a bug is in your code or whether the
system simply isn't behaving correctly. Which can, obviously, be very
frustrating.

--Josh

Marcel Hendrix

unread,
Dec 26, 2009, 8:00:29 AM12/26/09
to
Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth

[..]


> But how much of the language do those applications exercise? Do they
> use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
> extensive test suite using MARKER to restore the dictionary between
> sections? Each of these things is buggy on at least one supposedly
> standard Forth system.

For this statement to be true there only needs to be a single crummy
(or unmaintained, as there's no such thing as bug-free code) Forth system.

It would be more constructive to be specific here (which Forth, which feature).
Your statement smudges the reputation of all actively developed systems.
I can't imagine reported bugs not being fixed, especially not bugs
in such basic language features as were mentioned.

It is of course imaginable that supposed bugs reported by certain
people go unnoticed or are not taken seriously, especially if they aren't
supported with specific details or test code, or occur with obsolete
hardware or operating systems.

-marcel

Anton Ertl

unread,
Dec 26, 2009, 10:55:23 AM12/26/09
to
Aleksej Saushev <as...@inbox.ru> writes:
>I use GCC more frequently than Gforth, still I don't encounter bugs in it.
>Perhaps that's because I don't use its esoteric features.

What's esoteric for you may be essential for others.

>Meanwhile I run
>into major issues with standard features in Gforth. E.g. I hit another
>marker or, probably, dictionary bug, when after several hundreds of
>"marker smth ... smth" iterations marker invocation simply doesn't
>restore dictionary. For instance I see that ' smth returns the same
>execution token for the marker after the point it was to be removed.
>I've implemented a workaround and don't try to diagnose it further for now.

There is no need for you to diagnose it. Just send a reproducible bug
report. That bug report also should explain what you consider a bug
and why in an understandable way (that's also missing from the
description above).

Sending in bug reports is especially important for esoteric features
like markers which we don't use ourselves. Then, if nobody sends bug
reports, the bugs won't get fixed.

- 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 2009: http://www.euroforth.org/ef09/

Aleksej Saushev

unread,
Dec 26, 2009, 11:56:44 AM12/26/09
to
m...@iae.nl (Marcel Hendrix) writes:

> Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth
>
> [..]
>> But how much of the language do those applications exercise? Do they
>> use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
>> extensive test suite using MARKER to restore the dictionary between
>> sections? Each of these things is buggy on at least one supposedly
>> standard Forth system.
>
> For this statement to be true there only needs to be a single crummy
> (or unmaintained, as there's no such thing as bug-free code) Forth system.

Gforth is this system.

> It would be more constructive to be specific here (which Forth, which feature).

My list is:

Gforth, MARKER
PFE, INCLUDE-FILE
FICL, exceptions
pForth, exceptions

:NONAME and ACCEPT are bad experience someone else had.

> Your statement smudges the reputation of all actively developed systems.

One hardly calls system receiving no bug fixes for years "actively developed."
If Gforth were actively developed, we'd be using 0.7.1 with its marker
bug fixed for several months already.

> I can't imagine reported bugs not being fixed, especially not bugs
> in such basic language features as were mentioned.

Every actively developed software project has bug tracker.
Open source software project has bug tracker open to public, '90s are over.
If project doesn't provide bug tracker, how can you prove that bugs were
not reported? Note that there're no public contacts in Gforth's case,
mailing list is gone long ago and there's no replacement.

> It is of course imaginable that supposed bugs reported by certain
> people go unnoticed or are not taken seriously, especially if they aren't
> supported with specific details or test code, or occur with obsolete
> hardware or operating systems.

FreeBSD 6.3-STABLE is supported.
More so with FreeBSD 7.2-STABLE.
NetBSD 5.99.22 is current, which is far from being obsolete.
NetBSD 5 is supported branch.
Do you consider i486 as obsolete hardware?
I've never heard that Gforth from CVS HEAD is "obsolete," and I'm pretty
sure that if anyone says that aloud, he is to expect attacks from Anton,
Bernd and others claiming it is not.


--
HE CE3OH...

Micke

unread,
Dec 26, 2009, 12:05:20 PM12/26/09
to
On 25 joulu, 01:47, deech <aditya.si...@gmail.com> wrote:
I was wondering if there are
> other small, understandable Forth implementations, perhaps ones that
> are being used for real work.

http://flashforth.sf.net

/Mikael

Aleksej Saushev

unread,
Dec 26, 2009, 12:15:46 PM12/26/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

> Aleksej Saushev <as...@inbox.ru> writes:
>>I use GCC more frequently than Gforth, still I don't encounter bugs in it.
>>Perhaps that's because I don't use its esoteric features.
>
> What's esoteric for you may be essential for others.

I don't use any language features outside C89 standard let alone extensions.

>>Meanwhile I run
>>into major issues with standard features in Gforth. E.g. I hit another
>>marker or, probably, dictionary bug, when after several hundreds of
>>"marker smth ... smth" iterations marker invocation simply doesn't
>>restore dictionary. For instance I see that ' smth returns the same
>>execution token for the marker after the point it was to be removed.
>>I've implemented a workaround and don't try to diagnose it further for now.
>
> There is no need for you to diagnose it. Just send a reproducible bug
> report. That bug report also should explain what you consider a bug
> and why in an understandable way (that's also missing from the
> description above).
>
> Sending in bug reports is especially important for esoteric features
> like markers which we don't use ourselves. Then, if nobody sends bug
> reports, the bugs won't get fixed.

Not only you do use them, you use them in a quirky way, I posted example
how you can't even see names consisiting of ASCII control characters.

What do you call "reproducible bug report"? I tell you that I get
reproducible error with marker, but _only_ after hundred of invocations
and probably affected by other things. For me this is 100% reproducible,
and I have all chances that you'll call it isn't because of conditions.

Yes, under some unknown conditions, the following patterns in combination
lead into broken state:

marker tests-done
( some code )
tests-done

marker tests-done
[ifundef] libc require lib.fs library libc libc.so [then]
( some FFI code )
tests-done

I observe it by placing

' tests-done . cr

before and after last "tests-done" invocation (before general failure)
and noticing equal numbers. As I understand it, the dictionary is not
reset.

The original problem arises in FFI code, thus it may be connected with
that. FFI code plays nasty tricks with dictionary by using words with
unprintable names. That's why I say that this may be bug in dictionary
handling in general rather than in markers.


--
HE CE3OH...

Elizabeth D Rather

unread,
Dec 26, 2009, 1:06:23 PM12/26/09
to
Josh Grams wrote:
> Elizabeth D Rather wrote:
>> Aleksej Saushev wrote:
>>> Forth is compact only when it is incapable of doing elementary things,
>>> otherwise it is neither compact nor simple, that's the fact of the day.
>>>
>>> Ah, I forgot another alternative, Forth is compact when it is broken,
>>> pForth and FICL are nice examples of this kind. If you don't know where
>>> they're broken, you didn't use them for anything more than calculator.
>> Alexei, you are misinformed. I have worked with many compact Forths
>> that are running very significant real-world applications. I have
>> written of many of them here. I do not know why you keep posting such
>> uninformed opinions.
>
> But how much of the language do those applications exercise? Do they
> use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
> extensive test suite using MARKER to restore the dictionary between
> sections? Each of these things is buggy on at least one supposedly
> standard Forth system.

Well, I mostly work with FORTH, Inc. products, which are pretty well
vetted and have no known problems with any of these things. The widely
used free Forths (gForth, Win32Forth) are probably pretty well tested,
but (as Anton points out) rely on users to report bugs.

> If you stick to a basic subset of the language, you're usually safe.
> But the sad fact is that you simply can't rely on the free systems to
> behave in a standard fashion, or be free from serious bugs. So if you
> want to use the whole language, you always have to be looking over your
> shoulder and wondering whether a bug is in your code or whether the
> system simply isn't behaving correctly. Which can, obviously, be very
> frustrating.

Better to be selective about what system you pick. There are many
"hobby Forths" that meet the needs of their developers perfectly, but
may not be appropriate for production code.

Mat

unread,
Dec 26, 2009, 3:18:11 PM12/26/09
to
On 25 Dez., 16:17, deech <aditya.si...@gmail.com> wrote:
> On Dec 25, 6:27 am, Mat <damb...@web.de> wrote:
>
>
>
> > Hello,
>
> > A minimalistic and simple forth system is:www.retroforth.com
>
> > The Versions < 10 are subroutine threaded, the current system was
> > written completely from scratch on top of a small stack, based VM.
>
> > You can play with an extended and faster vm in progress, which offers
> > an (in this stage rudimentary) AOT compiler for native code
> > generation:
>
> >http://github.com/Mat2/extended-ngaro
>
> > 4p is a fast forth system with JIT compiler:http://maschenwerk.de/
>
> > This forth, as I know, is used for years in productive work.
>
> > That's also true for Reva:http://ronware.org/reva/
>
> > All above aren't ANS compatible but in some way related together.
>
> > ANS compatible:
>
> > If you want to learn in a fail save enviroment you can try:http://home.arcor.de/a.s.kochenburger/minforth.html
>
> > Other forths you may be interested in are:http://www.gnu.org/software/gforth/http://home.hccnet.nl/a.w.m.van.de...

>
> > If you want to experiment with something non conformistic but
> > innovative:
>
> >http://rainbowforth.sourceforge.net/http://www.colorforth.com/http://...

>
> > -Mat.
>
> Thank you! That is a wonderful list. Google could not have come up
> with it! Is there some systematic way (besides writing some code) of
> diving in to an implementation?
>
> -deech

As otherwise said, nothing compare to personal experience. That's a
sad answer because it mean in some way, some OSS forth implementations
are poorly documented for beginners (before brain death flame-wars
begins here one time again, that's my subjective viewpoint).
Personally, I try to document my own work in form of a implementation
guide but because I can only work on it in my spare time, it progress
very slowly - so I think time considerations can be one reason for
this situation. As an alternative for needed documentation, I suggest
you to contact the authors directly. Often there exist also a forum or
mailing list and/or ICQ channel for this purpose. (As a hint, asking
questions to people who work with the system of interest and are
interested in forth as language other than correspond with trolls who
just need to compensate psychic deficits though personal defamations
have some advantages).

Sorry for my english,

-Mat.

Bernd Paysan

unread,
Dec 26, 2009, 5:58:15 PM12/26/09
to
Aleksej Saushev wrote:
> What do you call "reproducible bug report"? I tell you that I get
> reproducible error with marker, but _only_ after hundred of
> invocations and probably affected by other things. For me this is 100%
> reproducible, and I have all chances that you'll call it isn't because
> of conditions.

No, we don't argue about reproducibility, we argue that you don't give
us your test case where it fails and which we can analyze, and find out
why it fails. You don't send us the code which makes it fail, you
rumble about general patterns and probably unknown conditions. In
short: head -> table. Sorry, this bug report requires additional
information for reproduction.

This is free software, if you fail to report a bug properly, it won't
get fixed. Especially when it involves deprecated libffi.fs, the tool
MARKER, which we don't use, and maybe is only reproducible on FreeBSD,
which we don't use, either.

> Yes, under some unknown conditions, the following patterns in
> combination lead into broken state:
>
> marker tests-done
> ( some code )
> tests-done
>
> marker tests-done
> [ifundef] libc require lib.fs library libc libc.so [then]
> ( some FFI code )
> tests-done
>
> I observe it by placing
>
> ' tests-done . cr
>
> before and after last "tests-done" invocation (before general failure)
> and noticing equal numbers. As I understand it, the dictionary is not
> reset.
>
> The original problem arises in FFI code, thus it may be connected with
> that. FFI code plays nasty tricks with dictionary by using words with
> unprintable names. That's why I say that this may be bug in dictionary
> handling in general rather than in markers.

Ok, FFI code is deprecated, but it still should work. It certainly *is*
an obscure feature of Gforth, which we would not care much if there is a
hidden bug in there that conflicts with MARKER - it *is* deprecated
after all (What more can we do to make you not use it any longer? Add
intentional bugs? Release a gforth-0.8.0 where it is dropped?). We
have little test code left - I adapted the old unix/socket.fs from 0.6.2
to 64 bit and tried running it a 1000 times, each time asking the local
web server for "HEAD / HTTP/1.0". I use the current CVS, which means
the file name of the loaded file will be stored up a 1000 times (it's
included a 1000 times), because Anton's hack to remove the file name as
well isn't active anymore. This doesn't crash. It doesn't crash using
the current unix/socket.fs, either. Both probably leak memory, but they
reset the dictionary fine. I also tried with plain gforth-0.7.0, works
fine, as well. I observe the dictionary pointer like you do; after
executing my marker, it's no longer visible.

What's true is that libffi.fs uses wordlists as a hash table for the
non-printable CIF strings. It actually uses a wordlist, where it
probably better should use a TABLE - this states the intention to store
arbitrary strings there - fixed. The strings are non-printable by
design ob libffi.fs, a design decision I don't agree with, but Gforth
should work fine, regardless if it's wordlist or table.

Aleksej Saushev

unread,
Dec 26, 2009, 7:35:19 PM12/26/09
to
Bernd Paysan <bernd....@gmx.de> writes:

> What's true is that libffi.fs uses wordlists as a hash table for the
> non-printable CIF strings. It actually uses a wordlist, where it
> probably better should use a TABLE - this states the intention to store
> arbitrary strings there - fixed. The strings are non-printable by
> design ob libffi.fs, a design decision I don't agree with, but Gforth
> should work fine, regardless if it's wordlist or table.

Is there a way to use more straightforward wordlist implementation?
The one based on linked lists. Or was it removed completely?


--
HE CE3OH...

Josh Grams

unread,
Dec 26, 2009, 7:51:03 PM12/26/09
to
Marcel Hendrix wrote: <2623082...@frunobulax.edu>

> Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth
>
> [..]
>> But how much of the language do those applications exercise? Do they
>> use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
>> extensive test suite using MARKER to restore the dictionary between
>> sections? Each of these things is buggy on at least one supposedly
>> standard Forth system.
>
> For this statement to be true there only needs to be a single crummy
> (or unmaintained, as there's no such thing as bug-free code) Forth system.

Hmm. What if I put it like this? With the possible exception of
gforth, I am not aware of any free software Forth system whose release
version behaves as specified by the standard in all respects. Many of
these differences can be worked around (and depending on your
programming style, you may not even notice any of them), but it can be
surprisingly difficult to get a Forth program to run on many different
systems, even though they all claim to be standard.

> It would be more constructive to be specific here (which Forth, which
> feature).

That seems irrelevant to me: the point is that, depending on what you're
doing, you can't just pick up a free system and expect it to run your
programs correctly. Also I have (I think) reported all of these to the
maintainers of the systems in question, so it didn't occur to me to
mention them again.

The systems I have tried so far which claim some standard-compliance are
4p, FICL, gforth, PFE, pforth, and SP-Forth. I haven't really tried
ciforth yet, and since I don't have a Windows machine, I have only tried
Win32Forth briefly under Wine. I think those are all the serious free
standard systems that I know of. If you know of other such systems
which run under Linux (x86 and preferably PPC as well), I'd be glad to
hear of them.

I thought I had a list of bugs somewhere, but I can't find it. So
here's a list off the top of my head:

4p (ANS compatibility seems to be an add-on, not a major goal):

* INCLUDE etc. don't save/restore the contents of the input buffer, so
you can't put anything on a line after one of these words.
* OPEN-FILE and CREATE-FILE are somewhat conflated, so `R/W CREATE-FILE`
does not truncate the file to zero length if it already exists.

FICL:

* IIRC, instead of calling a routine to accept input, it THROWs out of
the interpreter back to the part of the code which gets input. So you
cannot avoid the ok> prompt (which isn't non-standard, merely
annoying). More seriously, it means that ACCEPT doesn't work
properly: input always comes from the current stream, not from the
keyboard as it is supposed to. And any "extra" input which ACCEPT
doesn't use is passed back to the interpreter. So for instance try
`PAD 5 ACCEPT .` and enter input of more than 5 characters. I thought
about trying to patch this, but it looked like it was pretty well
coupled into the whole system, so I gave up.
* Also it has the CATCH/THROW bug which Aleksej turned up. I didn't get
around to reproducing this, but we talked about it enough that I'm
fairly sure I could.
* I haven't chased this down yet either, but PAD seems to be randomly
affected by certain things. When I do `PAD 10 BL FILL`, if I then do
`PAD 10 TYPE` I seem to get 10 spaces, but `PAD 10 DUMP` usually shows
the second and fourth bytes as 50 and 0, respectively, and `PAD CHAR+
C@ .` gives me various results.


PFE:

* RECURSE and DOES> don't work in a :NONAME definition. This may be
fixed in SVN -- I sent a possible patch, and I think Guido may have
applied it, but I don't undertand the code well enough to be sure it's
a good fix, and he seemed less familiar with it than I was.

* Certain environment queries which are supposed to return a flag
actually return a number (looks like a 4-digit year?), which causes
problems when ANDing the return value with something...

It also does a lot of things which aren't non-standard, but which I find
excruciatingly annoying:

* On a segfault, it doesn't restore the terminal state, so you are
generally left with a broken terminal.

* It reports errors using 0-based line-numbers, unlike every other piece
of software on the planet which use 1-based line numbers.

* ORDER shows <???> for every wordlist created by `WORDLIST`, so unless
you use PFE's `VOCABULARY` word, you can't tell them apart.

* It only takes one filename on the command-line, and that file is
treated as a "bootscript", so it is handled differently than if you
had INCLUDEd it. Specifically, a bunch of system state is reset
before it drops out to interactive mode. Also, BYE does not work from
within a bootscript.

* Also I don't like the way .S displays in a vertical format with both
decimal and hex -- what a waste of screen real-estate. But that's
obviously a minor quibble. :)


pforth: Actually, pforth seems fairly decent so far, except for lacking
wordlists. Again, Aleksej found a problem with CATCH/THROW here.


SP-Forth:

* ENVIRONMENT? names are in the default namespace.

* I think I found one other standard violation, but for some reason I
abandoned this system pretty quickly, so I can't remember.


That's all I can think of right now...

--Josh

Bernd Paysan

unread,
Dec 26, 2009, 8:01:26 PM12/26/09
to
Aleksej Saushev wrote:
> Is there a way to use more straightforward wordlist implementation?
> The one based on linked lists. Or was it removed completely?

If you don't want it at all, comment the "include hash.fs" out in
startup.fs - this gives you the default linked list wordlist. You also
can do "slowvoc on", which will render all wordlists you are generating
yourself to be searched by the linked list approach (while the Forth
wordlist still would be a fast hash).

Ed

unread,
Dec 27, 2009, 2:02:11 AM12/27/09
to
Marcel Hendrix wrote:
> Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth
>
> [..]
> > But how much of the language do those applications exercise? Do they
> > use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
> > extensive test suite using MARKER to restore the dictionary between
> > sections? Each of these things is buggy on at least one supposedly
> > standard Forth system.
>
> For this statement to be true there only needs to be a single crummy
> (or unmaintained, as there's no such thing as bug-free code) Forth system.
>
> It would be more constructive to be specific here (which Forth, which feature).
> Your statement smudges the reputation of all actively developed systems.
> I can't imagine reported bugs not being fixed, especially not bugs
> in such basic language features as were mentioned.
> ...

I can easily imagine it.

I've seen you throw up your hands (figuratively speaking) at the bizarre
behaviours/bugs exhibited by commercial forths. I've seen users send
in validated bug reports, and some I've sent myself. Some get fixed,
others won't. There's no pattern - sometimes the one's that don't get
fixed are more serious and lead to ongoing (albeit few) user complaints.

Knowing what I now know about forth, I'd only bye or use a forth if
it came with full source code. Not only is having full source some
measure of protection against poor support, company closing doors,
obsolescence etc., there are few forths I would call "professional
grade" i.e. one or more aspects are poorly, quirkily or incorrectly
implemented and likelihood of it changing is zero.

Not complaining - just stating the reality. No-one forces me to
use forth. In using forth, I'm accepting that it comes with minimal
support and some fixes/changes I'll need to do myself.


Anton Ertl

unread,
Dec 27, 2009, 6:54:12 AM12/27/09
to
Aleksej Saushev <as...@inbox.ru> writes:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>
>> Aleksej Saushev <as...@inbox.ru> writes:
>>>I use GCC more frequently than Gforth, still I don't encounter bugs in it.
>>>Perhaps that's because I don't use its esoteric features.
>>
>> What's esoteric for you may be essential for others.
>
>I don't use any language features outside C89 standard let alone extensions.

Either you write only toy programs in C, or (more likely) you use
language features that you don't know to be outside of C89.

>> Sending in bug reports is especially important for esoteric features
>> like markers which we don't use ourselves. Then, if nobody sends bug
>> reports, the bugs won't get fixed.
>
>Not only you do use them, you use them in a quirky way, I posted example
>how you can't even see names consisiting of ASCII control characters.

You lost me here. Where do we use markers, and what does this have to
do with seeing names?

>What do you call "reproducible bug report"?

One that allows me to reproduce the behaviour you consider buggy.

>I tell you that I get
>reproducible error with marker, but _only_ after hundred of invocations
>and probably affected by other things. For me this is 100% reproducible,
>and I have all chances that you'll call it isn't because of conditions.

If it's 100% reproducible for you, you should find it easy to generate
a file that, when included, exhibits the behaviour. Information about
the platform etc. will also help us in reproducing the behaviour.
Note that you can see in ~/.gforth-history what you did at the command
line.

>Yes, under some unknown conditions, the following patterns in combination
>lead into broken state:
>
> marker tests-done
> ( some code )
> tests-done
>
> marker tests-done
> [ifundef] libc require lib.fs library libc libc.so [then]
> ( some FFI code )
> tests-done
>
>I observe it by placing
>
> ' tests-done . cr
>
>before and after last "tests-done" invocation (before general failure)
>and noticing equal numbers. As I understand it, the dictionary is not
>reset.

That leaves too much guesswork to make it to the top of my ToDo list.

>FFI code plays nasty tricks with dictionary by using words with
>unprintable names.

Our dictionary implementation does not care if a name is printable or
not. This has also been used elsewhere, so it's unlikely to be the
source of the problem.

BTW, since you have expressed a preference for bug databases, we have
one for Gforth, on

https://savannah.gnu.org/bugs/?func=addbug&group=gforth

Reporting bugs by mail or news is more convenient for interacting with
the reporter, but the bug database is useful if we don't get around to
fixing the bug right away.

Albert van der Horst

unread,
Dec 27, 2009, 7:56:09 AM12/27/09
to
In article <g3oZm.1127$wC3....@newsfe07.iad>,
Josh Grams <jo...@qualdan.com> wrote:
<SNIP>

>
>If you stick to a basic subset of the language, you're usually safe.
>But the sad fact is that you simply can't rely on the free systems to
>behave in a standard fashion, or be free from serious bugs. So if you
...

That is called guarantees. That is something you have to pay for.
It is a sad fact of life that you can't always get something for
nothing.

If you can't put in money, you can put in the sweat to test
a free system to your satisfaction.
Even if a free system comes with a regression test, you still
have to make an effort to decide upon the quality of the test.

>
>--Josh

Coos Haak

unread,
Dec 27, 2009, 9:12:25 AM12/27/09
to
Op Sun, 27 Dec 2009 00:51:03 GMT schreef Josh Grams:

<snip>
> PFE:
.


.
> * ORDER shows <???> for every wordlist created by `WORDLIST`, so unless
> you use PFE's `VOCABULARY` word, you can't tell them apart.

How could Forth tell its name? WORDLISTs are anonymous items.
Perhaps a number could be helpful, I let ORDER display {NoName}

--
Coos

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

Marcel Hendrix

unread,
Dec 27, 2009, 4:41:51 PM12/27/09
to
Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth

> Marcel Hendrix wrote: <2623082...@frunobulax.edu>
>> Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth
[..]
>>> But how much of the language do those applications exercise? Do they
>>> use :NONAME extensively, or files, or exceptions, or ACCEPT, or have an
>>> extensive test suite using MARKER to restore the dictionary between
>>> sections? Each of these things is buggy on at least one supposedly
>>> standard Forth system.

>> For this statement to be true there only needs to be a single crummy
>> (or unmaintained, as there's no such thing as bug-free code) Forth system.

> Hmm. What if I put it like this? With the possible exception of
> gforth, I am not aware of any free software Forth system whose release
> version behaves as specified by the standard in all respects. Many of
> these differences can be worked around (and depending on your
> programming style, you may not even notice any of them), but it can be
> surprisingly difficult to get a Forth program to run on many different
> systems, even though they all claim to be standard.

Some additional comments based on my own explorations because it was hard
to believe the situation would be so serious.

You mentioned 4p, FICL, PFE, pforth and SP-Forth and Gforth. Judged by CLF
postings and your comments I expected PFE and SP-Forth and maybe pforth
to be usable. I downloaded pforth for Windows because I didn't know it.

Going by the file dates, pForth obviously hasn't been touched since 1998.
Indeed, the CATCH/THROW in catch.fth is simply wrong (trivial stack error).
This can be shown by its own example and test code at the end of the file.
I conclude this system is either not used by anyone or its maintainer
doesn't know how CATCH is supposed to work. That spells doom for less
esoteric language features. I also noted negative ALLOT and TIME&DATE are
not supported.

Next I downloaded SP-Forth. It starts off with an impressive installer.
However, it takes (too) MANY seconds to start up (?), is non-ANS, needs
to be told in all UPPERCASE and its help and docs are in Russian. I could
fix the uppercase and non-ANSness by including two files. Very nicely
done HTML help, at least/only for these two problems. Next I found that
the console window refused to work properly (couldn't set size and insert
mode etc.) Cut and paste didn't work, which was very awkward. Apparently,
after startup you can only use the system menu once (which should be enough,
of course). Although I made the console window very wide, SP-Forth uses a
line length of 80 characters whatever I did (minor issue, but not nice).

: test 0 do loop ;
1000000000 test 7 emit
.. took about 5 seconds (iForth: 1.2 seconds) , although the code is
beautiful (only and inc [esp] and a jno ):

see test

57695B 8945FC MOV FC [EBP] , EAX
57695E 33C0 XOR EAX , EAX
576960 BA00000080 MOV EDX , # 80000000
576965 2B55FC SUB EDX , FC [EBP]
576968 8D1C02 LEA EBX , [EDX] [EAX]
57696B 8B4500 MOV EAX , 0 [EBP]
57696E 8D6D04 LEA EBP , 4 [EBP]
576971 6881695700 PUSH , # 576981
576976 52 PUSH EDX
576977 53 PUSH EBX
576978 FF0424 INC [ESP]
57697B 71FB JNO 576978
57697D 8D64240C LEA ESP , C [ESP]
576981 C3 RET NEAR

Apparently the developers theorize but don't test :-)

There is indeed (per your notes) something wrong with ENVIRONMENT?

S" BLOCK" ENVIRONMENT?
S" BLOCK ENVIRONMENT?
^ -35 Illegal block number

This is a well-known problem, some of the environment queries overlap
regular Forth names.

The result of including benchmark.f was a reproducible disaster:

-- ---------------------------------------------------------------------------
S" samples/bench/benchmark.f" INCLUDED
start isn't unique (samples/bench/benchmark.f)
.S isn't unique (lib\include\tools.f)
? isn't unique (lib\include\tools.f)
AHEAD isn't unique (lib\include\tools.f)
[ELSE] isn't unique (lib\include\tools.f)
[IF] isn't unique (lib\include\tools.f)
[THEN] isn't unique (lib\include\tools.f)
[DEFINED] isn't unique (lib\include\tools.f)
[UNDEFINED] isn't unique (lib\include\tools.f)
GetTickCount isn't unique (samples/bench/benchmark.f)
M+ isn't unique (samples/bench/benchmark.f)
u2/ isn't unique (samples/bench/benchmark.f)

Loading benchmark routinesCARRAY isn't unique (samples/bench/benchmark.f)
Threshold isn't unique (samples/bench/benchmark.f)
NIL isn't unique (samples/bench/benchmark.f)


Benchmark code size = 140037 bytes.

This system's primitives using no extensions

Test time including overhead ms times ns (each)
DO LOOP 0 5000000 0
+ 0 5000000 0
M+ 32 5000000 6
* 31 5000000 6
/ 94 5000000 18
M* 31 5000000 6
M/ 78 5000000 15
/MOD 94 5000000 18
*/ 109 5000000 21
ARRAY fill 0 1000000 0
Total: 484 1


This system's O/S interface using no extensions

Test time including overhead ms times ns (each)
Win32 API: SendMessage 63 500000 126
Win32 API: GetTickCount 140 2000000 70
System I/O: KEY? 985 80000 12312
Total: 1188 1


This system's application performance using no extensions

Test time including overhead ms times ns (each)
Eratosthenes sieve 1899 Primes 78 8190000 9
Fibonacci recursion ( 35 -> 9227465 ) 141 9227430 15
Hoare's quick sort (reverse order) 109 2000000 54
Generate random numbers (1024 kb array) 110 262144 419
LZ77 Comp. (400 kb Random Data Mem>Mem) 140 1
Dhrystone (integer)EXCEPTION! CODE:C0000005 ADDRESS:00552E12 WORD:CMOVE
USER DATA: 00341E94 THREAD ID: 00000F6C HANDLER: 0012EF84
STACK: (5) 80000001 7C817077 148D12C7 148D1518 0059A781 00000000 [0000001F]
RETURN STACK:
0012EF38 : 00553DC3 MOVE
0012EF3C : 0059A7BD Proc0
0012EF40 : 7FF85EE0
0012EF44 : 7FF85EE0
0012EF48 : 0059A933 Proc0
0012EF4C : 0034868C
0012EF50 : 003487A4
0012EF54 : 00000000
0012EF58 : 00000000
0012EF5C : 00000002
0012EF60 : 00000003
0012EF64 : 00000000
0012EF68 : 00000000
0012EF6C : 0059A9C9 $DHRY$
0012EF70 : 0059AE07 BENCHMARK
0012EF74 : 00567C5B INTERPRET_
0012EF78 : 00567CE2 INTERPRET
0012EF7C : 00568371 TranslateFlow
0012EF80 : 0055516C CATCH
0012EF84 : 0012EFC4
0012EF88 : 0012FFC0
0012EF8C : 0056819B RECEIVE-WITH-XT
0012EF90 : 00347E34
0012EF94 : 00000006
0012EF98 : 00000010
0012EF9C : 00000026
0012EFA0 : 003432E0
0012EFA4 : 00000026
0012EFA8 : 00000000
0012EFAC : 00000000
0012EFB0 : 005681EF RECEIVE-WITH
0012EFB4 : 005683AF INCLUDE-FILE
0012EFB8 : 0000008C
0012EFBC : 00568483 (INCLUDED1)
0012EFC0 : 0055516C CATCH
0012EFC4 : 0012EFE8
0012EFC8 : 0012FFB8
0012EFCC : 00568523 INCLUDED_STD
0012EFD0 : 00000000
0012EFD4 : 0056CB39 Included
0012EFD8 : 00567C5B INTERPRET_
0012EFDC : 00567CE2 INTERPRET
0012EFE0 : 00567F09 MAIN1
0012EFE4 : 0055516C CATCH
0012EFE8 : 0012EFF8
0012EFEC : 0012FFC0
0012EFF0 : 00567F59 QUIT
0012EFF4 : 0055516C CATCH
0012EFF8 : 00000000
0012EFFC : 0012FFC0
0012F000 : 0056B07D ERR-EXIT
0012F004 : 0056BC66 (INIT)
END OF EXCEPTION REPORT
Exception #-1073741819 at: samples/bench/benchmark.f:1454:9:
BENCHMARK
^ 0xC0000005L ACCESS_VIOLATION
-- ---------------------------------------------------------------------------

Apparently nobody has run this example ever.

I tried floating point. Apparently one needs to load float.f. The FPU
stack is used, which rules out recursion etc.. Fast but impractical, but
maybe there's a better implementation that I couldn't find.

Eventually I set up the following ini file:

\ spf4.ini

WARNING 0!

REQUIRE QuickSWL ~pinka\spf\quick-swl3.f
REQUIRE HELP lib\ext\help.f
STARTLOG

S" lib/include/ansi.f" INCLUDED
S" lib/ext/locals.f" INCLUDED
S" lib/ext/caseins.f" INCLUDED
S" lib/ext/disasm.f" INCLUDED
S" lib/include/float.f" INCLUDED

-1 WARNING !

I didn't dare generate the true windows executable that one has to
compile one-self, sorry.

Let's just say that SP-Forth has the potential to become a very useful
Forth, but at the moment it is wishful thinking to hope it can be
interchangeably used with other ANS Forths.

That left PFE. It currently uses a compression algorithm I can't handle,
so I must accept your judgement that it is unusable also. Looking
at its sourceforge page it does seem that guidod is very actively
maintaining it: 2009-10-17 release 0.33.71 with many albeit minor
cleanup changelog items. Strange that he wouldn't react to real bug
reports.

> but it can be
> surprisingly difficult to get a Forth program to run on many different
> systems, even though they all claim to be standard.

It wasn't clear to me that you meant free systems.

>> It would be more constructive to be specific here (which Forth, which
>> feature).

> That seems irrelevant to me: the point is that, depending on what you're
> doing, you can't just pick up a free system and expect it to run your
> programs correctly. Also I have (I think) reported all of these to the
> maintainers of the systems in question, so it didn't occur to me to
> mention them again.

OK, apparently the free systems situation is worse than I thought.

> The systems I have tried so far which claim some standard-compliance are
> 4p, FICL, gforth, PFE, pforth, and SP-Forth.

"Some" is not enough for your specific purpose. Most free systems seem
to be quite keen on stressing deliberate ANS unfriendliness / deviations.

> I haven't really tried
> ciforth yet, and since I don't have a Windows machine, I have only tried
> Win32Forth briefly under Wine. I think those are all the serious free
> standard systems that I know of. If you know of other such systems
> which run under Linux (x86 and preferably PPC as well), I'd be glad to
> hear of them.

Win32Forth was very good last time I tried it. It is tied to windows,
but it can be used without noticing that at all (apart from not running
on Linux or OSX). ciforth is rock stable but doesn't do floating-point
and AFAIK doesn't interface to system libraries.

> I thought I had a list of bugs somewhere, but I can't find it. So
> here's a list off the top of my head:

[..]

See my additions above.

> That's all I can think of right now...

-marcel

Rod Pemberton

unread,
Dec 28, 2009, 3:47:55 AM12/28/09
to
"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
news:2009Dec2...@mips.complang.tuwien.ac.at...

> Aleksej Saushev <as...@inbox.ru> writes:
> >
> >I don't use any language features outside C89 standard let alone
extensions.
>
> Either you write only toy programs in C, or (more likely) you use
> language features that you don't know to be outside of C89.
>

Anton,

Your comments on FORTH are respected. But, your comments on C come across
as being ludicrous.

While the OP may only write "toy programs", that's a personal or
professional issue.

IMO, even primitive subsets of C can be used to code almost everything.
I've seen applications for Small C, a very restricted subset of C. I've
also seen the applications for the early PDP-11 version of C (available
online). You can't even call that version of C: C. It's proto-C, if that.
It's really primitive. Yet, the entire Unix operating system was re-coded
using it.

Also, as P.J. Plauger - a member of the C standards committees -
demonstrated in his 1991 book: "The Standard C Library", the *entire* C89 C
library can be written in the C89 version of the C language with *only* 18
operating system calls. I.e., everything you can do in C with the C
libraries, you can do in C without the C libraries, but using your own
routines and a few calls to the OS.

http://en.wikipedia.org/wiki/P_J_Plauger


Rod Pemberton


Albert van der Horst

unread,
Dec 27, 2009, 2:24:39 PM12/27/09
to
In article <11n5tclys43bi.1...@40tude.net>,

Coos Haak <chf...@hccnet.nl> wrote:
>Op Sun, 27 Dec 2009 00:51:03 GMT schreef Josh Grams:
>
><snip>
>> PFE:
>.
>.
>> * ORDER shows <???> for every wordlist created by `WORDLIST`, so unless
>> you use PFE's `VOCABULARY` word, you can't tell them apart.
>How could Forth tell its name? WORDLISTs are anonymous items.
>Perhaps a number could be helpful, I let ORDER display {NoName}

How about printing the actual WID? Having a couple of wordlists
all printed like {NoName} does nothing to identify them.
That is exactly what Josh is complaining about.

>
>--
>Coos

Anton Ertl

unread,
Dec 28, 2009, 8:53:24 AM12/28/09
to
"Rod Pemberton" <do_no...@nohavenot.cmm> writes:
>"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
>news:2009Dec2...@mips.complang.tuwien.ac.at...
>> Aleksej Saushev <as...@inbox.ru> writes:
>> >
>> >I don't use any language features outside C89 standard let alone
>extensions.
>>
>> Either you write only toy programs in C, or (more likely) you use
>> language features that you don't know to be outside of C89.
...

>IMO, even primitive subsets of C can be used to code almost everything.
>I've seen applications for Small C, a very restricted subset of C.

Sure, why not? However, the subset of C implemented in Small C is
quite different from the subset of C standardized in C89 and C99.

One important difference is that, if you use a feature outside Small C
(or PDP-11 C), you will notice it when you try to compile and run it,
whereas you have no way to know it when you have stepped outside the
confines of C89 or C99. Even compilers like gcc that have been
maintained by standard C bigots for several years will accept
non-standard programs without complaint in one version and may fail on
such programs in the next version (and of course your bug report on
that will be rejected because the program is non-standard).

One way to detect non-standard features in your C code is to post the
code in comp.lang.c and ask a question about it. You will likely get
at least one answer that tells you that your code is non-standard and
discussion of this code is off-topic there; of course, if you don't
get such an answer, that's still no proof that your code is standard
C; it could be that nobody was interested in it, or that they missed
some non-standard practice.

The Forth standard has a similar problem, but fortunately, the Forth
implementors and the comp.lang.forth regulars don't practice standards
bigotry, at least not to the same extent. Forth programmers relying
on return-address manipulations may disagree, though.

>Also, as P.J. Plauger - a member of the C standards committees -
>demonstrated in his 1991 book: "The Standard C Library", the *entire* C89 C
>library can be written in the C89 version of the C language with *only* 18
>operating system calls. I.e., everything you can do in C with the C
>libraries, you can do in C without the C libraries, but using your own
>routines and a few calls to the OS.

Would his 1991 book be up to the standards of the standards bigots
occupying comp.lang.c nowadays? I doubt it. I especially doubt that
he or anyone else can implement setjmp()/longjmp() in C89 without
setjmp()/longjmp(); and these are typically pure user-level calls and
the system calls available in popular OSs won't help with that.

Jerry Avins

unread,
Dec 28, 2009, 11:48:17 AM12/28/09
to

And it must be no surprise that you can do it all in assembler, too. So?

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

Elizabeth D Rather

unread,
Dec 28, 2009, 12:47:23 PM12/28/09
to
Rod Pemberton wrote:
> "Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
> news:2009Dec2...@mips.complang.tuwien.ac.at...
>> Aleksej Saushev <as...@inbox.ru> writes:
>>> I don't use any language features outside C89 standard let alone
> extensions.
>> Either you write only toy programs in C, or (more likely) you use
>> language features that you don't know to be outside of C89.
>>
>
> Anton,
>
> Your comments on FORTH are respected. But, your comments on C come across
> as being ludicrous.
>
> While the OP may only write "toy programs", that's a personal or
> professional issue.
>
> IMO, even primitive subsets of C can be used to code almost everything.
> I've seen applications for Small C, a very restricted subset of C. I've
> also seen the applications for the early PDP-11 version of C (available
> online). You can't even call that version of C: C. It's proto-C, if that.
> It's really primitive. Yet, the entire Unix operating system was re-coded
> using it.

The context was that Aleksej said that nothing worthwhile could be coded
in small versions of Forth. Of course, that remark is equally absurd.
The entire control system for NRAO's 36' radio telescope was written in
early 70's Forth (including highly accurate telescope control, dome
control, data acquisition, and sophisticated graphical data analysis),
running on one 16Kbyte computer and one 24Kbyte computer, joined by a
1-bit line, whose mass storage was mag tape.

It really isn't useful to deprecate any version of any language without
pretty serious proof!

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

Marcel Hendrix

unread,
Dec 28, 2009, 12:50:15 PM12/28/09
to
Elizabeth D Rather <era...@forth.com> writes Re: Small, understandable Forth

> Rod Pemberton wrote:
>> "Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
>> news:2009Dec2...@mips.complang.tuwien.ac.at...
>>> Aleksej Saushev <as...@inbox.ru> writes:
>>>> I don't use any language features outside C89 standard let alone extensions.
>>> Either you write only toy programs in C, or (more likely) you use
>>> language features that you don't know to be outside of C89.

[..]


> The context was that Aleksej said that nothing worthwhile could be coded
> in small versions of Forth.

No, the issue is that he claims he can write completely portable, significant,
programs in C89. Anton's statement is that you can't write significant programs
that are completely portable (in C89).

[..]

> The entire control system for NRAO's 36' radio telescope was written in
> early 70's Forth (including highly accurate telescope control, dome
> control, data acquisition, and sophisticated graphical data analysis),
> running on one 16Kbyte computer and one 24Kbyte computer, joined by a
> 1-bit line, whose mass storage was mag tape.

From this description it is absolutely clear that it was not a portable
Forth program. And why should it?

The minimum size of a useful program or the minimum computing power of
a useful gadget is probably very near zero and ought not be the subject
of a serious discussion. IMHO you will not find any portability near the
limits.

[..]

-marcel

Anton Ertl

unread,
Dec 28, 2009, 2:06:18 PM12/28/09
to
m...@iae.nl (Marcel Hendrix) writes:
>No, the issue is that he claims he can write completely portable, significant,
>programs in C89. Anton's statement is that you can't write significant programs
>that are completely portable (in C89).

Not quite. He wrote that he does, and I wrote that I don't think that
he does.

It may be possible for someone who knows all of the holes of the C
standard by heart to write a significant program that is actually
standard-conformant, but I think that very few people do it, even if
they think they do; and even a C standards bigot might forget about a
particular hole, and unwittingly write a non-standard program, and
there is usually no way to notice that.

Bruce McFarling

unread,
Dec 28, 2009, 4:45:57 PM12/28/09
to
On Dec 26, 7:51 pm, Josh Grams <j...@qualdan.com> wrote:
> 4p, FICL, gforth, PFE, pforth, and SP-Forth.  I haven't really tried
> ciforth yet, and since I don't have a Windows machine, I have only tried
> Win32Forth briefly under Wine.  I think those are all the serious free
> standard systems that I know of.  If you know of other such systems
> which run under Linux (x86 and preferably PPC as well), I'd be glad to
> hear of them.

Apropos of the original thread, it would be useful is Camel and hForth
were vetted for Forth-94 compliance for the wordsets they implement -
it may be easier to build up from a small base that is compliant than
to dive into a larger base that is non-compliant in subtle ways or
just due to buggy implementations.

Note that ciforth does not claim Forth-94 compliance. In particular,
it does not have a REFILL that can be used inside a file being
INCLUDED, >IN is only partly emulated with a read-only value, and the
Forth-94 reserved THROW code space is allocated to system error codes
instead.

The latter seems like it could be patched over with a prelude that
wraps a throw code translation for the reserved codes, AFAIR -1 to -4K
around the system THROW and CATCH.

The former is what I ran up against. I still haven't worked out
whether to write around it word by word or try to get a line by line
file reading overlay on top of the file at a time ciforth approach.

Ed

unread,
Dec 29, 2009, 2:50:23 AM12/29/09
to
Albert van der Horst wrote:
> In article <11n5tclys43bi.1...@40tude.net>,
> Coos Haak <chf...@hccnet.nl> wrote:
> >Op Sun, 27 Dec 2009 00:51:03 GMT schreef Josh Grams:
> >
> ><snip>
> >> PFE:
> >.
> >.
> >> * ORDER shows <???> for every wordlist created by `WORDLIST`, so unless
> >> you use PFE's `VOCABULARY` word, you can't tell them apart.
> >How could Forth tell its name? WORDLISTs are anonymous items.
> >Perhaps a number could be helpful, I let ORDER display {NoName}
>
> How about printing the actual WID? Having a couple of wordlists
> all printed like {NoName} does nothing to identify them.
> That is exactly what Josh is complaining about.

Certainly, but it's at the discretion of the implementor.

'94 defined ORDER very loosely. It doesn't say that wordlists must
be displayed via wids. Many forths had (still have) VOCABULARY
so it makes sense they might want to display wordlists via names.
Others might not have a choice.

It really doesn't matter what ORDER displays since one can't use
it programmatically anyway. It's a tool, like WORDS. Whether
what it displays is useful - is for the user to decide :)


idknow

unread,
Dec 29, 2009, 8:33:01 AM12/29/09
to
On Dec 24, 6:56 pm, Aleksej Saushev <a...@inbox.ru> wrote:
> deech <aditya.si...@gmail.com> writes:
> > I am a long time reader, but first time poster. I have been fascinated
> > by Forth since I read JonesForth [1]. I was wondering if there are

> > other small, understandable Forth implementations, perhaps ones that
> > are being used for real work. I am looking into making my own small
> > Forth and want to compare/contrast different implementations.
> > Something like GForth [2]  is too big!
>
> You don't use small implementation for real work.
> Even gforth, the one you call "too big", is underpowered.
>
> --
> HE CE3OH...

Hello again folks; Hi Aleksej:

How and Why is gforth *under-powered*?

Albert van der Horst

unread,
Dec 29, 2009, 8:41:08 AM12/29/09
to
In article <3ce0bb19-6a0a-4c32...@p8g2000yqb.googlegroups.com>,
Bruce McFarling <agi...@netscape.net> wrote:
<SNIP>

>
>Apropos of the original thread, it would be useful is Camel and hForth
>were vetted for Forth-94 compliance for the wordsets they implement -
>it may be easier to build up from a small base that is compliant than
>to dive into a larger base that is non-compliant in subtle ways or
>just due to buggy implementations.
>
>Note that ciforth does not claim Forth-94 compliance. In particular,
>it does not have a REFILL that can be used inside a file being
>INCLUDED, >IN is only partly emulated with a read-only value, and the
>Forth-94 reserved THROW code space is allocated to system error codes
>instead.
>
>The latter seems like it could be patched over with a prelude that
>wraps a throw code translation for the reserved codes, AFAIR -1 to -4K
>around the system THROW and CATCH.
>
>The former is what I ran up against. I still haven't worked out
>whether to write around it word by word or try to get a line by line
>file reading overlay on top of the file at a time ciforth approach.

What you didn't mention are the DO LOOP anomalies:
`` : test $FFFF,FFFF,FFFF,FFFF 0 DO I C@ . LOOP ; ''
only prints 0, not the whole memory of a 64-bit machine.
Also I never invested the time to comply fully with the documentation
requirements.

Apropos REFILL:
`` : REFILL -1 ; '' should go a long way.
`` : REFILL 1001 THROW ; '' is also a possibility, because REFILL
just never should be called, if all files and blocks are in memory.

Apropos THROW:
You'd have to use a translation table.
I hate error information going lost. So several ciforth errors map
to the same ANSI codes.
Instead of a wrapper, you would be better off with a patch.
Something along

``
REQUIRE OLD:
: NEW-THROW CELLS TABLE + @ OLD: THROW ;
'NEW-THROW 'THROW 3 CELLS MOVE // THROW use by old system
: THROW OLD: THROW ; // This is to be used by new code.
''

Apropos >IN:
``
I'm thinking about a writable >IN.
Instead of `` 0 >IN ! '' you would have to use a
special word to get the interpreter pointer back to the
start of a line.
: 0>IN! SRC ^J $\ DROP >R 2DROP R> >IN ! ;

''

Disclaimer: the code is just an indication of what is needed, and not
tested.

Version 4.0.6 was released in 2005. 1] Since then there has never been
a complaint, problem report or whatever, stimulating me to add
a -p (pedantic) option. You're the first to come up with a stimulating
remark in that direction.

Groetjes Albert

1] Yes, lina *is* actively maintained. There just are no bug reports.

Josh Grams

unread,
Dec 29, 2009, 9:20:40 AM12/29/09
to
Marcel Hendrix wrote: <0482322...@frunobulax.edu>

> Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth
>> Marcel Hendrix wrote: <2623082...@frunobulax.edu>
>>> Josh Grams <jo...@qualdan.com> writes Re: Small, understandable Forth
> [..]
>
> Next I downloaded SP-Forth.

>
> There is indeed (per your notes) something wrong with ENVIRONMENT?
>
> S" BLOCK" ENVIRONMENT?
> S" BLOCK ENVIRONMENT?
> ^ -35 Illegal block number
>
> This is a well-known problem, some of the environment queries overlap
> regular Forth names.

And of course ANS 3.2.6 Environmental Queries says they shouldn't:

"The name spaces for `ENVIRONMENT?` and definitions are disjoint. Names of
definitions that are the same as ENVIRONMENT? strings shall not impair the
operation of `ENVIRONMENT?`."


> That left PFE. It currently uses a compression algorithm I can't handle,
> so I must accept your judgement that it is unusable also. Looking
> at its sourceforge page it does seem that guidod is very actively
> maintaining it: 2009-10-17 release 0.33.71 with many albeit minor
> cleanup changelog items. Strange that he wouldn't react to real bug
> reports.

Guido is actually about as good as any open source author about
responding to bug reports; probably better than most.

You should maybe not take my complaints about PFE too seriously: I have
run across several people who seem to be using it quite happily. But
somehow I always wind up fighting with it. :( I just feel like every
time I use it, I run across some oddity that makes me question the
quality of the implementation. And since it has been around for a
while, and seems to have an actual user base, and the first design
objective on its web page is to be a "correct" implementation, I was
really hoping for better things from it.

>> The systems I have tried so far which claim some standard-compliance are
>> 4p, FICL, gforth, PFE, pforth, and SP-Forth.
>
> "Some" is not enough for your specific purpose. Most free systems seem
> to be quite keen on stressing deliberate ANS unfriendliness / deviations.

Yeah, "some" was for 4p. AFAIK the rest claim to be ANS compliant.

----

Anyway, sorry to be a killjoy. I realize they're free software, and you
get what you pay for and all that. And often none of this is a problem.
You can get a long way with them in spite of their limitations. But
some days... I've dug around inside 15 or 20 Forth systems, and most of
them aren't all that pretty. I keep wondering if I couldn't do better.
Must resist the temptation...

--Josh

Bruce McFarling

unread,
Dec 29, 2009, 4:50:33 PM12/29/09
to
On Dec 29, 8:41 am, Albert van der Horst <alb...@spenarnc.xs4all.nl>
wrote:

> Apropos REFILL:
>         `` : REFILL -1 ; '' should go a long way.
>         `` : REFILL 1001 THROW ;  '' is also a possibility, because REFILL
>         just never should be called, if all files and blocks are in memory.

Forth-94 allows multi-line comments in an INCLUDED file to use REFILL
as part of a process of a multi-line comment word scanning for a
ending line. Obviously a non-Forth-94 SOURCE >IN and REFILL requires
rewriting that process.

A portable script cannot possibly *know* that all files and blocks are
in memory in the system that it is executed on.

As I alluded to, one option is an implementation of Forth-94 SOURCE
REFILL and >IN on top of ciforth, which should be possible, after all,
with the whole file in memory, though one would have to take care to
take those words out of scope before loading any ciforth library
files. The other is to write a ciforth specific version of those
words, since the base script makes heavy use of [UNDEFINED] and
[DEFINED] conditional compilation.

I don't have any spanning DO-LOOPs - indeed, I likely have more ?DO-
LOOPs than DO-LOOPs.

Looking at my uses of >IN, what I've used it for is to save the input
state for standard words like CREATE that do not have a standard non-
parsing factor, so in a word, ``[]Extend:'', that executes a
vocabulary when it exists and creates the vocabulary when it doesn't,
I have to re-use the token if it is not found. If SAVE-INPUT and
RESTORE-INPUT work correctly, I can define ciforth-specific versions
of those words in a ciforth prelude file.

> Instead of a wrapper, you would be better off with a patch.

The advantage of the wrapper is that it turns on and off in the
desired way as []Niclos[] goes into and out of scope.

Ed

unread,
Dec 30, 2009, 4:47:20 PM12/30/09
to
Josh Grams wrote:
> ...

> Anyway, sorry to be a killjoy. I realize they're free software, and you
> get what you pay for and all that. And often none of this is a problem.
> You can get a long way with them in spite of their limitations. But
> some days... I've dug around inside 15 or 20 Forth systems, and most of
> them aren't all that pretty. I keep wondering if I couldn't do better.
> Must resist the temptation...

Yes. Those who build their own forth rarely get back to writing apps
or doing anything useful. It may explain why there's such a scarcity
of forth software and yet so many experts :)


Sp...@controlq.com

unread,
Dec 30, 2009, 5:59:39 PM12/30/09
to
On Thu, 31 Dec 2009, Ed wrote:

> Date: Thu, 31 Dec 2009 08:47:20 +1100
> From: Ed <nos...@invalid.com>
> Newsgroups: comp.lang.forth
> Subject: Re: Small, understandable Forth

Oh, I don't know. I've written at least 2 C based forth interpreters, and
ported them to numerous operating systems (DOS, MPEV, MPEXL, HPUX, SunOS,
Solaris, Windows (95,XP, 2003 and 7), Linux, BSD), and implemented the
same language on 8, 16, 32 and 64 bit architectures since 1988.

I've also done a few *REAL* things with Forth (and other languages) since
as well. My interpreter is FIG like, isn't cross compiled, isn't as
optimized as some of the commercial apps, but it does port nicely,
performs adequately (comparable to any current scripting language), and is
dirt simple to migrate to any hosted operating system. The latest version
does not even require libc, and could in theory be re-hosted onto bare
iron, and I plan to get to this as soon as time permits ... sigh ...

-- RSS-Forth version 202 Copyright Control-Q Research 1988-2009. --
ok words
>> << and xor or until repeat while == != <= >= > < then else if again
begin wheel reset leave k j i loop (loop) ?branch branch do (do) cells
cellsize see .s .us unresolved vm align hold #> #S # <# count octal
decimal hex ' nfa cfa dp lfa pfa flg state base rp r0 sp s0 tib pad d0
here , c, \ ." " <resolve <mark >resolve >mark (quote) ( .( word words c!
c@ ! @ create does> 1- 1+ 0= 0< 0> - + * */mod */ /mod / mod . u. type cr
space spaces key emit prompt dup ?dup drop swap over depth newword version
.version literal interpret (literal) ; : (colon) execute find bye quit ok
ok : x 0 begin 1+ dup 0 < if leave then again ;
ok ' x see
: x
34370237440 (literal) 0
34370237456 1+
34370237464 dup
34370237472 (literal) 0
34370237488 <
34370237496 ?branch 34370237520
34370237512 leave
34370237520 branch 34370237456
34370237536 0
ok cellsize .
8 ok bye
-- RSS-Forth version 202 Normal User Termination. --

The bottom line is, I would not dissuade people from creating their own
pet forth's. Approached correctly, there are many learning opportunities
and a lot of fun re-discovering the original thought processes.

Professional programmers will generally tend toward rich application
environments, and the commercial providers. Hobbyist types could do far
worse than learning from the iron up by rolling their own, at least one
time ... and THEN spending the time to learn the language ... if only
because the Forth concept of FACTORING is so relevant to EVERY programming
language ...

Cheers,
Rob Sciuk

Josh Grams

unread,
Dec 31, 2009, 7:22:23 PM12/31/09
to
Ed wrote: <hhghmd$96q$1...@news-01.bur.connect.com.au>

Yeah, I was stuck in that phase for three or four years when I first
discovered Forth. I must have put together 7 or 8 toy Forth systems of
various designs, besides digging through the sources of any systems that
I ran across. I still tinker with that sort of thing sometimes. But at
least I don't still try to pretend it's useful. :)

OTOH, there is a niche I'd love to see filled... If I write (for
instance) in Python, I can hand my code to even relatively non-technical
people, and they are usually able to grab Python and the necessary
modules and run my program on whatever computer they have handy. I'm
not aware of any free Forth system that lets me do that reliably and
easily. But it's not important enough to dedicate all my spare time to
it for the couple of years it would probably take. Well, not so far,
anyway. :)

I have gotten to the point where I can throw together Forth scripts to
do one-off tasks pretty comfortably. I have even started using it
occasionally for string-handling tasks which would previously have found
me turning to Perl without a second thought. But it still seems like
any time I try to write any kind of desktop application, I immediately
wind up buried in trivial boilerplate (binding to libraries, figuring
out argument order, re-implementing basic data structures to fit the
application, etc.) and burn out before I get to the interesting bits.

--Josh

Elizabeth D Rather

unread,
Dec 31, 2009, 8:33:28 PM12/31/09
to

You didn't write that Python, did you?

That is what Forth94 addressed, fairly successfully. The problem is
that writers of "toy Forths" tend not to follow the Standard, either
accidentally or deliberately. Depending on what kinds of programs you
write, a lot of things can be easily ported between well-tested,
standard Forths. For example, the Intellasys compiler ran on both
gForth and SwiftForth. Forth 200x has added standard features that
should address even more portability issues.

> I have gotten to the point where I can throw together Forth scripts to
> do one-off tasks pretty comfortably. I have even started using it
> occasionally for string-handling tasks which would previously have found
> me turning to Perl without a second thought. But it still seems like
> any time I try to write any kind of desktop application, I immediately
> wind up buried in trivial boilerplate (binding to libraries, figuring
> out argument order, re-implementing basic data structures to fit the
> application, etc.) and burn out before I get to the interesting bits.

Again, most of the standard systems, both free and commercial, have
already addressed most of those issues. This is the difference between
DIY and using off-the-shelf systems.

Cheers,

Bernd Paysan

unread,
Dec 31, 2009, 8:53:35 PM12/31/09
to
Elizabeth D Rather wrote:
> For example, the Intellasys compiler ran on both
> gForth and SwiftForth.

Bad example with Dennis Ruffer just posting horrible parts of that ;-).
And I still don't know if it can be made work on 64 bit Gforth
(something the '94 standard really solved, but when the programmer only
tests on 32 bits, it's unlikely to really work).

Porting code between complex Forth systems does not really tell us how
good the standard is. I ported MINOS over from bigForth to VFX, and it
uses a lot of carnal knowledge and non-standard extensions on either
side. VFX needed some crucial features to be added and bugs to be
fixed, as well as MINOS itself needed quite some cleanup. Porting
benefits both the program that is ported and the system it is ported to.

This sort of exercise allows us to determine what's lacking from the
standard, and we should solve the problems in the long run. Some are
quite tricky, as the external C interface shows (bigForth and VFX use
both a very similar approach, which is feasible, since both are x86
only).

Bruce McFarling

unread,
Jan 1, 2010, 12:13:46 AM1/1/10
to
On Dec 31, 8:53 pm, Bernd Paysan <bernd.pay...@gmx.de> wrote:
> This sort of exercise allows us to determine what's lacking from the
> standard, and we should solve the problems in the long run. Some are
> quite tricky, as the external C interface shows (bigForth and VFX use
> both a very similar approach, which is feasible, since both are x86
> only).

Playing around with the buggy BMW (Bruce McFarling's Writer) wrapper
around Leo Wong's LF.F
... http://www.complang.tuwien.ac.at/forth/programs/bmw008.zip ...
and compiling it on SwiftForth, gforth and hforth for DOS and trying
to compile it on lina for Linux is where I came up with my list of
seven gaps in Forth-94 support for portable applets some years back.
Three of them have been addressed by the Forth200x process, one is
live in the Forth200x process, one is something that seems like it can
be handled at the library level, and I've dropped two of the seven
from my list as things that can definitely be handled at the library
level.

The three handled by Forth200x are:

(1) DEFER - Forth200x.
http://www.forth200x.org/deferred.html

"(4) [UNDEFINED] [DEFINED] ... if these are bootstrapped, it
effectively means pushing the test into the optionally-compiled file
rather than having it in the calling file, which creates unecessary
reads of files that need not be called at all." Forth200x
http://www.forth200x.org/defined.html

"(7) Providing additional support to allow EKEY to be actually used
for cross-platform code with just a check using [UNDEFINED] to see
whether a key is defined or has to be emulated." Forth200x.
http://www.forth200x.org/ekeys.html

The one proposed but not yet accepted in the Forth200x process is:
"(2) Relative subdirectory support that works when a file is being
INCLUDED."
Forth200x RfD on ``F"'', has not yet reached the call for vote
stage, but the name could be used as Comus.
http://www.forth200x.org/directories.html

Given ``F"'', a tool library hierarchy can be bootstrapped with a pair
of scripts at the top of the library hierarchy. One script is called
with the desired target and executes F" in the context of the library
hierarchy to get the host filename, with the other bootstrapping the
first by using ``F"'' to compile the location of the second into the
dictionary. The system specific prelude simply includes the second to
install access to the library hierarchy.

=================
The one that I've penciled in for handling at the library stage is:

"(6) OCTET ( fam1 -- fam2 ) for access to files defined in terms of
byte-oriented standards ... with bytes mapped to CHARS on reading and
[the result of] writing CHARS wider than eight bits [into the buffer
for writing to a file] an ambiguous condition (note that this mapping
is automatic with BLOCKS in systems with chars wider than 8 bits)."

Since CHARS are at at least a byte wide, and with BYTE-PACK and BYTE-
UNPACK as aliases for MOVE in au=byte=char systems, BYTE-PACK and BYTE-
UNPACK can be written in a system-specific prelude using whatever is
the system facility for handling bytes in au<>byte and byte<>char
systems.
BYTE-PACK ( c-addr byte-addr u -- )
BYTE-UNPACK ( byte-addr c-addr u -- )

The OCTET file access method mapping bytes to chars in FILE words
allows model-neutral access to most byte-oriented files/packets with
very little effort on the part of the person doing the port.

However, with an explicit file definition, it should be possible to
access the file in binary mode using a ``CHUNK'', the number of
address units that is an integral multiple of bytes, chars and cells.
Programming in conventional systems this is 2 or 4, and enforces
algorithms for grabbing data in small discrete units, and testing on
both 16-bit and 32-bit implementations catches failures to abstract
properly.

Working in a stream of chunks always allows binary data seen as a
compact unbroken stream of chars to be retrieved as a compact unbroken
stream of bytes, except for a possible partial chunk at the end (which
only implies a little extra padding when a buffer for BYTE-UNPACK is
defined as a number of CHUNKs).

Given that byte=char=au is so common, and no single low-level byte
access wordset is equally efficient in all byte<>char and byte<>au
cases, it seems that OCTETS are best addressed by first developing
libraries that work on byte-defined files for 16 bit byte=au=char, 32
bit byte=au=char and 32 bit 2byte=2au=1char systems and proving the
concept that BYTE-PACK BYTE-UNPACK and chunk handling is sufficient.

====================
The two that I've dropped from the list are:

"(5) REQUIRE ... because the library oversight system needs to know
precisely what semantics can be expected of this word. There are also
benefits to implementors knowing exactly what the portable semantics
are, so that they can work out the most effective way of dividing the
labor between the portable word and the specific approach to source
code and wordset management taken by the implementation."
It turns out that I've been able to write REQUIRE out of the naive
incrementally compiled library oversight system I was experimenting
with earlier by defining conditional compilation test words that work
in the scope of the library oversight vocabulary. This pushes the
intelligence from the word to the script.

"(3) BLOCKS-ALLOT ( u -- block# u ior ) so I can use Blocks in an
application without requiring the user to dictate the block range to
be available for each specific application (note that in the default
definition of BLOCKS-ALLOT, it is perfectly acceptable for the user to
be polled for the range of blocks to be made available in this way ...
that's a one-time set up rather than an every-time set-up). Matched by
BLOCKS-FREE ( block# u -- ior )."

I've work out semantics for this capability that can be
bootstrapped in any Forth-94 system providing the Block wordset (and
of course if a Block wordset is not provided, it can be compiled on
any Forth-94 system providing the FILE wordset) - the key is that
information on free blocks only need to be retained when there are
freed blocks available for use, so one or more of the free blocks can
be used to retain that information ... a variable holding the pointer
to the current freed block record block can just be nul when all
available work blocks have been allocated.

So as a bootstrap, a portable script can determine whether the
words are available, include portable definitions if they are not,
then determine if there are enough free blocks available, and in the
last recourse as the user where in the block system there are enough
blocks free, and free those blocks to get started. If anything, easier
done than said.

============

So all up, the gaps that I found are either closed by the Forth200x
process, or have at least had a public name and semantics proposed
that can close the gap, or seem like they can be closed at the library
level.

Josh Grams

unread,
Jan 1, 2010, 8:31:31 AM1/1/10
to
Elizabeth D Rather wrote:
> On 12/31/09 2:22 PM, Josh Grams wrote:
>> There is a niche I'd love to see filled... If I write (for instance)

>> in Python, I can hand my code to even relatively non-technical
>> people, and they are usually able to grab Python and the necessary
>> modules and run my program on whatever computer they have handy. I'm
>> not aware of any free Forth system that lets me do that reliably and
>> easily. But it's not important enough to dedicate all my spare time
>> to it for the couple of years it would probably take. Well, not so
>> far, anyway. :)
>
> You didn't write that Python, did you?
>
> That is what Forth94 addressed, fairly successfully. The problem is
> that writers of "toy Forths" tend not to follow the Standard, either
> accidentally or deliberately. Depending on what kinds of programs you
> write, a lot of things can be easily ported between well-tested,
> standard Forths. For example, the Intellasys compiler ran on both
> gForth and SwiftForth. Forth 200x has added standard features that
> should address even more portability issues.

Yes, I know, but that's a totally different issue. I don't want "easily
ported", I want "write once, run anywhere" (for values of "anywhere"
which include at least Windows, OSX, and various Linuxes). I assume
that, if this ever becomes possible, it will be in the form of one Forth
system which has been ported to many different places. But I suppose it
could also happen through different Forth systems becoming more
compatible.

Either way, it's not a huge deal; there are plenty of other languages I
can use for that sort of project. But Forth might be more fun. :)

And I'm not sure why you assume that I'm talking only about toy Forths:
I originally jumped into this thread to claim that none of the free
Forth systems which run on my machine (with the exception of gforth) are
actually fully standard.

>> I have gotten to the point where I can throw together Forth scripts
>> to do one-off tasks pretty comfortably. I have even started using it
>> occasionally for string-handling tasks which would previously have
>> found me turning to Perl without a second thought. But it still
>> seems like any time I try to write any kind of desktop application, I
>> immediately wind up buried in trivial boilerplate (binding to
>> libraries, figuring out argument order, re-implementing basic data
>> structures to fit the application, etc.) and burn out before I get to
>> the interesting bits.
>
> Again, most of the standard systems, both free and commercial, have
> already addressed most of those issues. This is the difference
> between DIY and using off-the-shelf systems.

Er. No, how could they? :) Having to write my own bindings to external
libraries is an artifact of how few people are publishing desktop
applications in Forth source form. And the rest are presumably a lack
of skill on my part. In other languages I can usually sketch in a
program to get a working skeleton with basic functionality, and refine
the interfaces and data structures as I flesh it out. But in Forth
those sort of changes seem to ripple through the code a lot farther. I
think I am getting better at writing modular Forth code, but it's slow
going.

--Josh

Josh Grams

unread,
Jan 1, 2010, 8:47:24 AM1/1/10
to
Bruce McFarling wrote:
> The one proposed but not yet accepted in the Forth200x process is:
> "(2) Relative subdirectory support that works when a file is being
> INCLUDED."
> Forth200x RfD on ``F"'', has not yet reached the call for vote
> stage, but the name could be used as Comus.
> http://www.forth200x.org/directories.html
>
> Given ``F"'', a tool library hierarchy can be bootstrapped with a pair
> of scripts at the top of the library hierarchy. One script is called
> with the desired target and executes F" in the context of the library
> hierarchy to get the host filename, with the other bootstrapping the
> first by using ``F"'' to compile the location of the second into the
> dictionary. The system specific prelude simply includes the second to
> install access to the library hierarchy.

I prefer to just have paths to INCLUDED and company default to being
relative to the directory containing the current source file (or search
a system include path if not found). For systems which don't have it,
it's easy enough to build this on top of INCLUDE-FILE. Well, replacing
REQUIRE isn't so easy, but if you don't worry about symlinks you can
still do it fairly portably.


> "(5) REQUIRE ... because the library oversight system needs to know
> precisely what semantics can be expected of this word. There are also
> benefits to implementors knowing exactly what the portable semantics
> are, so that they can work out the most effective way of dividing the
> labor between the portable word and the specific approach to source
> code and wordset management taken by the implementation."
> It turns out that I've been able to write REQUIRE out of the naive
> incrementally compiled library oversight system I was experimenting
> with earlier by defining conditional compilation test words that work
> in the scope of the library oversight vocabulary. This pushes the
> intelligence from the word to the script.

Can I see your code? I have accumulated enough bits of compatibility
code that I decided I need some sort of helper code to load them. I've
been trying to design a Forth package manager that can start out very
simple, but whose design won't impede later extension. So I'd be
curious to see what you have done...

--Josh

Albert van der Horst

unread,
Jan 1, 2010, 9:41:00 AM1/1/10
to
In article <3fb%m.1814$Sk4....@newsfe10.iad>,

Josh Grams <jo...@qualdan.com> wrote:
>Ed wrote: <hhghmd$96q$1...@news-01.bur.connect.com.au>
>> Josh Grams wrote:
>>> ...
>>> Anyway, sorry to be a killjoy. I realize they're free software, and you
>>> get what you pay for and all that. And often none of this is a problem.
>>> You can get a long way with them in spite of their limitations. But
>>> some days... I've dug around inside 15 or 20 Forth systems, and most of
>>> them aren't all that pretty. I keep wondering if I couldn't do better.
>>> Must resist the temptation...
>>
>> Yes. Those who build their own forth rarely get back to writing apps
>> or doing anything useful. It may explain why there's such a scarcity
>> of forth software and yet so many experts :)
>
>Yeah, I was stuck in that phase for three or four years when I first
>discovered Forth. I must have put together 7 or 8 toy Forth systems of
>various designs, besides digging through the sources of any systems that
>I ran across. I still tinker with that sort of thing sometimes. But at
>least I don't still try to pretend it's useful. :)

I design Forth's from a different angle.

We got transputer boards. No we want to do something with it.
A Forth, then factoring (hcc1996) and prime counting (hcc1998).

Renesas donned a small board with the an Elektor magazine.
I wanted to run Forth on it. Then I ordered a better Renesas board,
more powerful. A Forth, then, to proof that the Forth works:
playing the Big Ben melody on the tingel-tangel.

We got a truckload of 6809 computers.
I wanted to run Forth on it. We had Brad Rodriguez Forth running,
a dedicated Forth and then ciforth.
Then to proof that the Forth works: a tamper free code slot
demonstrated on yet another hcc fair. (It senses nails
through a several centimetre block of aluminium.)

Now I'm onto a better Renesas board (also originating from
Elektor). I want to improve on their sine generator that
was their usage example (pretty pathetic, for an electronics
magazine).

Then the original ciforth. Computer Intelligence Forth was intended
to be a totally stand alone system like colorforth, not running
Okad, but exhibiting (some) intelligence.
Somewhere along the way I got distracted...

(We is more or less the Dutch Forth Chapter.)

>
>--Josh

Groetjes Albert

Anton Ertl

unread,
Jan 1, 2010, 10:34:21 AM1/1/10
to
Bernd Paysan <bernd....@gmx.de> writes:
>And I still don't know if it can be made work on 64 bit Gforth
>(something the '94 standard really solved, but when the programmer only
>tests on 32 bits, it's unlikely to really work).

Not in my experience. The typical case is that programs working on
one cell width also work on a different cell width.

And that's not just for my programs, but for others as well: Most of
the appbench programs work on 32-bit and 64-bit Forths from the start,
and AFAIK several of them had not been tested on 64-bit Forths before.
And even Brew, which at first appeared not to work on 64-bit Forths
just gave different results (from different overflow characteristics
or something like that), but worked as it should. Similarly for
Benchgc. Two programs that needed some changes for working on 64-bits
were the chess programs (Brainless and Fcp), but they were relatively
small.

Anton Ertl

unread,
Jan 1, 2010, 10:55:07 AM1/1/10
to
Bruce McFarling <agi...@netscape.net> writes:
>The one proposed but not yet accepted in the Forth200x process is:
>"(2) Relative subdirectory support that works when a file is being
>INCLUDED."

That's pretty much stalled. There is significant resistance to that
and not that much support.

>The two that I've dropped from the list are:
>
>"(5) REQUIRE ... because the library oversight system needs to know
>precisely what semantics can be expected of this word.

REQUIRE is in Forth200x: http://www.forth200x.org/required.html

Do you mean to say that the semantics are not defined sufficiently?
If so, what is lacking?

Bruce McFarling

unread,
Jan 1, 2010, 12:24:33 PM1/1/10
to
On Jan 1, 8:47 am, Josh Grams <j...@qualdan.com> wrote:
> > Given ``F"'', a tool library hierarchy can be bootstrapped with a pair
> > of scripts at the top of the library hierarchy. One script is called
> > with the desired target and executes F" in the context of the library
> > hierarchy to get the host filename, with the other bootstrapping the
> > first by using ``F"'' to compile the location of the second into the
> > dictionary. The system specific prelude simply includes the second to
> > install access to the library hierarchy.

> I prefer to just have paths to INCLUDED and company default to being
> relative to the directory containing the current source file (or search
> a system include path if not found).  For systems which don't have it,
> it's easy enough to build this on top of INCLUDE-FILE.  Well, replacing
> REQUIRE isn't so easy, but if you don't worry about symlinks you can
> still do it fairly portably.

This was discussed when DIRECTORIES went out for three RfD ... the
problem is not for systems that don't have it so much as for systems
that have already different path handling that is assumed by local
files using INCLUDED.

IOW, its not a question of preferred implementation designs, but
rather a question of existing implementation designs.

Implementations that have relative paths by default be relative to the
directory containing the current source file, F" is just a word that
copies the text into a buffer and returns the ( ca u ) for the buffer.
For systems that have a particular prefix specifying loading relative
to the file currently being interpreted (gforth uses ``./'' but others
uses ``./'' for the current working directory), its the same thing
except prepending that prefix.

For systems that do not have it, its likely to be straightforward in
most cases so long as you know which operating system you are working
on, so implementation could well be more a per-OS than a per-
implementation task.

> > "(5) REQUIRE ... because the library oversight system needs to know
> > precisely what semantics can be expected of this word. There are also
> > benefits to implementors knowing exactly what the portable semantics
> > are, so that they can work out the most effective way of dividing the
> > labor between the portable word and the specific approach to source
> > code and wordset management taken by the implementation."
> >    It turns out that I've been able to write REQUIRE out of the naive
> > incrementally compiled library oversight system I was experimenting
> > with earlier by defining conditional compilation test words that work
> > in the scope of the library oversight vocabulary. This pushes the
> > intelligence from the word to the script.

> Can I see your code?  I have accumulated enough bits of compatibility
> code that I decided I need some sort of helper code to load them.  I've
> been trying to design a Forth package manager that can start out very
> simple, but whose design won't impede later extension.  So I'd be
> curious to see what you have done...

Its just building a vocabulary hierarchy from scratch, a registry
vocabulary, and having some words for testing for the existence of
version constants.

This library system is built on the concept of three levels of file -
ordinary forth script files (.fs) assume that the words they use are
available and just compile into the CURRENT vocabulary when they are
called.

Niclos file scripts know about the existence of the []Niclos[]
hierarchy, install themselves, and may export their target public
words to FORTH or to the CURRENT vocabulary at the time they are
called. They may INCLUDE ordinary forth file script files or other
niclos file script files, but only in the directory in which they are
located or the current working directory.

Niclos library scripts (.nls) perform version control and engage in
optional compilation in response to tokens handed to the script in a
dedicated command stack, and also navigate the Niclos file hierarchy
system.

I don't have anything from the .nls level that has been tested yet
(that's why the word to export a version constant into the []Niclos
vocabulary is not below), but here is an unstable alpha of the .nfs
support. Given that the system is to be self-boostrapping, the
foundation for the .nfs level is a .fs file, and the foundation for
the .nls is a .nfs file.

With respect to REQUIRE, by looking into []Niclos to see whether a
toolkit exists, and then into the toolkit to see whether it has the
correct version constants, a .nfs script can see whether a desired
capability is there, providing, for major version, a known set of
words with defined behavior. The primary purpose of the minor version
is to support patching around bugs if there is a known bug that was
not fixed until a later minor version.

The two other parts of the foundation file is the extended block
comments and the dummy THROW. The dummy THROW is just print the THROW
code and ABORT, but allows applications that use CATCH THROW error
handling to use toolkits without restricting those toolkits to systems
with CATCH and THROW available.

\ -[ niclos.fs ]-
ONLY FORTH
BL WORD []Niclos[] FIND NIP [IF]
\ S" nlocal.nfs" INCLUDED
\\ Skip to <eof>

This is Niclos-core.
The definitions below should be found anytime []Niclos[]
is defined. So if it is, we're outta here.
[THEN]

FALSE [IF] ====================
Using CORE, BLOCK, SEARCH
Using from CORE EXT:
\ Part of boot-strapping process
:NONAME FALSE NIP TRUE \

\ eligible for conditional compilation
2>R 2R> ?DO REFILL TO U> VALUE

Using from SEARCH EXT:
ALSO FORTH ONLY

... And now, because the ``---['' word is not yet defined and this
is an IF-THEN scripting block comment, time to get back the
compilation process started.


--[ Core Niclos Structure ]--
======================== [THEN]

\ []Niclos[] Bootstrap - only word exported to FORTH
\ do not assume WORDLIST beyond Forth-94 standard words

ONLY FORTH DEFINITIONS

\ Cannot do colon definition between CREATE and DOES>
:NONAME ( -- )
DOES> @ >R ONLY FORTH GET-ORDER R> SWAP 1+ SET-ORDER ;

WORDLIST CREATE []Niclos[] , EXECUTE

[]Niclos[] DEFINITIONS

\ Version constants
TRUE CONSTANT Niclos01?
0 CONSTANT Niclos01#

\ * runtime action for subvocabularies, Forth-83 model
: {does-vocabulary} ( -- )
DOES> @ >R GET-ORDER NIP R> SWAP SET-ORDER ;

\ Leave exit unlocked
: ONLY ONLY ; : ALSO ALSO ; : FORTH FORTH ;

\ bootstrap [UNDEFINED] and [DEFINED]
\
BL WORD [UNDEFINED] FIND NIP 0= [IF]
\ * True if word is not visible
: [UNDEFINED] ( "name" -- undefined? )
BL WORD FIND NIP 0= ; IMMEDIATE
[THEN]

[UNDEFINED] [DEFINED] [IF]
\ * True if word is visible
: [DEFINED] ( "name" -- defined? )
BL WORD FIND NIP 0<> ; IMMEDIATE
[THEN]

[UNDEFINED] \\ [IF] \ TOOL2000.TXT extended to Blocks
\ * \\ skips interpreting rest of a block or a file
\ the way that \ skips interpreting rest of a line
\ Works w/chained blocks, not 'THRU' blockset
\
: \\ ( "...<eof>" -- )
BLK @ IF
SOURCE >IN ! DROP
ELSE
BEGIN REFILL 0= UNTIL
THEN ;
[THEN]

\ * target vocabulary for exported words
GET-CURRENT VALUE get-export

\ * target vocabulary for exported words
: set-export ( wid -- ) TO get-export ;

\ * current compilation wordlist becomes export target
: export>current ( -- ) GET-CURRENT set-export ;

\ * bring export target to front of search order
: []export[] ( -- )
GET-ORDER NIP get-export SWAP SET-ORDER ;

\ * []Niclos wordlist is a vocabulary/version registry
WORDLIST CONSTANT Niclos-tools

\ * Access Niclos vocabularies
CREATE []Niclos Niclos-tools , {does-vocabulary}

\ * defined vocabulary replaces first wordlist in the
\ search order, which will be Niclos-tools.
\ ``ALSO []Niclos Tkit1[]''
\
: []Toolkit: ( "name" -- ) \ Makes: name ( -- TRUE )
WORDLIST CREATE , {does-vocabulary} ;

\ * creates vocabulary if it does not exist in []Niclos and
\ then makes it the CURRENT vocabulary for definitions. It
\ leaves search order 'vocname' []Niclos[] FORTH so if
\ there are required support vocabularies, that comes next.
\
: []Extend: ( "tkitname" -- )
[]Niclos DEFINITIONS >IN @ >R
BL WORD FIND 0= IF
R@ >IN ! []Toolkit: R@ >IN ! '
THEN
RDROP EXECUTE DEFINITIONS ;

FALSE [IF] ====================
--[ Foundation Niclos Tools: Ntools[] ]--
======================== [THEN]

\ * used for open support tool sharing without requiring
\ Major Version changes when changing factoring of support
\ words. Always test Ntools[] word for existence before
\ defining.
[]Niclos[] ALSO []Extend: Ntools[]

\ Words below which are are Comus - eg, the more widespread
\ words in Forth Toolbelt2002 - conditionally compiled.

TRUE CONSTANT Ntools00?
0 CONSTANT NTools00#

[DEFINED] NOT [IF] \ Forth-79
1 NOT [IF] \ if true, NOT means INVERT
\ * In Niclos scripts, NOT means 0=
: NOT ( flag -- ~flag ) 0= ;
[THEN]
[ELSE]
: NOT ( flag -- ~flag ) 0= ;
[THEN]

[UNDEFINED] ON [IF] \ TOOL2002.TXT
\ * SET variable
: ON ( addr -- ) TRUE SWAP ! ;
[THEN]

[UNDEFINED] OFF [IF] \ TOOL2002.TXT
\ * RESET variable
: OFF ( addr -- ) FALSE SWAP ! ;
[THEN]

\ * Promiscuous variables
\ Rule for use: use at point where only words
\ in the same script are being called
\
VARIABLE temp
VARIABLE flag
VARIABLE out
VARIABLE act1
VARIABLE act2
VARIABLE act3

\ * One-shot private words
\ Usage :noname ... ; act1 ! ... : foo ... [,act1] ... ;
: [,act1] ( -- ) act1 @ COMPILE, ; IMMEDIATE
: [,act2] ( -- ) act2 @ COMPILE, ; IMMEDIATE
: [,act3] ( -- ) act3 @ COMPILE, ; IMMEDIATE

[UNDEFINED] ANDIF [IF] \ TOOL2002.TXT
: ANDIF \ p ANDIF q THEN ... yields p=0 otherwise q
POSTPONE DUP POSTPONE IF POSTPONE DROP
; IMMEDIATE
[THEN]
[UNDEFINED] ORIF [IF] \ TOOL2002.TXT
: ORIF \ p ORIF q THEN ... yields q when p=0, otherwise p
POSTPONE DUP POSTPONE 0= POSTPONE IF POSTPONE DROP
; IMMEDIATE
[THEN]

[UNDEFINED] \\line [IF]
: \\line ( "..." -- "" ) SOURCE >IN ! DROP ;
[THEN]

: c=str? ( c ca u -- [ca u]="c"? ) 1 = >R C@ = R> AND ;
: \token? ( "\ ..."|"..." -- T|F ) [CHAR] \ BL PARSE c=str? ;

: ---[file ( ... "<eol>\<bl>" | <eof>" -- )
\\line BEGIN REFILL 0= ORIF \token? \\line THEN UNTIL ;

1024 CONSTANT blksize
64 CONSTANT blkrow
blkrow 1 - INVERT CONSTANT rowmask

: \\row ( "..." -- "" )
>IN @ rowmask AND blkrow + blksize MIN >IN ! ;

: eob? ( ""|"..." -- T|F ) >IN @ blksize = ;

: ---[block ( ... "<eor>\<bl>"|"<eob>" -- )
\\row BEGIN eob? ORIF \token? \\row THEN UNTIL ;

FALSE [IF] ====================
---[ Multi-line Comments ]---
======================== [THEN]

[]Niclos[] DEFINITIONS
ALSO []Niclos Ntools[]

: ---[ ( ... "\ "|"end" -- )
BLK @ IF ---[block ELSE ---[file THEN ;

: --[ ( ... "\ "|"end" -- ) ---[ ;
: -[ ( ... "\ "|"end" -- ) ---[ ;

---[ Using Extended Comments ]---

And now, extended comments are available:

... -[ filename ]- can be used to concatenate scripts
and scan or split them later, alternate ``\ -[''.
... --[ major section ]--
... ---[ minor section ]---

To Forth, everything after the ---[ word is decoration,
but literate programming filters may make use of it.


--[ Niclos-Core: Version Testing ]--

Niclos version control vocabularies are named in the
pattern of ``Name[]'' and they contain version information
based on "Name", eg, ``Niclos00?'' and ``Niclos00#''.

``[]Niclos[]'', the foundation vocabulary, must be in the
search order when any Niclos system script is being
interpreted. It contains ``[]Niclos'', the toolkit
container vocabulary, which is named for use in a pair, as
in ``ALSO []Niclos Nblocks[]''

Nothing should be defined into []Niclos other than
Niclos vocabularies or words that emulate provision of
Niclos vocabularies, since []Niclos never remains in the
search order in normal use.


---[ Niclos Major Versions ]--

Major versions work like:
* Major versions are: name00?
* They are constants (or values) that return a value
as indicated below.
* The major-return-value is ``mrv'' in stack comments.
* DROPPING words is permitted between major versions
* Choice of versionid scheme is up to author/librarian,
but Name and id should fit in EIGHT (8) characters.
* Niclos uses six char Name and:
** 00 pre-alpha, experimental
** 01-05, alpha, (any 02 through 05 might be skipped)
** 06-09, beta (any 07 through 09 might be skipped)
** 10-99, release
* Not present in Name[] or []Niclos[] implies not
compiled, but, tacitly, permitted to be compiled.
* FALSE implies not compiled and DON'T compile (this
allows block problematic major versions to be blocked,
either by the user or in a prelude file.
* TRUE if supported in this wordlist
* Any other value MUST BE a wordlist-id, indicating it
is supported in a different wordlist

Note that "wordlist-id" version constants will normally be
stored in the []Niclos[] vocabulary, and the "flag"
version constants normally stored in that version's
public vocabulary.

Variants not in a main release path should have their main
version incremented and be initialed with two or three
letters. In a script file hierarchy, these will have a
normal eight (8) character version load script name but be
in a subdirectory or parallel directory based on the initials.
So ``TRUE CONSTANT Niclos03-brm01'', would be a variant
release of Niclos02.


---[ Minor Versions ]--

Minor versions are: <name><version#>#

Minor versions may only fix bugs and add available public
words so each minor version is an increment on the previous,
and the version is a constant of the version index, tested
by relative comparison. A minor version equal 0 indicates a
major version is not yet tested/stable - its presence is
required to test that it respects version control but is not
for released code.

This is a publication-oriented system rather than one
focused on development in progress, so do not publish
an untested modification into a main release. Until
all words have been tested, and whatever other publication
requirements of the Niclos toolkit librarian have been met,
a new minor version should only ever have the unstable minor
version 0.

Publishing code for review and testing for portability
when the author does not have access to a broad range of
systems can be done with a pre-alpha variant release with
a version 0.

---[ Version Factors ]---

find-version searches for a string in the most recent
wordlist and []Niclos[]

\ * This vocabulary is for sharing support words that are
\ not part of the main public wordset contained in the
\ main Niclos toolkit.
\
[]Niclos[] ALSO []Extend: Ntools[]

\ Is-White ( char -- flag ) TOOL2002.TXT
\ used here as is-ws? and as factor in is-not-ws?

\ NB. If more complex White-Space is needed, this should be
\ defined in the system prelude.
\ When Comus words are publicly defined in Mixed or Upper,
\ do multi-case test for case-sensitive models

[UNDEFINED] is-ws? [IF]
[DEFINED] is-white [IF]
: is-ws? ( c -- flag ) is-white ;
[ELSE] [DEFINED] Is-White [IF] \ TOOL2002.TXT
: is-ws? ( c -- flag ) Is-White ;
[ELSE]
\ * Test c for white space. By default, any character
\ with value less than 33 is taken as white space.
: is-ws? ( char -- flag ) \ TOOL2002.TXT
33 - 0< ;
[THEN]
[THEN]
[THEN]
[UNDEFINED] not-ws? [IF]
\ * test for not white space
: not-ws? ( char -- flag ) is-ws? 0= ;
[THEN]

[UNDEFINED] PARSE-NAME [IF]
[DEFINED] parse-name [IF] \ reference implementation
: PARSE-NAME parse-name ;
[ELSE]
[UNDEFINED] xt-skip [IF] \ reference implementation
\ * skip all characters satisfying xt ( c -- f )
: xt-skip ( addr1 n1 xt -- addr2 n2 ) \ gforth
>R BEGIN
DUP
WHILE
OVER C@ R@ EXECUTE
WHILE
1 /STRING
REPEAT
THEN R> DROP ;
[THEN]

: PARSE-NAME ( "name" -- c-addr u )
SOURCE >IN @ /STRING
['] is-ws? xt-skip OVER >R
['] not-ws? xt-skip
( end-word restlen r: start-word )
2DUP 1 MIN + SOURCE DROP - >IN !
DROP R> TUCK - ;
[THEN]
[THEN]

: get-first-wid ( -- wid )
GET-ORDER OVER >R
0 ?DO DROP LOOP
R> ;

: find-version ( ca u -- mvr )
2DUP 2>R get-first-wid SEARCH-WORDLIST IF
2RDROP EXECUTE
ELSE
2R> Niclos-tools SEARCH-WORDLIST IF EXECUTE ELSE 0 THEN
THEN ;

---[ Major Version Test ]---

Version control is performed with tests that can drive
conditional [IF] ... [ELSE] ... [THEN] scripts.

version? name
searches for the name in the current search order. If
it is not present, 0 is returned, if it is present, it
is executed.

version? name version! [IF] ...
version! leaves FALSE and TRUE alone, and assumes otherwise
that it is a replacement wordlist-id, replacing the current
vocabulary.

external? ( mrv -- mrv flag=wid? )
generates a flag based on whether it is a definite result
here, or an external vocabulary - this is a factor of version?
useful in its own right.
``version? name external? [IF] ...''

possibly? ( "name" -- x*j TRUE | FALSE )
executes name if found anywhere, leaving flag on whether
found or not. This is a generally useful support word, and
especially useful for selecting which of various
vocabularies that can be used to provide a needed facility.
``[]Niclos possibly? Nbmw[] NOT [IF] ...''

\ Foundation words in []Niclos[]

[]Niclos[] DEFINITIONS ALSO []Niclos Ntools[]

\ * generic execute if found
: possibly ( "token" -- x*j )
BL WORD FIND IF EXECUTE ELSE DROP THEN ;

\ * generic execute if found, flag=found?
: possibly? ( "version-token -- x*j flag )
BL WORD FIND IF EXECUTE TRUE ELSE DROP FALSE THEN ;

\ * execute
: version? ( "version-token" -- mvr )
PARSE-NAME find-version ;

\ * distinguish "definite" major version results from
\ external wordlist-id's

: external? ( mvr -- mvr flag=wid? )
DUP 0= OVER TRUE = OR 0= ;

\ * resolves workspace-id if it is one
: version! ( mvr -- mvr' )
external? IF
>R GET-ORDER NIP R> SWAP SET-ORDER
TRUE
THEN ;

---[ Minor Version Test ]---

<minor? is an AMENDMENT to a major version return (mvr) on
the stack. If the mvr is not TRUE, minor# returns false, so
it is normally used after [>version] and, indeed, normally
only PRESENT in the vocabulary/ies for which [version] gives
TRUE.

\ * test for minor version
\ version? Niclos00? version! 16 <minor? Niclos00# [IF]
\ No minor is equivalent to a minor of 0

: <minor? ( mvr target-minor# "version#" -- mvr' )
version? ?DUP U> 0= AND TRUE = ;

\ * test for stable version
: stable? ( mrv "version" -- mrv' )
1 <minor? ;

---[ Backup Error Return ]---

Niclos scripts are encouraged to THROW without worrying
about whether the THROW will be caught. When CATCH is not
available, the script should simply report the return code
and abort.

NB. A Niclos script that relies on CATCH/THROWN does not
test for ``THROW'', it tests for ``CATCH''.

This is deferred, so that if THROW is an extension in a
system, a prelude for a Niclos script that requires THROW
can load it and then install it to any earlier Niclos
scripts that simply THROW errors.

\ NB: Commonwealth English slang alert

[UNDEFINED] THROW [IF]
\ * Value to defer THROW
' DROP VALUE {THROW}

\ * THROW deferred through {THROW}
: THROW ( k*x n | k*x | i*x n ) {THROW} EXECUTE ;

\ * When CATCH/THROW not available, Niclos
\ THROWS errors back to user with ABORT
\
: throw-the-dummy ( flag -- continue | ABORT )
?DUP IF
CR ." Thrown value: " . CR ABORT
THEN ;

' throw-the-dummy TO {THROW}
[THEN]

[]Niclos[]

\\ // \\ // \\ // \\ // \\ //

---[ That's All, Folks! ]---

This is the Niclos01 minor version 00 model to date.

Bruce McFarling

unread,
Jan 1, 2010, 12:34:43 PM1/1/10
to
On Jan 1, 10:55 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> Bruce McFarling <agil...@netscape.net> writes:
> >The one proposed but not yet accepted in the Forth200x process is:
> >"(2) Relative subdirectory support that works when a file is being
> >INCLUDED."

> That's pretty much stalled.  There is significant resistance to that
> and not that much support.

That's a catch-22 - since the only real extensive libraries are those
provided with the systems they were developed for, the large majority
of people using the capability are using the approach of that
implementation. And that portable capability is a necessary but far
from a sufficient condition for developing extensive cross-platform
libraries.

> >The two that I've dropped from the list are:

> >"(5) REQUIRE ... because the library oversight system needs to know
> >precisely what semantics can be expected of this word.
>
> REQUIRE is in Forth200x:http://www.forth200x.org/required.html

> Do you mean to say that the semantics are not defined sufficiently?
> If so, what is lacking?

No, I mean that providing additional capabilities specific to the
library system left REQUIRE redundant within the context of the
library. REQUIRE is perfectly fine for loading an application that
uses the library system without requiring the person loading that
application to know anything about the library system.

Bruce McFarling

unread,
Jan 1, 2010, 12:40:14 PM1/1/10
to
On Jan 1, 10:34 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> Bernd Paysan <bernd.pay...@gmx.de> writes:
> >And I still don't know if it can be made work on 64 bit Gforth
> >(something the '94 standard really solved, but when the programmer only
> >tests on 32 bits, it's unlikely to really work).

> Not in my experience.  The typical case is that programs working on
> one cell width also work on a different cell width.

different => larger

Upsizing often works without a hitch. Downsizing often requires
substantial rework.

Bruce McFarling

unread,
Jan 1, 2010, 1:03:13 PM1/1/10
to
On Jan 1, 8:31 am, Josh Grams <j...@qualdan.com> wrote:
> Yes, I know, but that's a totally different issue.  I don't want "easily
> ported", I want "write once, run anywhere" (for values of "anywhere"
> which include at least Windows, OSX, and various Linuxes).  I assume
> that, if this ever becomes possible, it will be in the form of one Forth
> system which has been ported to many different places.  But I suppose it
> could also happen through different Forth systems becoming more
> compatible.

If the same library can compile and run correctly on Swiftforth, VFX
and gforth without any user intervention, that would be "write once,
use anywhere" for Windows, OSX, and various Linuxen.

> And I'm not sure why you assume that I'm talking only about toy Forths:
> I originally jumped into this thread to claim that none of the free
> Forth systems which run on my machine (with the exception of gforth) are
> actually fully standard.

Why is it required to have more than one full standard free Forth
system available on all mainstream PC operating systems when there are
two professional implementations that each have quite capable, free-as-
in-free-beer evaluation downloads?

> Er.  No, how could they? :)  Having to write my own bindings to external
> libraries is an artifact of how few people are publishing desktop
> applications in Forth source form.

Just use the higher level GUI application toolkits provided in the
implementations you omitted from consideration and there's no need to
directly *use* their capabilities to write bindings to external
libraries - their higher level tools already do that.

Given all the cheap Chinese mini-netbooks being sold worldwide for
$120 and less which are sold in the US running WindowsCE ... they are
often sold running customized Linux distributions outside of North
America, but tend to have WindowsCE installed for North American sales
because running Linux generates such a high return rate in the US ...

... a gforth (or Swiftforth or VFX with a free evaluation version)
port to WindowsCE would be more useful in terms of expanding the range
of Forth applications than any amount of effort devoted to getting a
fourth and fifth and sixth fully compliant Forth-94 system for Windows
x86 and OSX and the main Linux distributions.

Robert Epprecht

unread,
Jan 2, 2010, 5:26:00 AM1/2/10
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

> Most of the appbench programs work on 32-bit and 64-bit Forths from
> the start, and AFAIK several of them had not been tested on 64-bit
> Forths before. And even Brew, which at first appeared not to work
> on 64-bit Forths just gave different results (from different overflow
> characteristics or something like that), but worked as it should.

I did not have access to a 64bit machine when I wrote the brew version
used in the appench suite, btw.

Brew is a bit a special case regarding integer overflow as I deliberately
did *not* try to prevent its code mutation engine to build genes which will
eventually produce integer overflows. I leave it to the evolutionary process
to decide if such genes make any sense (in terms of 'fitness') or not. Most
other well tested 32bit programs would not tolerate integer overflow to
happen. So such issues would not exist in running them on 64bit.

BTW: There is a newer brew snapshot on http://reppre51.home.solnet.ch/
which works well with the appbench suite on 64bit (gforth and vfx)
There is *no* change in the benchmark that is run, only in the assertion
methods, random generators and integer comparisons to give the same
result on 32/64bit values regardless of possible 32bit overflows.

Robert Epprecht

Anton Ertl

unread,
Jan 2, 2010, 10:15:34 AM1/2/10
to
Josh Grams <jo...@qualdan.com> writes:
>Yes, I know, but that's a totally different issue. I don't want "easily
>ported", I want "write once, run anywhere"

Yes, I think that we should have a standard that makes that possible.
Unfortunately, some others are less ambitious.

>(for values of "anywhere"
>which include at least Windows, OSX, and various Linuxes). I assume
>that, if this ever becomes possible, it will be in the form of one Forth
>system which has been ported to many different places.

Gforth runs on all the OSs you mentioned. But I guess you are still
missing pre-existing bindings to external libraries in Gforth. Yes,
that will take a little more time.

Anton Ertl

unread,
Jan 2, 2010, 10:21:42 AM1/2/10
to
Josh Grams <jo...@qualdan.com> writes:
>Bruce McFarling wrote:
>> The one proposed but not yet accepted in the Forth200x process is:
>> "(2) Relative subdirectory support that works when a file is being
>> INCLUDED."
>> Forth200x RfD on ``F"'', has not yet reached the call for vote
>> stage, but the name could be used as Comus.
>> http://www.forth200x.org/directories.html
...

>I prefer to just have paths to INCLUDED and company default to being
>relative to the directory containing the current source file (or search
>a system include path if not found).

1) I originally thought that this would be hard to agree on, because
every system already does something when you give it a relative file
name. However, maybe I was wrong: If we specify that the first base
directory tried is the one containing the current source file, and
afterwards a system-specific search path is tried, probably all
existing programs for all Forth systems would continue to work (the
only possible exception is if same-named, but different files happen
to be in different directories in an unfortunate way). Of course,
this will still be hard to agree on, because the ideas on how to build
programs are extremely divergent.

2) F" etc. has the advantage that it does not just work for INCLUDED
and friends, but also for OPEN-FILE (e.g., for accessing a data file
coming with the application), and even if the OPEN-FILE or INCLUDED
happens in a different file than the string (e.g., if the file names
are stored in an array and only loaded later, maybe on-demand). So I
think we should have that even if we agree on 1).

Anton Ertl

unread,
Jan 2, 2010, 10:42:33 AM1/2/10
to
Bruce McFarling <agi...@netscape.net> writes:
>On Jan 1, 10:55=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

>wrote:
>> Bruce McFarling <agil...@netscape.net> writes:
>> >The one proposed but not yet accepted in the Forth200x process is:
>> >"(2) Relative subdirectory support that works when a file is being
>> >INCLUDED."
>
>> That's pretty much stalled. =A0There is significant resistance to that

>> and not that much support.
>
>That's a catch-22 - since the only real extensive libraries are those
>provided with the systems they were developed for, the large majority
>of people using the capability are using the approach of that
>implementation.

AFAIK there are several systems that use source-file relative file
names for INCLUDED and friends: Gforth and Win32Forth (others?).

I guess if the people publishing portable source code write for that
capability instead of bending over backwards to accomodate the other
systems, maybe other systems would adopt that feature, too.

Or maybe they wouldn't, because their implementors have different
ideas about portability. But then those of us who want
write-once-run-anywhere portability will have other problems with
these systems as well, so it's unclear if catering for such systems
really pays off.

Anton Ertl

unread,
Jan 2, 2010, 10:54:55 AM1/2/10
to
Bruce McFarling <agi...@netscape.net> writes:
>On Jan 1, 10:34=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

>wrote:
>> Bernd Paysan <bernd.pay...@gmx.de> writes:
>> >And I still don't know if it can be made work on 64 bit Gforth
>> >(something the '94 standard really solved, but when the programmer only
>> >tests on 32 bits, it's unlikely to really work).
>
>> Not in my experience. =A0The typical case is that programs working on

>> one cell width also work on a different cell width.
>
>different =3D> larger

>
>Upsizing often works without a hitch. Downsizing often requires
>substantial rework.

Not in my experience. I have developed the majority of the Forth code
I have written in the last 14 years on 64-bit systems, and it
typically worked on 32-bit systems the first time it ran there, just
as the other way round.

Sure, downsizing to 16 bits will often be more work or impossible, but
typically because of space constraints.

Bruce McFarling

unread,
Jan 2, 2010, 11:45:25 AM1/2/10
to
On Jan 2, 10:42 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> I guess if the people publishing portable source code write for that
> capability instead of bending over backwards to accomodate the other
> systems, maybe other systems would adopt that feature, too.

I'm happy if a lot of systems adopt that, because F" is very easy to
write for those systems -- create a buffer, copy S" ./" into that
buffer, parse to " and copy that into the rest of the buffer. Return
the buffer address and the number of characters.

However, regarding this argument: "If people publishing portable
source code ignore the fact that BEHAVIOR_X is not portable, maybe
other systems would adopt BEHAVIOR_X and then it would be portable."

Kind of didn't happen that way for over thirty years now, I'm not
holding my breath it will happen anytime soon.

Bruce McFarling

unread,
Jan 2, 2010, 11:48:11 AM1/2/10
to
On Jan 2, 10:54 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> Sure, downsizing to 16 bits will often be more work or impossible, but
> typically because of space constraints.

Rarely impossible, if blocks are available as extended working memory,
but the range of 16-bit signed integers often means shifting from
cells to doubles.

Bernd Paysan

unread,
Jan 2, 2010, 11:58:16 AM1/2/10
to
Anton Ertl wrote:

> Josh Grams <jo...@qualdan.com> writes:
>>I prefer to just have paths to INCLUDED and company default to being
>>relative to the directory containing the current source file (or
>>search a system include path if not found).
>
> 1) I originally thought that this would be hard to agree on, because
> every system already does something when you give it a relative file
> name. However, maybe I was wrong: If we specify that the first base
> directory tried is the one containing the current source file, and
> afterwards a system-specific search path is tried, probably all
> existing programs for all Forth systems would continue to work (the
> only possible exception is if same-named, but different files happen
> to be in different directories in an unfortunate way). Of course,
> this will still be hard to agree on, because the ideas on how to build
> programs are extremely divergent.

I think the major discrepancy was between a search-path related way of
looking up files (as in Gforth or bigForth) vs. a macro-expanding
facility as implemented in VFX. Stephen Pelc argued that the macro-
expanding facility is very general-purpose, powerful, and can be tweaked
to whatever you want. However, the missing search path requires that
the macros are used directly in the file name, and at least as
implemented in VFX, it's next to impossible to make the current-file-
relative loading work, even when you use a macro for that - because
there is no "magic" macro for that purpose. And VFX has no search-path
list to implement a lookup semantics similar to Gforth or bigForth.

> 2) F" etc. has the advantage that it does not just work for INCLUDED
> and friends, but also for OPEN-FILE (e.g., for accessing a data file
> coming with the application), and even if the OPEN-FILE or INCLUDED
> happens in a different file than the string (e.g., if the file names
> are stored in an array and only loaded later, maybe on-demand). So I
> think we should have that even if we agree on 1).

In Gforth we have OPEN-FPATH-FILE, which opens a file with the same
search mechanism as INCLUDED. bigForth goes a bit further, and applies
the search mechanism to OPEN-FILE itself - same idea as with VFX: if you
use it in one place, use it everywhere.

J Thomas

unread,
Jan 2, 2010, 12:06:38 PM1/2/10
to
Anton Ertl wrote:

> Bruce McFarling <agi...@netscape.net> writes:
>> (Anton Ertl) wrote:
>>> Bernd Paysan <bernd.pay...@gmx.de> writes:
>>> >And I still don't know if it can be made work on 64 bit Gforth
>>> >(something the '94 standard really solved, but when the programmer
>>> >only tests on 32 bits, it's unlikely to really work).
>>
>>> Not in my experience. =A0The typical case is that programs working on
>>> one cell width also work on a different cell width.
>>
>>different =3D> larger
>>
>>Upsizing often works without a hitch. Downsizing often requires
>>substantial rework.
>
> Not in my experience. I have developed the majority of the Forth code I
> have written in the last 14 years on 64-bit systems, and it typically
> worked on 32-bit systems the first time it ran there, just as the other
> way round.

Does that imply that > 32-bit precision rarely made a difference?

> Sure, downsizing to 16 bits will often be more work or impossible, but
> typically because of space constraints.

While > 16-bit precision did often matter, but > 64K address space
mattered more.

Anton Ertl

unread,
Jan 2, 2010, 12:48:17 PM1/2/10
to
Bruce McFarling <agi...@netscape.net> writes:
>On Jan 2, 10:42=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

>wrote:
>> I guess if the people publishing portable source code write for that
>> capability instead of bending over backwards to accomodate the other
>> systems, maybe other systems would adopt that feature, too.
>
>I'm happy if a lot of systems adopt that, because F" is very easy to
>write for those systems -- create a buffer, copy S" ./" into that
>buffer, parse to " and copy that into the rest of the buffer. Return
>the buffer address and the number of characters.

That works only on systems where "./" refers to the directory of the
current source file, and even there it does not work correctly if the
F" is in a different file (in a different directory) than the
file-name-using word.

>However, regarding this argument: "If people publishing portable
>source code ignore the fact that BEHAVIOR_X is not portable, maybe
>other systems would adopt BEHAVIOR_X and then it would be portable."
>
>Kind of didn't happen that way for over thirty years now, I'm not
>holding my breath it will happen anytime soon.

Hmm, some things have happened, although maybe not because some
applications have used the features.

I guess it also has to do with how the feature is documented, and on
how attractive the library or application is and on how it is updated.

I guess the maximal impact would be an attractive application or
library, with attractive updates often enough that the typical
approach of some system implementors of changing the source code
rather than addressing the shortcomings of their systems becomes
tiring. In addition the documentation should clearly spell out that
the users of the application should always use the latest version of
the application and should complain to the system implementor about
the lack of that feature.

But yes, in general I think that system implementors who think that
changing the source code of a library or application is a satisfactory
approach to portability are a lost cause. That was what my last
paragraph was about.

Anton Ertl

unread,
Jan 2, 2010, 1:03:26 PM1/2/10
to
J Thomas <jeth...@gmail.com> writes:

>Anton Ertl wrote:
>> I have developed the majority of the Forth code I
>> have written in the last 14 years on 64-bit systems, and it typically
>> worked on 32-bit systems the first time it ran there, just as the other
>> way round.
>
>Does that imply that > 32-bit precision rarely made a difference?

In some cases it does make a difference. But then the difference is
typically that you can use the program on bigger parameters or bigger
data sets or somesuch.

>> Sure, downsizing to 16 bits will often be more work or impossible, but
>> typically because of space constraints.
>
>While > 16-bit precision did often matter, but > 64K address space
>mattered more.

Yes.

Anton Ertl

unread,
Jan 2, 2010, 1:06:46 PM1/2/10
to

That seems to be just the result of different ideas about how to build
(and especially port) programs. Maybe I misunderstand what Stephen
Pelc meant, but it seemed to me that his idea of porting a program
(even from one machine to the next, using the same Forth system)
involves editing several path macros in some files before being able
to run the program (and maybe other chores). For me that is just
unportability.

For me a program is portable if I unzip it and can run it as-is.
Anything else is various shades of unportability (and the shade can be
measured in the time that a new user needs for the porting task).

>> 2) F" etc. has the advantage that it does not just work for INCLUDED
>> and friends, but also for OPEN-FILE (e.g., for accessing a data file
>> coming with the application), and even if the OPEN-FILE or INCLUDED
>> happens in a different file than the string (e.g., if the file names
>> are stored in an array and only loaded later, maybe on-demand). So I
>> think we should have that even if we agree on 1).
>
>In Gforth we have OPEN-FPATH-FILE, which opens a file with the same
>search mechanism as INCLUDED. bigForth goes a bit further, and applies
>the search mechanism to OPEN-FILE itself

Neither addresses the second issue of having the OPEN-FILE in a source
file different from the one where the file name was specified. That's
certainly not a frequent situation, but if we are going to do it at
all, we might just as well do it right.

Bernd Paysan

unread,
Jan 2, 2010, 1:36:26 PM1/2/10
to
Anton Ertl wrote:
> For me a program is portable if I unzip it and can run it as-is.
> Anything else is various shades of unportability (and the shade can be
> measured in the time that a new user needs for the porting task).

Same here, we are in violent agreement.

>>In Gforth we have OPEN-FPATH-FILE, which opens a file with the same
>>search mechanism as INCLUDED. bigForth goes a bit further, and
>>applies the search mechanism to OPEN-FILE itself
>
> Neither addresses the second issue of having the OPEN-FILE in a source
> file different from the one where the file name was specified. That's
> certainly not a frequent situation, but if we are going to do it at
> all, we might just as well do it right.

Ah, I won't say that's an infrequent situation. It happens a lot inside
Theseus-generated GUIs, where all icons contain file names which are
accessed at run time (when the icon becomes visible), but should be
specified at compile time. In bigForth, it somehow works, since the
icon base directory is part of the search path list (but would break if
there was by accident a file with the same name), but in VFX, this
completely falls apart - you can only use this scheme as long as you are
in the source directory.

Josh Grams

unread,
Jan 2, 2010, 2:02:04 PM1/2/10
to
Bernd Paysan wrote: <8ia417-...@vimes.paysan.nom>

Interesting. I can see that a macro facility is great in some
circumstances, but it doesn't fit my usage of INCLUDE very well.

I think your needs depend quite a bit on how you work. You can get
along fine with include paths relative to the current working directory
if you have no a flat project layout, or one which is static enough that
you always put a file at the same place relative to the root of the
project tree. And if you have macros, you can have a macro pointing to
your Library or System folder, and put them somewhere outside your
project. I have a vague impression that MPE and Forth, Inc. work along
those lines.

But I'm not that...disciplined, I guess. I have a tendency to leave
common code with the project for which I first developed it, and use
symlinks or version control tools to pull the pieces I need into the
project I'm working on. So I want each sub-directory to be a
self-contained unit that I can move around at will, without having to
worry about where it is in relation to the root of my project tree. So
for that I need the include paths to be relative to the current source
file.

>> 2) F" etc. has the advantage that it does not just work for INCLUDED
>> and friends, but also for OPEN-FILE (e.g., for accessing a data file
>> coming with the application), and even if the OPEN-FILE or INCLUDED
>> happens in a different file than the string (e.g., if the file names
>> are stored in an array and only loaded later, maybe on-demand). So I
>> think we should have that even if we agree on 1).

My reaction when I first saw that proposal was that doing the path
search when you parse the string seemed like a bad idea -- it seems like
it should happen when you're actually going to do something with the
file. But I imagine you have thought about it more than I have. And as
long as some factor is provided which does the path search, then anybody
can do it whichever way they want.

> In Gforth we have OPEN-FPATH-FILE, which opens a file with the same
> search mechanism as INCLUDED. bigForth goes a bit further, and applies
> the search mechanism to OPEN-FILE itself - same idea as with VFX: if you
> use it in one place, use it everywhere.

I like having the path search mechanism generally available -- I have
taken advantage of that a couple of times. But I don't think I usually
want it for dealing with data files, so putting it in OPEN-FILE seems
like one step too far. I'd rather find my data directory as a whole,
and have the OPEN-FILE fail if a file isn't there, rather than trying to
search for it other places on a per-file basis...

Hrm. I suppose I can simply use an empty search path (or one with only
the data directory) if I want that behavior.

--Josh

Stephen Pelc

unread,
Jan 2, 2010, 3:01:15 PM1/2/10
to
On Sat, 02 Jan 2010 17:58:16 +0100, Bernd Paysan <bernd....@gmx.de>
wrote:

>I think the major discrepancy was between a search-path related way of
>looking up files (as in Gforth or bigForth) vs. a macro-expanding
>facility as implemented in VFX.

That's a good summary, but excludes why we do not like search paths.
1) They are prone to error in name conflicts between files, e.g.
the original version supplied with a system and the one modified
by an application programmer.
2) They are restricted to use with files.

Many application developers keep their projects well away from
the Forth system that hosts it. When you move application source
code from (say) the development desktop to a laptop for
commissioning, you need an unambiguous way of defining
exactly where you expect to find the files.

At the expense of some set up, text macros permit us to do this.

>Stephen Pelc argued that the macro-
>expanding facility is very general-purpose, powerful, and can be tweaked
>to whatever you want. However, the missing search path requires that
>the macros are used directly in the file name, and at least as
>implemented in VFX, it's next to impossible to make the current-file-
>relative loading work, even when you use a macro for that - because
>there is no "magic" macro for that purpose. And VFX has no search-path
>list to implement a lookup semantics similar to Gforth or bigForth.

All you are arguing for is a macro that is relative to some folder.
a) IDIR - relative to the current include file
b) CDIR - the current working directory
c) LDIR - the directory containing the executable
...

The mechanics to this are all in VFX Forth - you just never asked.

>> 2) F" etc. has the advantage that it does not just work for INCLUDED
>> and friends, but also for OPEN-FILE (e.g., for accessing a data file
>> coming with the application), and even if the OPEN-FILE or INCLUDED
>> happens in a different file than the string (e.g., if the file names
>> are stored in an array and only loaded later, maybe on-demand). So I
>> think we should have that even if we agree on 1).

F" is simply a wrapper - it makes it easier to add a "sort of" macro
system to those that don't have it, but it's second rate compared to
real macros.

Anton's objection to macros using '%' as a delimiter, e.g.
%idir%/foobar.fs
is that % is found in Unix file systems. Every filename containing %
on our Linux boxes is either of the form
%gconf
or
%032
or
%2f
or some such.

Restricting macros names to alpha characters fixes the CGI expansion
issues, and modifying the behaviour of unfound macros to pass
everything including the delimiter fixes the rest.

IMHO, this causes no more breakage than perverting './' in file
path names. In the 15 years we've been using this mechanism,
MPE has had minimal tech support on the topic.

Search paths work fairly well when you are devloping new system
components. They just do not scale well to large apps. Note that
Minos/Theseus is not a large app in our world view. I'll be happy
to add IDIR and CDIR macros if there is demand. So far there has
been no demand.

Macros have one big advantage. They a text substitution facility.
Such as facility is required by most commercial apps. With macros
we get "two for one".

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

Bernd Paysan

unread,
Jan 2, 2010, 4:39:12 PM1/2/10
to
Stephen Pelc wrote:

> On Sat, 02 Jan 2010 17:58:16 +0100, Bernd Paysan <bernd....@gmx.de>
> wrote:
>>I think the major discrepancy was between a search-path related way of
>>looking up files (as in Gforth or bigForth) vs. a macro-expanding
>>facility as implemented in VFX.
>
> That's a good summary, but excludes why we do not like search paths.
> 1) They are prone to error in name conflicts between files, e.g.
> the original version supplied with a system and the one modified
> by an application programmer.

Search paths have a lookup order, and usually the current working
directory has higher priority than the system library path. So the same
file name modified by the application programmer will win (same as with
Forth words - if you redefine a system definition, yours will win).

> 2) They are restricted to use with files.

Text macro substitution is of course a much more general feature.

> Many application developers keep their projects well away from
> the Forth system that hosts it. When you move application source
> code from (say) the development desktop to a laptop for
> commissioning, you need an unambiguous way of defining
> exactly where you expect to find the files.

You need, I don't.

> At the expense of some set up, text macros permit us to do this.

I've my systems on *several* computers. Windows, Linux, Mac OS X,
different user names, different default installation locations, and I
don't need to set up *anything* to get an application running on another
computer.

The system library is found in the search path. This search path is
adjusted at install time or build of the system - depending when that
choice has to be made (for Linux packages: build time, for source
tarballs or setup.exe: Install time).

The application files I'm loading are found relatively to the loader
file, or looked up in the directories in the search path list.

> All you are arguing for is a macro that is relative to some folder.
> a) IDIR - relative to the current include file
> b) CDIR - the current working directory
> c) LDIR - the directory containing the executable

The current working directory is straight forward - a relative path name
will be opened relatively to the current working directory anyways. The
directory containing the executable is not particularly interesting,
especially in Unix. IDIR could be useful.

> The mechanics to this are all in VFX Forth - you just never asked.

The mechanics are there, but IDIR is not actually implemented. Any way
to obtain the current include file path would be highly recommended.

> Restricting macros names to alpha characters fixes the CGI expansion
> issues, and modifying the behaviour of unfound macros to pass
> everything including the delimiter fixes the rest.
>
> IMHO, this causes no more breakage than perverting './' in file
> path names.

Of course - no complaints here or no complaints there is fair to
compare. What we wanted was something similar to C's #include <foo> and
#include "foo", so that the user can specify files relatively to his
project directory or directly access files through the search path.

> Search paths work fairly well when you are devloping new system
> components. They just do not scale well to large apps.

We know. You also need "relative to current include file". But having
no search path at all makes it difficult to write even small programs
like MINOS. And of course, when I would write a large application, a
fair amount of it would be components similar to MINOS. To distinguish
these components, probably each would reside in a directory of its own,
i.e. you load minos/3d-turtle.fs, or browser/javascript.fs or whatever -
and there the files would use ./ to load their dependencies. The file
system itself is fairly good at separating name spaces.

MINOS applications are supposed to load some MINOS-related stuff, like
3d-turtle.fs (which itself depends on floating point and OpenGL
bindings) or icons. The application doesn't know and shouldn't know
where these come from (they are the responsibility of those who install
MINOS), and should have a way to override them (e.g. if the application
programmer wants his own icon set, he can use the same names in his
local directory - those will be found first, and consistently replace
all icons used within MINOS).

> Macros have one big advantage. They a text substitution facility.
> Such as facility is required by most commercial apps. With macros
> we get "two for one".

Well, you get two oranges for one apple.

One last suggestion: At least set basepath correctly when someone
installs the VFX package and starts vfxlin first on his computer,
instead of leaving basepath empty and setting vfxpath to your project
home directory on your PC - having to edit the .VfxForth.ini after first
invocation is certainly somewhat lacking.

Marcel Hendrix

unread,
Jan 2, 2010, 5:32:43 PM1/2/10
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Small, understandable Forth

> J Thomas <jeth...@gmail.com> writes:
>>Anton Ertl wrote:
>>> I have developed the majority of the Forth code I
>>> have written in the last 14 years on 64-bit systems, and it typically
>>> worked on 32-bit systems the first time it ran there, just as the other
>>> way round.

There are some more or less subtle problems to watch out for. I don't have
a 14 year experience, but the last year came up with the following examples:

--(1)--

64BIT? [IF] : bessj0 ( F: r1 -- r2 ) FPOPXMM0 0 BLAS-LIB: bessj0 FFOREIGN ;
[ELSE] : bessj0 ( F: r1 -- r2 ) FPUSHD 2 BLAS-LIB: bessj0 FFOREIGN ;
[THEN]

System calls on 64-bit OS's use SSE2 code and pass values in registers (where
every OS has its own standard), not on the stack.

--(2)--

\ does all digits at once, skipping blanks
: >DHEX ( c-addr1 u1 -- d c-addr2 u2 )
-LEADING -TRAILING
BASE @ >R HEX
0. 2SWAP
BEGIN >NUMBER DUP
WHILE OVER C@ BL = IF 1 /STRING FALSE ELSE TRUE ENDIF
UNTIL THEN
R> BASE ! ( report as two 32 bit numbers )
[ 64BIT? ] [IF] 2SWAP DROP tmp ! tmp 32B@+ SWAP 32B@ 2SWAP [THEN] ;

Here code was developed on a 32-bit Forth and passed the result as a double.
To avoid massive changes, on a 64-bit Forth I splitted the return value in two
parts (a hack).

--(3)--

A binary file written by a 32-bit Forth can not be read on a 64-bit system and vv.
I found another of these in my Forth news reader (X-Newsreader: iForth 2.0 console
(October 21, 2006)) just yesterday.

--(4)--

Typically algorithms like MD5 and SHA don't work on a 64-bit system because they
explicitly use 32-bit values. This is also true for e.g. the shootout's
/bench/heapsort/heapsort.frt and /bench/random/random.frt programs.

Similar problems are with floating-point code that assumes that a single
precision float is 32-bits == 1 CELL or that a double-precision float is a
Forth double.

>>>Does that imply that > 32-bit precision rarely made a difference?

> In some cases it does make a difference. But then the difference is
> typically that you can use the program on bigger parameters or bigger
> data sets or somesuch.

With a 64-bit Forth the Euler programs are a lot less fun (their authors
develop the problems so that they're just out of 32-bit reach and
straight-forward solutions don't run).

>>> Sure, downsizing to 16 bits will often be more work or impossible, but
>>> typically because of space constraints.

>>While > 16-bit precision did often matter, but > 64K address space
>>mattered more.

16-bit code simply can't run on a 64-bit OS. I don't see my current
employer install Virtual PC on every machine just to run these (maybe
I am mistaken).

-marcel


J Thomas

unread,
Jan 2, 2010, 6:52:29 PM1/2/10
to
Anton Ertl wrote:
> Bernd Paysan <bernd....@gmx.de> writes:

>>I think the major discrepancy was between a search-path related way of
>>looking up files (as in Gforth or bigForth) vs. a macro-expanding
>>facility as implemented in VFX. Stephen Pelc argued that the macro-
>>expanding facility is very general-purpose, powerful, and can be tweaked
>>to whatever you want. However, the missing search path requires that
>>the macros are used directly in the file name, and at least as
>>implemented in VFX, it's next to impossible to make the current-file-
>>relative loading work, even when you use a macro for that - because
>>there is no "magic" macro for that purpose. And VFX has no search-path
>>list to implement a lookup semantics similar to Gforth or bigForth.
>
> That seems to be just the result of different ideas about how to build
> (and especially port) programs. Maybe I misunderstand what Stephen Pelc
> meant, but it seemed to me that his idea of porting a program (even from
> one machine to the next, using the same Forth system) involves editing
> several path macros in some files before being able to run the program
> (and maybe other chores). For me that is just unportability.
>
> For me a program is portable if I unzip it and can run it as-is.
> Anything else is various shades of unportability (and the shade can be
> measured in the time that a new user needs for the porting task).

I want to point out again that this particular issue could become
something you could handle with a library.

If you have code that navigates a virtual file system (VFS) all inside
one single file, then it isn't much of a standards issue. The new user
has to locate the single file that contains your VFS. And he has to have
code that can handle that particular VFS. Everything else will work
without needing him to do anything.

We already have standard commands to use a single file that can be found
and opened. Once you have a Forth VFS that works inside a single file,
all the OS issues go away. (Would you need two files, one for binary and
another for lines of text?) We could have, say, two or three versions of
the code that traverses a VFS, and that would probably provide enough
variety that practically everybody would be willing to use one of them.
So we could have some standard way for a .fvs source file to reveal which
navigation code it needs, and if that code is not already loaded either
load it, or tell the new user why it doesn't work, or possibly go online
and attempt to download the code from one of the sources the file
suggests. Or if you want to avoid porting problems you can have your VFS
code be the first thing loaded from your file.

If you want something that's completely portable for new users, you will
put all the libraries you call into the same VFS. There will be no
problems whether you use macros or relative or absolute paths relative
to the VFS, because it's entirely under your control. Your Forth code
manipulating your file structure inside a single OS file. Your macro
code etc will not face alien files it is not prepared for; it will be
used for the files in your VFS. You will not have any problems dealing
with foreign OSes and their file structures because you have bypassed
the OS. (You could still run into things like an OS-imposed maximum
filesize.) If it isn't foolproof it's mainly your responsibility that it
isn't.

This approach has been successfully used by other languages, notably
java and TCL. Forth could do that too.

But I have the impression that you guys want to solve a larger problem.
Not just make portable applications, but portably manipulate file
systems in any way they need to be manipulated. With some
initialization you can perhaps portably deal with complex file
hierarchies. If you have to do it, then you get your portable libraries
as an added benefit. But if you don't have to do it, would it be
worthwhile to try for the simpler goal instead?

Albert van der Horst

unread,
Jan 2, 2010, 9:21:38 PM1/2/10
to
In article <4cdf412a-25a2-4f1a...@v7g2000vbd.googlegroups.com>,
Bruce McFarling <agi...@netscape.net> wrote:
>On Jan 2, 10:54=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

Rarely? I have very few solutions for Euler problems that get by with
64 kbyte of space. It is not uncommon to run out of 32 bit space.
It is what you're doing with Forth, I suppose.
I've not solved problem 272 yet, but maybe a table of half
a million cells might come in handy.

Flashing a Renesas board and then building an image of 1 Mbyte of
memory in blocks?

Albert van der Horst

unread,
Jan 2, 2010, 9:30:37 PM1/2/10
to
In article <6071030...@frunobulax.edu>, Marcel Hendrix <m...@iae.nl> wrote:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Small, understandable Forth
>
>> J Thomas <jeth...@gmail.com> writes:
>>>Anton Ertl wrote:
>>>> I have developed the majority of the Forth code I
>>>> have written in the last 14 years on 64-bit systems, and it typically
>>>> worked on 32-bit systems the first time it ran there, just as the other
>>>> way round.
>
>There are some more or less subtle problems to watch out for. I don't have
>a 14 year experience, but the last year came up with the following examples:
>
>--(1)--
>
> 64BIT? [IF] : bessj0 ( F: r1 -- r2 ) FPOPXMM0 0 BLAS-LIB: bessj0 FFOREIGN ;
> [ELSE] : bessj0 ( F: r1 -- r2 ) FPUSHD 2 BLAS-LIB: bessj0 FFOREIGN ;
> [THEN]
>
>System calls on 64-bit OS's use SSE2 code and pass values in registers (where
>every OS has its own standard), not on the stack.

<other examples snipped>

What about this one?

1 ARG[] TYPE

doesn't work any more on ciforth.

1 ARG[] returns an address length pair with the first argument,
e.g. "-e" (load electives).
But this is located in memory above $8000,0000,0000,0000
The system call behind TYPE (write) can't handle addresses
above $7FFF,FFFF

>-marcel

Josh Grams

unread,
Jan 3, 2010, 9:07:09 AM1/3/10
to
Anton Ertl wrote: <2010Jan...@mips.complang.tuwien.ac.at>

> Josh Grams <jo...@qualdan.com> writes:
>>Yes, I know, but that's a totally different issue. I don't want "easily
>>ported", I want "write once, run anywhere"
>
> Yes, I think that we should have a standard that makes that possible.
> Unfortunately, some others are less ambitious.

I'm almost that ambitious -- I just don't see a good C interface
becoming standardized any time soon...

>>(for values of "anywhere"
>>which include at least Windows, OSX, and various Linuxes). I assume
>>that, if this ever becomes possible, it will be in the form of one Forth
>>system which has been ported to many different places.
>
> Gforth runs on all the OSs you mentioned. But I guess you are still
> missing pre-existing bindings to external libraries in Gforth. Yes,
> that will take a little more time.

Yeah, gforth is getting very close. I keep forgetting that it works on
OSX now. I'm a little leery of the C interface requiring a C compiler
at runtime. But with a little fiddling I should be able to install a
cross toolchain on my Linux box and pre-generate the libraries for
Windows from there. Hmm...might have to do that for OSX as well -- or
does it come out of the box with a C compiler?

--Josh

Josh Grams

unread,
Jan 3, 2010, 10:18:49 AM1/3/10
to
Bruce McFarling wrote:
> On Jan 1, 8:47 am, Josh Grams <j...@qualdan.com> wrote:
> ...

>> Can I see your code? I have accumulated enough bits of compatibility
>> code that I decided I need some sort of helper code to load them. I've
>> been trying to design a Forth package manager that can start out very
>> simple, but whose design won't impede later extension. So I'd be
>> curious to see what you have done...
>
> It's just building a vocabulary hierarchy from scratch, a registry

> vocabulary, and having some words for testing for the existence of
> version constants.
>
> This library system is built on the concept of three levels of file.
... ordinary forth scripts (.fs), Niclos file scripts (.nfs), and Niclos
library scripts (.nls).

> I don't have anything from the .nls level that has been tested yet
> (that's why the word to export a version constant into the []Niclos
> vocabulary is not below), but here is an unstable alpha of the .nfs
> support. Given that the system is to be self-boostrapping, the
> foundation for the .nfs level is a .fs file, and the foundation for
> the .nls is a .nfs file.

Ah, excellent. That's very much what I was thinking. Though I'd like
to provide a more abstract interface to allow for other implementation
techniques.


> BL WORD []Niclos[] FIND NIP [IF]

Note that the standard only requires WORD to provide one buffer, and it
is sometimes used for the interpreter, so this may not work on some
systems (e.g. Win32Forth?).


> Ordinary forth script files (.fs) assume that the words they use are


> available and just compile into the CURRENT vocabulary when they are
> called.
>
> Niclos file scripts know about the existence of the []Niclos[]
> hierarchy, install themselves, and may export their target public
> words to FORTH or to the CURRENT vocabulary at the time they are
> called. They may INCLUDE ordinary forth file script files or other
> niclos file script files, but only in the directory in which they are
> located or the current working directory.
>
> Niclos library scripts (.nls) perform version control and engage in
> optional compilation in response to tokens handed to the script in a
> dedicated command stack, and also navigate the Niclos file hierarchy
> system.

I was basing my ideas on existing package managers (Debian's apt-get,
Gentoo's portage, Perl's CPAN, BSD's ports, Python modules, Ruby gems,
etc., etc., etc.). So my three levels are:

- Ordinary forth source files or archives.

- Package specification files which declare what features are provided
and what dependencies are required, and conditionally include the
appropriate sources.

- A package manager tool which searches a dependency graph constructed
from the package specs and loads the necessary sources.

Since I want it to be usable for non-standard Forths as well, I decided
not to go overboard trying to write the package manager in plain vanilla
standard Forth. I'll settle for it being easily portable, since that
only has to be done once for each Forth system, and it should be useful
enough to justify that effort.

So here's what I'm thinking:

Features (packages) are referred to by whitespace delimited names. A
feature can be either a Forth word or a collection of other features.
So we have a tree of features. You request a feature using a selector,
a space-separated list of names which is used as a search pattern on the
full feature paths. So "foo bar" would find any "bar" with an ancestor
"foo", and you can request features however vaguely or specifically you
like.

The basic interface for specifying packages is:

DEMAND ( c-addr u -- ) \ c-addr u is a selector
Declare a dependency on another feature.

FULFILL-DEMANDS ( -- )
Load packages to fill all unsatisfed dependencies.

SUPPLY ( c-addr u -- ) \ c-addr u is a single name
SUPPLIED ( -- )
Mark the start and end of a feature.

SUPPLY? ( c-addr u -- flag ) \ c-addr u is a single name
Should we load this feature? Use with [IF] ... [THEN]

Then of course there are parsing versions of the string words.

Versions can be handled pretty generically: just like any other
sub-package, except that you normally only want to load one version,
whereas you want to load all sub-packages which make up a feature. So
we just need a word to mark a sub-package as being an alternate version.

Then I think I'll take a page from djb's book, and keep a separate
ordered list of versions for each package, with major versions marked.
That way we can accomodate whatever wacky version numbering scheme a
developer may dream up, and they don't have to conform to any particular
format, or sort lexically in the correct order, or anything like that.

Also I probably want words to give the URL of the source code, maybe a
manifest file so you can verify the sources, patch files, or whatever.
And it would be cool if the selector parsing allowed using inequalities
to request a version (>=1.0, <2.0, etc.).

And...I'll stop now. I can think of all kinds of other extensions and
conveniences to add, but I need to get the basics working before I get
too carried away. :)

--Josh

Helmar

unread,
Jan 3, 2010, 3:56:55 PM1/3/10
to
On Jan 3, 10:18 am, Josh Grams <j...@qualdan.com> wrote:

> I was basing my ideas on existing package managers (Debian's apt-get,
> Gentoo's portage, Perl's CPAN, BSD's ports, Python modules, Ruby gems,
> etc., etc., etc.).

Did you recognize that these problems with package managers are
community problems? Try to follow the discussion of OpenSolaris to see
why this is so ;)

>  So my three levels are:
>
> - Ordinary forth source files or archives.
>
> - Package specification files which declare what features are provided
>   and what dependencies are required, and conditionally include the
>   appropriate sources.
>
> - A package manager tool which searches a dependency graph constructed
>   from the package specs and loads the necessary sources.

Ah, well. Why package specifications?
Did you ever see
> http://code.google.com/p/forth4p/source/browse/helper/4pdep
? That works without and usually can give you a good description of
what depends on what. Very simple, no Forth since it's used to build
the Forth in a non-Forth environment.

Regards,
-Helmar

Josh Grams

unread,
Jan 4, 2010, 8:44:40 AM1/4/10
to
Helmar wrote:
> On Jan 3, 10:18 am, Josh Grams <j...@qualdan.com> wrote:
>
>> I was basing my ideas on existing package managers (Debian's apt-get,
>> Gentoo's portage, Perl's CPAN, BSD's ports, Python modules, Ruby gems,
>> etc., etc., etc.).
>
> Did you recognize that these problems with package managers are
> community problems? Try to follow the discussion of OpenSolaris to see
> why this is so ;)

Sorry, what problems are you talking about? I haven't noticed any
serious problems with any of the package managers that I have used. And
where can I find this OpenSolaris discussion? I did a bit of searching
around, and looked through a bit of the archives for a couple of their
bajillion e-mail lists, and didn't see anything that looked relevant...

Right now I'm not particularly concerned about community problems,
unless they arise from technical limitations. I'm not trying to build a
community -- I'm trying to write a simple tool to make my life easier.
I do hope that if I do a good job, it will be useful to other people.
So I want to design with that in mind. But I'm not going to worry too
much about community until I have reason to believe that there will *be*
a community. :)

>> So my three levels are:
>>
>> - Ordinary forth source files or archives.
>>
>> - Package specification files which declare what features are provided
>> and what dependencies are required, and conditionally include the
>> appropriate sources.
>>
>> - A package manager tool which searches a dependency graph constructed
>> from the package specs and loads the necessary sources.
>
> Ah, well. Why package specifications?
> Did you ever see
>> http://code.google.com/p/forth4p/source/browse/helper/4pdep

> That works without and usually can give you a good description of
> what depends on what. Very simple, no Forth since it's used to build
> the Forth in a non-Forth environment.

Some dependencies aren't easily extracted from the source, so I need to
support declaring them manually. I do want to autogenerate the obvious
stuff. And the package declarations *could* be in the same file as the
source, but for various reasons I think it is usually better to keep
them separate.

--Josh

Anton Ertl

unread,
Jan 5, 2010, 11:24:44 AM1/5/10
to
m...@iae.nl (Marcel Hendrix) writes:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Small, understandable Forth
>
>> J Thomas <jeth...@gmail.com> writes:
>>>Anton Ertl wrote:
>>>> I have developed the majority of the Forth code I
>>>> have written in the last 14 years on 64-bit systems, and it typically
>>>> worked on 32-bit systems the first time it ran there, just as the other
>>>> way round.
>
>There are some more or less subtle problems to watch out for. I don't have
>a 14 year experience, but the last year came up with the following examples:
>
>--(1)--
>
> 64BIT? [IF] : bessj0 ( F: r1 -- r2 ) FPOPXMM0 0 BLAS-LIB: bessj0 FFOREIGN ;
> [ELSE] : bessj0 ( F: r1 -- r2 ) FPUSHD 2 BLAS-LIB: bessj0 FFOREIGN ;
> [THEN]
>
>System calls on 64-bit OS's use SSE2 code and pass values in registers (where
>every OS has its own standard), not on the stack.

That's not a Forth issue.

Different architectures definitely have different ABIs (and calling
conventions), even if the cell size is the same; e.g., you won't use
SSE2 on PowerPC64 or Alpha. And sometimes even different OSs on the
same architecture have different ABIs. If you let the ABI pollute
your Forth code instead of isolating it in a foreign function
interface, you will have portability problems, yes; but they come from
the ABI and the (lack of a decent) foreign function interface, not
from Forth.

>--(2)--
>
>\ does all digits at once, skipping blanks
>: >DHEX ( c-addr1 u1 -- d c-addr2 u2 )
> -LEADING -TRAILING
> BASE @ >R HEX
> 0. 2SWAP
> BEGIN >NUMBER DUP
> WHILE OVER C@ BL = IF 1 /STRING FALSE ELSE TRUE ENDIF
> UNTIL THEN
> R> BASE ! ( report as two 32 bit numbers )
> [ 64BIT? ] [IF] 2SWAP DROP tmp ! tmp 32B@+ SWAP 32B@ 2SWAP [THEN] ;
>
>Here code was developed on a 32-bit Forth and passed the result as a double.
>To avoid massive changes, on a 64-bit Forth I splitted the return value in two
>parts (a hack).

What's wrong with just passing a double in any case? Where does this
requirement of "report as two 32 bit numbers" come from? That's the
culprit for this non-portability.

>--(3)--
>
>A binary file written by a 32-bit Forth can not be read on a 64-bit system and vv.

Yes, binary files can cause problems in communicating between
different cell sizes and byte orders; therefore, my preferred way of
communication is text files. If I use binary files, then I usually
define everything in number of bits or bytes, not in cells.

Binary files are the only place where I remember having to do
something special for different cell sizes: It had to do with creating
a Gforth image; the target can have a different cell size than the
running system, and the cell size dependency was on the target cell
size.

>I found another of these in my Forth news reader (X-Newsreader: iForth 2.0 console
>(October 21, 2006)) just yesterday.

Maybe you could add a function to your newsreader that warns you when
you post non-quoted lines that are longer then about 70 characters, as
you did several times in this posting.

>--(4)--
>
>Typically algorithms like MD5 and SHA don't work on a 64-bit system because they
>explicitly use 32-bit values. This is also true for e.g. the shootout's
>/bench/heapsort/heapsort.frt and /bench/random/random.frt programs.

Most of these are probably due to differences in overflow behaviour (I
would not expect that of a heapsort program, though).

>Similar problems are with floating-point code that assumes that a single
>precision float is 32-bits == 1 CELL or that a double-precision float is a
>Forth double.

Why would code assume that?

>With a 64-bit Forth the Euler programs are a lot less fun (their authors
>develop the problems so that they're just out of 32-bit reach and
>straight-forward solutions don't run).

You mean, they develop the tasks such that languages with bigints look
good? I guess they should develop them to be just out of reach of
128-bit integers, then.

Anton Ertl

unread,
Jan 5, 2010, 12:56:01 PM1/5/10
to
Josh Grams <jo...@qualdan.com> writes:
>I'm a little leery of the C interface requiring a C compiler
>at runtime.

The plan is to pre-generate the interface files for the common
libraries at Gforth build time, then you don't need a C compiler at
run time in most cases. And if you want to interface to a C library
you have written yourself, you'll have a C compiler anyway.

>But with a little fiddling I should be able to install a
>cross toolchain on my Linux box and pre-generate the libraries for
>Windows from there.

Cross-building Gforth is not easy. I would rather recommend
installing Cygwin on Windows, and building Gforth there, including
pre-generating the interface files.

Anton Ertl

unread,
Jan 5, 2010, 1:34:06 PM1/5/10
to
Josh Grams <jo...@qualdan.com> writes:
>Bernd Paysan wrote: <8ia417-...@vimes.paysan.nom>
>> Anton Ertl wrote:
[...]

>You can get
>along fine with include paths relative to the current working directory
>if you have no a flat project layout, or one which is static enough that
>you always put a file at the same place relative to the root of the
>project tree.

"Relative to the working directory" is a pain, because I want to refer
to my data files through the working directory.

E.g., in Gforth I can do stuff like

gforth ~/forth/foo/main.fs -e "foo datafile bye"

or somesuch, and main.fs will look for the files it INCLUDEs in
~/forth/foo/; and if I install the foo package elsewhere, it will look
there; and it will access "datafile" in the working directory.

On a Forth system that interprets relative file names in INCLUDEs as
relative to the working directory, I have to work around that, e.g.,
like this

(cd ~/forth/foo/ && vfxlin "include main.fs foo /path/to/datafile bye")

Moreover, that does not work properly when an independently developed
library sits in its own subdirectory, so you have to throw all the
libraries and their files in the same directory as the main program.

>And if you have macros, you can have a macro pointing to
>your Library or System folder, and put them somewhere outside your
>project.

Then the unzip-and-run approach is not possible. You need to copy the
libraries to the Library folder first, and hope that there's no name
or version clash there. And the library would have to know that it's
always installed in the directory specified by a specific macro.

Having a library directory may be a good idea for reusing libraries,
especially if we have a package management system that deals with
that, but that's far in the future. And even then I want to be able
to, say, work on a new version of the library without having to change
all the INCLUDEs referring to other files in the library.

>So I want each sub-directory to be a
>self-contained unit that I can move around at will, without having to
>worry about where it is in relation to the root of my project tree.

Yes, or some system or library root directory.

>>> 2) F" etc. has the advantage that it does not just work for INCLUDED
>>> and friends, but also for OPEN-FILE (e.g., for accessing a data file
>>> coming with the application), and even if the OPEN-FILE or INCLUDED
>>> happens in a different file than the string (e.g., if the file names
>>> are stored in an array and only loaded later, maybe on-demand). So I
>>> think we should have that even if we agree on 1).
>
>My reaction when I first saw that proposal was that doing the path
>search when you parse the string seemed like a bad idea

The idea in F" is actually not to do a path search. F" just refers to
files relative to the directory of the current source file. I.e., you
would specify a relative name in your source file, and F" would just
prepend the directory of the current source file, resulting in an
absolute file name (or maybe wd-relative file name, but that's only ok
if the wd is not changed before the use).

> -- it seems like
>it should happen when you're actually going to do something with the
>file.

Doing a path search in F" is also an interesting idea. Apart from the
source-file directory the other components of the path normally don't
change between F" and the use of the file (except maybe the wd). As
long as we only care about the existence and readability of the file
or somesuch, it should be good enough to do it during F". However, if
we have more specific acceptance criteria (such as a particular data
format), the search should be performed by the user of the file name.

Unfortunately, once F" has converted the name into an absolute name,
we have lost the information about the relative file name, so we would
need additional complications to support that, and I don't see an
elegant solution at the moment.

>> In Gforth we have OPEN-FPATH-FILE, which opens a file with the same
>> search mechanism as INCLUDED. bigForth goes a bit further, and applies
>> the search mechanism to OPEN-FILE itself - same idea as with VFX: if you
>> use it in one place, use it everywhere.
>
>I like having the path search mechanism generally available -- I have
>taken advantage of that a couple of times. But I don't think I usually
>want it for dealing with data files, so putting it in OPEN-FILE seems
>like one step too far. I'd rather find my data directory as a whole,
>and have the OPEN-FILE fail if a file isn't there, rather than trying to
>search for it other places on a per-file basis...

Doing the path search for each individual file can be quite flexible
and a benefit to the program's user: E.g., I remember a game that
searched for some files among its own directories as well as one of my
directories. I could just drop in a file in my directory without
affecting the general setup.

BTW, OPEN-FPATH-FILE uses the Forth source path. There is also
OPEN-PATH-FILE to which you pass an arbitrary path. That's probably
more useful for data files.

Marcel Hendrix

unread,
Jan 5, 2010, 1:28:06 PM1/5/10
to
an...@a4.complang.tuwien.ac.at (Anton Ertl) writes Re: cell size portability (was: Small, understandable Forth)

> m...@iae.nl (Marcel Hendrix) writes:
>>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Small, understandable Forth

>>System calls on 64-bit OS's use SSE2 code and pass values in

>> registers (where every OS has its own standard), not on the stack.

> That's not a Forth issue.

Not after 14 years.

> Different architectures definitely have different ABIs (and calling
> conventions), even if the cell size is the same; e.g., you won't use
> SSE2 on PowerPC64 or Alpha. And sometimes even different OSs on the
> same architecture have different ABIs. If you let the ABI pollute
> your Forth code instead of isolating it in a foreign function
> interface, you will have portability problems, yes; but they come from
> the ABI and the (lack of a decent) foreign function interface, not
> from Forth.

The FLAG specification is there now and it is good for at least 3
major OS's. PowerPC64 and Alpha hardware are a problem for people
writing CODE on the bare metal, but I guess they won't mind solving
the resulting issues themselves.

>> [ 64BIT? ] [IF] 2SWAP DROP tmp ! tmp 32B@+ SWAP 32B@ 2SWAP [THEN] ;

>> Here code was developed on a 32-bit Forth and passed the result as
>> a double. To avoid massive changes, on a 64-bit Forth I splitted
>> the return value in two parts (a hack).

> What's wrong with just passing a double in any case? Where does
> this requirement of "report as two 32 bit numbers" come from?
> That's the culprit for this non-portability.

It was not my design, the code was large and unfamiliar, and I didn't
want to check every call location.

BTW, the other way round is much harder. I had to bootstrap my 64-bits
Forth with a 32-bit metacompiler and then e.g. number conversion and
64-bit address and data specification issues pop up. Of course I
wanted to compile the source code for the metacompiler and assembler
/ disassembler on the 64-bit Forth eventually. You might be right
claiming that is not a Forth issue either.

>> I found another of these in my Forth news reader (X-Newsreader:
>> iForth 2.0 console (October 21, 2006)) just yesterday.

> Maybe you could add a function to your newsreader that warns you when
> you post non-quoted lines that are longer then about 70 characters,
> as you did several times in this posting.

People on this newsgroup persist in doing much worse things, but I
see your point and will try to do something about mine.

>>--(4)--

>>Typically algorithms like MD5 and SHA don't work on a 64-bit system
>> because they explicitly use 32-bit values. This is also true for
>> e.g. the shootout's /bench/heapsort/heapsort.frt and
>> /bench/random/random.frt programs.

> Most of these are probably due to differences in overflow behaviour (I
> would not expect that of a heapsort program, though).

ISTR it is the random number generator.

>> Similar problems are with floating-point code that assumes that a
>> single precision float is 32-bits == 1 CELL or that a
>> double-precision float is a Forth double.

> Why would code assume that?

Well, there used to be people that put floats on the data stack :-)
And old ABI's require floats on the C stack, not in the FPU.

>> With a 64-bit Forth the Euler programs are a lot less fun (their
>> authors develop the problems so that they're just out of 32-bit
>> reach and straight-forward solutions don't run).

> You mean, they develop the tasks such that languages with bigints
> look good? I guess they should develop them to be just out of
> reach of 128-bit integers, then.

Pyrrhus: Some languages that have bigints would then not finish before
the end of time.

-marcel

Anton Ertl

unread,
Jan 5, 2010, 2:15:40 PM1/5/10
to
steph...@mpeforth.com (Stephen Pelc) writes:
>That's a good summary, but excludes why we do not like search paths.
>1) They are prone to error in name conflicts between files, e.g.
>the original version supplied with a system and the one modified
>by an application programmer.

With power comes responsibility. I think search paths are worth their
cost in error-proneness.

But in any case, F" and friends is not about search paths. It's about
referring to the current source-file's directory. No search involved.

>2) They are restricted to use with files.

And what's the problem with that?

>Many application developers keep their projects well away from
>the Forth system that hosts it. When you move application source
>code from (say) the development desktop to a laptop for
>commissioning, you need an unambiguous way of defining
>exactly where you expect to find the files.
>
>At the expense of some set up, text macros permit us to do this.

And with F", you can do the same without any expense in set up.

>All you are arguing for is a macro that is relative to some folder.
>a) IDIR - relative to the current include file

So you would have us write

include %IDIR%/file.fs \ variant 1

where I would write

include file.fs \ variant 2

or

include ./file.fs \ variant 3

or

F" file.fs" included \ variant 4

Not so bad. However, I think that most programmers would prefer
variant 2, though. Morover, variant 1 does not even work in VFX
Forth, whereas variant 2 and 3 work in Gforth and other systems, so
they have more existing practice:

vfxlin says:

include tmp/test1.fs
Including tmp/test1.fs
Including %IDIR%/test2.fs
Err# -258 ERR: Failed to open requested file.
Source: "tmp/test1.fs" on line 1
-> include %IDIR%/test2.fs
^
even though tmp/test2.fs exists.

In contrast (variant 2):

[c8:~:26710] echo "include test2.fs" >tmp/test1.fs
[c8:~:26711] echo ".( hello) cr" >tmp/test2.fs
[c8:~:26712] gforth tmp/test1.fs -e bye
hello

>b) CDIR - the current working directory

Why should a source file refer to that? A properly written program
works wherever the wd is, so it typically does not refer to the
working directory.

Of course, it would be nice if the user of such a program had a
system-independent way of referring to the wd when he calls the
program, but that's not necessary for the program to be portable.
It's in the same category as finding consensus about the OS
command-line interface for Forth systems.

>c) LDIR - the directory containing the executable

Why should a source file refer to that?

>F" is simply a wrapper - it makes it easier to add a "sort of" macro
>system to those that don't have it, but it's second rate compared to
>real macros.

For you it could be a simple wrapper, for others it would be much
simpler to implement than a full macro package. But more importantly,
I think that it's more likely that people write

include foo.fs

instead of

include %IDIR%/foo.fs

That's especially likely, because even on those systems that implement
working-directory-relative file names rather than source-directory
relative file names, the former will work in typical development test
(where the two directories are the same) will still work. But once
the directories are different, only the systems with source-directory
relative file names will work as intended.

So if you want people to use %IDIR% etc., you have to make your system
produce an error or somesuch when they leave the %IDIR% away.

Or alternatively, we could standardize on the behaviour where the
straightforward code actually works, even if the wd is elsewhere.

>Anton's objection to macros using '%' as a delimiter, e.g.
> %idir%/foobar.fs
>is that % is found in Unix file systems.

No, that's mostly resolved with the addition of the unescaping stuff
(whatever we want to call it). I still fear that this will not be
used as it should, but at least it's possible.

My main objections are:

1) It requires more effort from the programmer (adding %IDIR% and
unescaping in a number of places), and it's error-prone especially
because leaving away necessary %IDIR%s and unescapings may not show up
in ordinary testing (so they have to add special testing for that).

2) It requires a lot more implementation complexity in many Forth
systems than F". You claim that your approach also covers the F"
case, but if that is the case, why does %IDIR% not work in vfxlin?

3) Your ideas about the "expense of some set up" are the antithesis of
portability.

> modifying the behaviour of unfound macros to pass
>everything including the delimiter fixes the rest.

Actually that makes it likely to miss a missing unescape. It would be
a good idea to report a % in the wrong place as an error at least
during testing.

>Search paths work fairly well when you are devloping new system
>components. They just do not scale well to large apps.

That's why TeX has its own path search library (kpathsearch), because
it's not a large application. And the game I mentioned elsewhere
(maybe Unreal Tournament) also is no large application IYO.

IMO for small and unflexible applications you don't need a search path
mechanism, because you know where everything is. But if you need more
flexibility (e.g., because you want to accomodate a lot of add-ons
like TeX and the game), you need the flexibility of search paths. And
for a really large application that added flexibility can be useful
even when developing the core application.

But again, F" and friends is not about search paths. Nobody needs to
implement search paths in order to implement F".

Anton Ertl

unread,
Jan 5, 2010, 3:10:05 PM1/5/10
to
J Thomas <jeth...@gmail.com> writes:
>If you have code that navigates a virtual file system (VFS) all inside
>one single file, then it isn't much of a standards issue. The new user
>has to locate the single file that contains your VFS. And he has to have
>code that can handle that particular VFS. Everything else will work
>without needing him to do anything.

I don't think that such a thing will become popular. We have
abandoned blocks for files, because we want to be able to use other
tools for the environment we are using in addition to the Forth system
and Forth tools. The same reason will make us ignore such a private
file system.

Moreover, in order to support such a private file system, we have to
reimplement substantial parts of the system (in particular INCLUDE).
If we are able and prepared to do that, we can just as well do it for
implementing the features we want (source-directory relative includes,
maybe search paths) for the native file system of the OS for less
work.

>But I have the impression that you guys want to solve a larger problem.
>Not just make portable applications, but portably manipulate file
>systems in any way they need to be manipulated.

Certainly I want to be able to write utilities in Forth that deal with
files. And I don't want the utility to fail just because it thinks it
sees a macro name in one of the file names I passed to it. I have
quite a bit of experience with such problems, and IMO Forth should not
become another sh or another perl (i.e., languages unfit for the
purpose because they tend to mangle file names because they think they
see their meta-characters in them).

Stephen Pelc

unread,
Jan 5, 2010, 5:44:54 PM1/5/10
to
On Tue, 05 Jan 2010 19:15:40 GMT, an...@a4.complang.tuwien.ac.at
(Anton Ertl) wrote:

>Not so bad. However, I think that most programmers would prefer
>variant 2, though. Morover, variant 1 does not even work in VFX
>Forth, whereas variant 2 and 3 work in Gforth and other systems, so
>they have more existing practice:
>
>vfxlin says:
>
>include tmp/test1.fs
>Including tmp/test1.fs
>Including %IDIR%/test2.fs
>Err# -258 ERR: Failed to open requested file.
> Source: "tmp/test1.fs" on line 1
> -> include %IDIR%/test2.fs

Because IDIR isn't implemented by default! Why, because no *user*
has requested it.

>>c) LDIR - the directory containing the executable
>
>Why should a source file refer to that?

Because there are operating systems other than Unix with different
working conventions. Macros are usable for applications as well as
"just" for compiling source code. That's one reason why we like
them.

>3) Your ideas about the "expense of some set up" are the antithesis of
>portability.

We have not yet ported a significant component or application that has
not required some host-dependent layer. Having to adjust one macro is
trivial compared to the porting effort.

>IMO for small and unflexible applications you don't need a search path
>mechanism, because you know where everything is. But if you need more
>flexibility (e.g., because you want to accomodate a lot of add-ons
>like TeX and the game), you need the flexibility of search paths. And
>for a really large application that added flexibility can be useful
>even when developing the core application.

IMHO you need to be able to specify the root directory of a component
and compile a group of files relative to that root.

Bernd Paysan

unread,
Jan 5, 2010, 5:57:31 PM1/5/10
to
Stephen Pelc wrote:
> IMHO you need to be able to specify the root directory of a component
> and compile a group of files relative to that root.

Ah, I see you have finally understood *what* we want - it's precisely
*this* specification. Now next step is that you understand why our
solution does that, and why it's better than macros - because it's
implicit. If you load the loader file of your component, all other
files are located relative to this loader file.

BTW: User requests don't say anything. Users rarely understand the
problem well enough to ask the right question.

J Thomas

unread,
Jan 5, 2010, 10:32:47 PM1/5/10
to
Anton Ertl wrote:
> J Thomas <jeth...@gmail.com> writes:

>>If you have code that navigates a virtual file system (VFS) all inside
>>one single file, then it isn't much of a standards issue. The new user
>>has to locate the single file that contains your VFS. And he has to have
>>code that can handle that particular VFS. Everything else will work
>>without needing him to do anything.
>
> I don't think that such a thing will become popular. We have abandoned
> blocks for files, because we want to be able to use other tools for the
> environment we are using in addition to the Forth system and Forth
> tools. The same reason will make us ignore such a private file system.

The way they did it for TCL starkits, first you develop your app using
your native systems's files. Then when you're ready to ship it, you run a
routine that converts your source code to a VFS. Your user then needs two
or three files to run your app. He needs a TCL that runs on his system
and is the correct version number. And he needs the file that contains
your app.

Maybe you have a generalised app and for a specialised application you
want a third file that specifies a particular format. For example, there
is a wiki app that needs a third file to hold the data, and even if most
of the wiki starts out empty, you still want to provide the help files.
But often you can initialise the data files empty and the user doesn't
have to even know about them, much less install them.

If you want to edit the source files they have tools to expand them into
a regular directory tree, provided that your system is compatible with
the tree that the author used. Then when you're done you can roll them
back up into a starkit again.

This makes apps that are quite portable. If there is a TCL interpreter
that
runs on a particular platform, and there is enough memory and disk space,
then the app will run. It is completely independent of the host directory
structure because the app is all in one file, and the data is in one or
more files in the same folder. The user must install TCL so it can access
that folder, and TCL does the rest.

Similarly, consider java .jar files. The jar system still gives you a
java mess of files, but think what it would be like without jar files!

> Moreover, in order to support such a private file system, we have to
> reimplement substantial parts of the system (in particular INCLUDE). If
> we are able and prepared to do that, we can just as well do it for
> implementing the features we want (source-directory relative includes,
> maybe search paths) for the native file system of the OS for less work.

You would need a virtual file system. Just one, because if you can do it
in Forth using the inside of one file, then you can do it on any system
that gives you OPEN-FILE etc. Presumably you would build VFS-INCLUDE and
if you want to you could have a way for VFS-INCLUDE to check whether the
current source is inside a virtual file system, and call INCLUDE if it
is not. Then you could use the same make files whether your sources are
unrolled or not.

My original point was that if you have code to do this, in a library,
then you don't need to create a standard for implementors to each
re-create for their own native file systems. This library will work for
source code on any standard system, without a standard. That's a good
thing. But it does not give you the tools to portably deal with host file
systems, and that's something that individual applications might want to
do apart from the issue of installing Forth apps. So it doesn't give you
everything you might want. Still there's a great big advantage when you
can do things without an additional standsard.



>>But I have the impression that you guys want to solve a larger problem.
>>Not just make portable applications, but portably manipulate file
>>systems in any way they need to be manipulated.
>
> Certainly I want to be able to write utilities in Forth that deal with
> files. And I don't want the utility to fail just because it thinks it
> sees a macro name in one of the file names I passed to it. I have quite
> a bit of experience with such problems, and IMO Forth should not become
> another sh or another perl (i.e., languages unfit for the purpose
> because they tend to mangle file names because they think they see their
> meta-characters in them).

Sure. To the extent you can do it in a VFS, you can control that. If you
want special macro names or special characters to tell you it's a macro
then you can design your file system to avoid those names or characters.
It's all in Forth and it's all under your control. That's valuable, if it
fits your needs. You save yourself the problems of predicting what an
Apple or BeOS or whatever file system might do. Your stuff works
everywhere that a standard Forth will run.

But by avoiding the problems of foreign file systems it doesn't help you
actually manipulate foreign file systems.

a...@littlepinkcloud.invalid

unread,
Jan 6, 2010, 5:20:19 AM1/6/10
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:

> Maybe I misunderstand what Stephen Pelc meant, but it seemed to me
> that his idea of porting a program (even from one machine to the
> next, using the same Forth system) involves editing several path
> macros in some files before being able to run the program (and maybe
> other chores). For me that is just unportability.

That is a rather absolutist black-and-white view of the issue.

> For me a program is portable if I unzip it and can run it as-is.
> Anything else is various shades of unportability (and the shade can
> be measured in the time that a new user needs for the porting task).

Given that Forth runs in many applications without any external
operating system, the notion of "unzip and run" is, obviously, not
universally applicable to Forths. "unzip and run" assumes that your
OS supports a hierarchical filesystem with files that are strings of
bytes.

Portability is a continuum, with absolute portability (i.e. unzip and
run) at one end. Absolute portability is one desirable attribute of a
programming langauge, but it's not the only one. The question here is
whether it's worth striving for.

Andrew.

Albert van der Horst

unread,
Jan 6, 2010, 7:20:45 AM1/6/10
to
In article <2010Jan...@a4.complang.tuwien.ac.at>,
Anton Ertl <an...@a4.complang.tuwien.ac.at> wrote:
>m...@iae.nl (Marcel Hendrix) writes:
<SNIP>

>
>>With a 64-bit Forth the Euler programs are a lot less fun (their authors
>>develop the problems so that they're just out of 32-bit reach and
>>straight-forward solutions don't run).
>
>You mean, they develop the tasks such that languages with bigints look
>good? I guess they should develop them to be just out of reach of
>128-bit integers, then.

One of the latest problem (269) requires an answer modulo 10**8.
Rather 32-bit friendly I would say.
There is not too much that can be said in general about Euler
problems. Sometimes the answer wouldn't fit 128 bit neither.
If floating point is needed, they generally ask a lot of precision
such that REAL*4 FORTRAN wouldn't work.
But it is true that one benefits from having 64 bits, and
especially a large memory space.

Also naive solution tend to run for hours or years,
while one should aim at seconds. Over 2 years one can
see that the demands on computing power have gone up.

If you use Python, you need not bother about integer size at all.
My solution calculates the 60 digit number then prints them
modulo 10**8. (No I wouldn't program like that in Forth.)

>
>- anton
>--

Josh Grams

unread,
Jan 6, 2010, 8:40:04 AM1/6/10
to
Anton Ertl wrote: <2010Jan...@a4.complang.tuwien.ac.at>

> Josh Grams <jo...@qualdan.com> writes:
>>I'm a little leery of the C interface requiring a C compiler
>>at runtime.
>
> The plan is to pre-generate the interface files for the common
> libraries at Gforth build time, then you don't need a C compiler at
> run time in most cases. And if you want to interface to a C library
> you have written yourself, you'll have a C compiler anyway.
>
>>But with a little fiddling I should be able to install a
>>cross toolchain on my Linux box and pre-generate the libraries for
>>Windows from there.
>
> Cross-building Gforth is not easy. I would rather recommend
> installing Cygwin on Windows, and building Gforth there, including
> pre-generating the interface files.

Oh. Would I have to cross-build gforth? I was thinking I could just
install a cross gcc/libtool and have libcc.fs use that to build the
interface files. I figured at worst I'd have to grab a libcc.h from a
Windows build...

--Josh

Anton Ertl

unread,
Jan 6, 2010, 10:17:18 AM1/6/10
to
Josh Grams <jo...@qualdan.com> writes:
>Anton Ertl wrote: <2010Jan...@a4.complang.tuwien.ac.at>

>> Cross-building Gforth is not easy. I would rather recommend
>> installing Cygwin on Windows, and building Gforth there, including
>> pre-generating the interface files.
>
>Oh. Would I have to cross-build gforth? I was thinking I could just
>install a cross gcc/libtool and have libcc.fs use that to build the
>interface files. I figured at worst I'd have to grab a libcc.h from a
>Windows build...

Ah, that's different. You don't need to cross-build Gforth for that.
And I guess you would run libcc.fs from the Linux Gforth, right? Ok,
that might work far enough to generate the files you need (but the
Linux linker won't successfully link these Windows shared objects with
the Linux Gforth image). Still, if you want to run Gforth with
foreign functions in Windows, in the long run the Cygwin path looks
like less trouble to me.

Anton Ertl

unread,
Jan 6, 2010, 10:28:23 AM1/6/10
to
m...@iae.nl (Marcel Hendrix) writes:
>an...@a4.complang.tuwien.ac.at (Anton Ertl) writes Re: cell size portability (was: Small, understandable Forth)
>
>> m...@iae.nl (Marcel Hendrix) writes:
>>>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Small, understandable Forth
>
>>>System calls on 64-bit OS's use SSE2 code and pass values in
>>> registers (where every OS has its own standard), not on the stack.
>
>> That's not a Forth issue.
>
>Not after 14 years.

You lost me here. BTW, SSE2 is less than 14 years old.

>> Different architectures definitely have different ABIs (and calling
>> conventions), even if the cell size is the same; e.g., you won't use
>> SSE2 on PowerPC64 or Alpha. And sometimes even different OSs on the
>> same architecture have different ABIs. If you let the ABI pollute
>> your Forth code instead of isolating it in a foreign function
>> interface, you will have portability problems, yes; but they come from
>> the ABI and the (lack of a decent) foreign function interface, not
>> from Forth.
>
>The FLAG specification is there now and it is good for at least 3
>major OS's. PowerPC64 and Alpha hardware are a problem for people
>writing CODE on the bare metal, but I guess they won't mind solving
>the resulting issues themselves.

Or maybe they will just use Gforth which has a foreign function
interface that does not require the users to know the target platform
and its ABI.

>>> [ 64BIT? ] [IF] 2SWAP DROP tmp ! tmp 32B@+ SWAP 32B@ 2SWAP [THEN] ;
>
>>> Here code was developed on a 32-bit Forth and passed the result as
>>> a double. To avoid massive changes, on a 64-bit Forth I splitted
>>> the return value in two parts (a hack).
>
>> What's wrong with just passing a double in any case? Where does
>> this requirement of "report as two 32 bit numbers" come from?
>> That's the culprit for this non-portability.
>
>It was not my design, the code was large and unfamiliar, and I didn't
>want to check every call location.

That seems even stranger. Who told you that the callers did not just
use the doubles as doubles (e.g., print with "D."); then this approach
would break (or at least should, if D. etc. are implemented
correctly).

>BTW, the other way round is much harder. I had to bootstrap my 64-bits
>Forth with a 32-bit metacompiler and then e.g. number conversion and
>64-bit address and data specification issues pop up. Of course I
>wanted to compile the source code for the metacompiler and assembler
>/ disassembler on the 64-bit Forth eventually. You might be right
>claiming that is not a Forth issue either.

That's closer to Forth. However, here the problem is already in the
problem you are trying to solve, so it's unreasonable to expect that
the programming language's portability features will solve that
problem automatically for you.

>>> Similar problems are with floating-point code that assumes that a
>>> single precision float is 32-bits == 1 CELL or that a
>>> double-precision float is a Forth double.
>
>> Why would code assume that?
>
>Well, there used to be people that put floats on the data stack :-)
>And old ABI's require floats on the C stack, not in the FPU.

Ah, so it's another problem coming from an unportable foreign
function interface.

Anton Ertl

unread,
Jan 6, 2010, 10:58:11 AM1/6/10
to
steph...@mpeforth.com (Stephen Pelc) writes:
>On Tue, 05 Jan 2010 19:15:40 GMT, an...@a4.complang.tuwien.ac.at
>(Anton Ertl) wrote:
>
>>Not so bad. However, I think that most programmers would prefer
>>variant 2, though. Morover, variant 1 does not even work in VFX
>>Forth, whereas variant 2 and 3 work in Gforth and other systems, so
>>they have more existing practice:
>>
>>vfxlin says:
>>
>>include tmp/test1.fs
>>Including tmp/test1.fs
>>Including %IDIR%/test2.fs
>>Err# -258 ERR: Failed to open requested file.
>> Source: "tmp/test1.fs" on line 1
>> -> include %IDIR%/test2.fs
>
>Because IDIR isn't implemented by default! Why, because no *user*
>has requested it.

Well, of course I have not requested it:

1) I actually want something else: I want "INCLUDE foo.fs" to look for
foo in the directory that contains the file currently being INCLUDED.

2) I am not sure if I am taken seriously. After all, you run a
commercial operation, and I have not paid.

>>>c) LDIR - the directory containing the executable
>>
>>Why should a source file refer to that?
>
>Because there are operating systems other than Unix with different
>working conventions.

A program that uses OS-specific conventions will not be portable to
other OSs. I don't think that adding features for this

Still, what are these operating systems and conventions that need to
know where the executable file is?

>Macros are usable for applications as well as
>"just" for compiling source code.

You (again) seem to use "application" with a special, undisclosed
meaning here that excludes programs that are compiled from source
code. It would facilitate the discussion if you specified what you
mean when you write "application".

>>3) Your ideas about the "expense of some set up" are the antithesis of
>>portability.
>
>We have not yet ported a significant component or application that has
>not required some host-dependent layer. Having to adjust one macro is
>trivial compared to the porting effort.

I have done lots of stuff that does not require anything
host-dependent.

And if there is something specific, it's generally not specific to the
host or the installation, but to the operating system, architecture or
Forth system. And the difference between an architecture layer and
having to change a macro for the specific installation directory is:

The architecture layer can be done once and included with the program,
and the typical user of the program does not have to write or change
it. So the program can be unzipped and run, and is portable at least
among the supported architectures.

In contrast, every user incurs the "expense of some set up" for the
directory macros in the approach you advocate.

>>IMO for small and unflexible applications you don't need a search path
>>mechanism, because you know where everything is. But if you need more
>>flexibility (e.g., because you want to accomodate a lot of add-ons
>>like TeX and the game), you need the flexibility of search paths. And
>>for a really large application that added flexibility can be useful
>>even when developing the core application.
>
>IMHO you need to be able to specify the root directory of a component
>and compile a group of files relative to that root.

Yes, that's what source-directory relative file names give you.

The additional flexibility of a path-based system is that you can drop
the component in any of a number of directories (e.g., some controlled
by the system (administrator), some controlled by the user), and the
component will be found through it's name.

It is loading more messages.
0 new messages