[net.lang] Philosophy, Environment, and Syntax of FORTH

rb@cci632.UUCP (07/12/86)

In article <474@astroatc.UUCP> philm@astroatc.UUCP (Phil Mason) writes:
>In article <152@cci632.UUCP> rb@ccird1.UUCP (Rex Ballard) writes:
>>In article <679@ucbcad.BERKELEY.EDU> faustus@ucbcad.BERKELEY.EDU (Wayne A. Christopher) writes:
>>>Maybe I'm not seeing the point about "threaded" languages -- you don't see
>>>C programmers claiming that the major advantage of C is that you can use
>>>function calls to build up higher-level routines out of lower ones...  Or is
>>>it just that since forth is the first language many micro users use after
>>>basic and asm, functions (or "words") seem like a really big thing...
>>
>>Actually, you do see part of the point.  Yes C is "extensible", as is forth.
>>However, most C functions are not usually thought of as "extensions" to
>>the language.
>
>In C and other compiled languages, the goal of writing an application is NOT
>to write routines that act as building block tools, but to get the application
>out the door as fast as possible.

This is a matter of philisophical discipline.  One can come up with a very
powerful set of building block tools.  It takes a little effort, but
the long term benefits are worth it.

>With Forth, you can get a set of helpful tools
>AND get it out the door quickly.

The tendency to produce throrougly debugged "blocks" quickly as a result
of the Environment make it more practical to do this in Forth.  It can
be done in C.

>Forth's extensibility really means that its
>philosophy leads the designer to create useful extensions to the language 
 ^^^^^^^^^^  Very Important word here

>itself rather than just creating routines to do one non-reusable thing. The
>closest thing compiled languages have that matches the concept of Forth
>extensibility is their source libraries. Come on, do you write a new library
>every time you make an new application that includes helpful tools for writing
>applications? NO. Of course not.

As a matter of fact, I DO!  This came as a side effect of writing code in
Forth in an earlier job.

>>In forth, as you work up to the top of the design (because there is
>>no convenient forward referencing), you view most levels with the
>>maximum generality possible.  Forth functions are intentionally used
>>over and over.
>
>You can quite easily add forward referencing to Forth. A common implementation
>is called 'DEFER'. It's simple. Forthers have been doing it for quite awhile.

This however is the exception, rather than the rule.  Rarely do Forth
programmers write the top levels and *debug* them before moving to lower
levels.  The result is that the Design must be Much more Complete, at least
in the implementor's mind.

>If you think about how you design in other languages, you still do it
>bottom-up or in combination with top-down. How many times do you use forward 
>referencing?

Personally?  Very rarely.  However, I have seen a great number of "compiler"
code where it looks like half the bottom level routines were NEVER TESTED.
I actually crashed a PDP-11 by simply using a patch to call a funtion that
never got called (undetected unreachable statement) otherwise.

>>In C, it is possible, even necessary to implement "Top Down" rather
>>than "Bottom Up".  As a result, the C programmer will frequently
>>write one big monster function and break little units out only as
>>he needs them.
>
>In Forth, you make little functions. Nothing more than 16 lines in length
>if you want to use good style. No monster incomprehensible functions.
>If you have truly thought out your design, there is no need for monster
>functions.

I frequently limit myself to 25 lines of C code per function.  Again,
a practice learned from Forth.  In addition, except when required by
"state coupling", each routine is in it's own file and all but the mainline
and very top levels are built into a library.  The extra 9 lines are
typically variable declarations, so the effective yeild is about the same.

>Whether it be easier to make bugs or not,

It is very easy if you forget to dup or use swap instead of over, or
left yourself in the wrong base.

>Forth is a quick, efficient 
>software design environment. You spend most of your creative energy 
>waiting for the compiler to finish rather than debugging the routines you 
>couldn't afford to make a test harness for.

There you have the Key to a good future language.  When your code/compile/test
cycle is 1 second, rather than 1 hour (or one day in some cases), THEN you
have the start of a good fourth generation Language.

>>Other languages are extensible.  In fact there are other languages that
>>are BETTER than forth if extensibility is required.
>
>Not true. LISP is the closest thing. Try writing real-time, low-level code in
>LISP!

Well, actually, there are several interprers and threaded interpreters that
are also extensible.  Smalltalk, Prolog, Neon, True Basic, and several others
Can be extensible by adhering to the Forth philosophy :-).

>Why try to make C in Forth? There are two different philosophies at work there.
>Sounds like trying to write software tools in BASIC.

Want me to tell you about my BASIC library?  Keeping track of Gosubs...
I didn't think so :-).

>Something LIKE C could be created. Look at a language called MAGIC-L.

There are several Forth BASED languages in which someone has enhanced
the language and changed the parser slighly, or used the basic principles
to create a better one.  Neon, PostScript, SmallTalk, Threaded Pascal,
and Threaded Basic, to name a few.  Many others have developed features
such as frames, arguments, ... all the best features of any language.
They change the name because "Forth Fanatics" don't want the language
enhancments to be part of "standard Forth".

>>Another advantage of the '79 and '83 standards is that very long function
>>names are supported (up to 128 bytes on most implementations).  This is
>
>There is a practical limit to name length if you want to be able to remember
>and write lots of code with them.

But simple "action_type" names make it easy to locate all the words that
deal with a given type (class) or a given action.

fetch_float is easier to remember and search on than 2d@ or worse podbpt
(print out to debug port).  Variable seem less memnonic when they have
some vowels.  The main disadvantage is it's harder to type.  A Dvorak
keyboard is a better solution than a Kanji character set.

>>Finally, threaded languages do not rely on a single stack and "frames".
>>
>>A disadvantage of this of course is that the function is now solely
>>responsible for type.  This means no type checking.
>
>True, but well-structured code and careful, consistent use of the stack is a
>boon, not a hinderance.

It is the discipline of the programmer to overcome these problems that
makes it a boon.  The ticklish problem is how to simplify type management
without loosing the 16-25 line discipline.

>>What makes forth attractive is not it's incredible power as a language.
>>In fact anything short of assembler is more robust.  What makes forth
>>attractive is it's definition of the "environment" available, and the
>>power in relation to the hardware requirements.
>
>Forth is not anemic. If you want a more sophisticated enviroment, write one.
>Come on UNIX hackers, you've been rewriting environments for quite awhile.

The problem is, to have a useful environment enhancement in Forth, you
have to have source.  Very few people want to distribute easily examined
source to a significant system.  The other option is to "grand slam" the
entire kernal in binary, stripped, executable form.  If you can crack into
the "Task" and create your own headers, you can get a very powerful forth
system out of a forth application.  Atari's "demo disk" was great.

>>The big lose, at first glance, is the slower execution time.  This
>>can be overcome with Forth "compilers" which produce tight, headerless,
>>rommable code that executes as fast as assembler (because it IS assembler).
>
>An optimized un-adulterated threaded-code Forth can still beat a mediocre
>compiler. If you want the extreme, ultra-portability, high-level Forth
>beats them all.

I should have qualified my statement.  Depending on the processor, compiled
code may be faster.

Assuming you have the basic primitives as subroutines, all you have to do
to turn forth source into assembler source is put a call instruction
in front of each word, put one word per line, push the literals, and
replace the semicolon with a return instruction.  Many forths will produce
"call code", also know as subroutine threaded code for you.

>>Newer languages, and older ones, are taking advantage of many of the
>>techniques and principles introduced by Forth.  Hopefully others, such
>>as C, will do the same.
>
>Amen.
>
>But until they appear,
>
>
>Think Big, Build Small, Port Everywhere - - -
>
>			Control the World with Forth.

At least try it out for two months and learn the principles.
You may not want to give it up!