[comp.lang.forth] New Directions: Forth is not postfix

dwp@willett.UUCP (Doug Philips) (01/19/90)

Let me say right off that I am *not* proposing any of this for ANSI Forth.

One of the things that is an annoying inconsistency is that
Forth is not fully postfix.  The words ':', 'IF', 'DO', 'ELSE'
etc. are prefix.  Has anyone out there done real postfix forth?

For example:

    {{ I . }} 10 0 ITERATE

where '{{' and '}}' make a nameless word and push its address (say in
whatever form @EXECUTE needs) on the stack.  Of course one could always do
something to the effect of:

    ['] Foo 10 0 ITERATE

but having to name every 'closure' would be a pain, not to mention
confusing and unnecessary.  (Assume that ['] is right for @EXECUTE)

IF ELSE THEN might be:

    else-addr then-addr condition IF-THEN-ELSE

IF THEN might be:

    then-addr condition IF-THEN

One of the benefits to this is that UNLOOP is just a plain exit.
One of the drawbacks to this is that it highlights Forth's lack of paradigm
for doing controlled exits of more than just the immediately enclosing
construct, as in:

... {{ ... EXIT-:-WE-ARE-IN CheckError IF-THEN ... }} 100 0 ITERATE ...

<<I'm not interested in arguing over the spelling of the names, I'm interested
in the semantics.>>

		-Doug

---
Fastest: (willett!dwp@gateway.sei.cmu.edu OR ...!sei!willett!dwp)
...!{uunet,nfsun,sei}!willett!dwp  [in a pinch: dwp@vega.fac.cs.cmu.edu]

scowl@.cs.pdx.edu (Scott W. Larson) (01/22/90)

In article <284.UUL1.3#5129@willett.UUCP> dwp@willett.UUCP (Doug Philips) writes:
>Let me say right off that I am *not* proposing any of this for ANSI Forth.
>
>One of the things that is an annoying inconsistency is that
>Forth is not fully postfix.  The words ':', 'IF', 'DO', 'ELSE'
>etc. are prefix.  Has anyone out there done real postfix forth?

The prefix words like ':', '."' and 'abort' are very irritating
when writing a new outer interpreter because there is no way
to pass string values to them at run time. What if I want to
write a new ':' that does what ':' does, but gets the name of
the new definition from somewhere other than input. It would
be much more flexible to have colon work like this:

  " MyDef" :

In my case, I have to totally redefine ':' from scratch.

Fortunately the Forth-83 standard made 'find' work this way,
otherwise my senior project would be dead in the water.

peter@ficc.uu.net (Peter da Silva) (01/22/90)

> One of the things that is an annoying inconsistency is that
> Forth is not fully postfix.  The words ':', 'IF', 'DO', 'ELSE'
> etc. are prefix.  Has anyone out there done real postfix forth?

Adobe did. It's called Postscript.

Oddly enough, I did something like this a while ago, using the same
syntax as Postscript. Before I'd ever heard of said language.

> IF ELSE THEN might be:

>     else-addr then-addr condition IF-THEN-ELSE

	{ stuff } { stuff } cond ifelse

> IF THEN might be:

>     then-addr condition IF-THEN

	{ stuff } cond if

> One of the benefits to this is that UNLOOP is just a plain exit.

	Yes.

> One of the drawbacks to this is that it highlights Forth's lack of paradigm
> for doing controlled exits of more than just the immediately enclosing
> construct....

> ... {{ ... EXIT-:-WE-ARE-IN CheckError IF-THEN ... }} 100 0 ITERATE ...

(vaguely postscripty forth:)

	sizeof jumpbuf allocate 'status define

	{	bunch
		{	of
			{	nested
				{ stuff } while
				{ true status longjmp } something if
			} exec
		} status setjmp 0= if
	} 'new_word define

(actually throw and catch are better names, but longjmp/setjmp should be more
familiar to the large number of C hacks on Usenet)

So, do we call this "SIXTH"?
-- 
 _--_|\  Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \
\_.--._/ Xenix Support -- it's not just a job, it's an adventure!
      v  "Have you hugged your wolf today?" `-_-'

toma@tekgvs.LABS.TEK.COM (Tom Almy) (01/23/90)

In article <2243@psueea.UUCP> scowl@eecs.UUCP (Scott W. Larson) writes:
>In article <284.UUL1.3#5129@willett.UUCP> dwp@willett.UUCP (Doug Philips) writes:
>What if I want to
>write a new ':' that does what ':' does, but gets the name of
>the new definition from somewhere other than input. It would
>be much more flexible to have colon work like this:
>
>  " MyDef" :
>

Well, STOIC worked this way, and it was certainly convenient. String arguments
in Forth are one of three things that cause the most confusion for new
Forth programmers (no conditionals in interpret state, and the use of "." to
make a double integer are the other two).

Although it doesn't help for colon, LMI Forths have take the approach in most
"extension" words of defining a function ~foo which takes a string argument,
and another function foo that reads the string from the input stream. foo is
defined in terms of ~foo as : foo bl feed ~foo ; immediate
where the function feed is a state smart version of WORD. Personally I wish
it weren't state smart, but at least the tilde functions are available.

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply

ns@maccs.dcss.mcmaster.ca (Nick Solntseff) (02/03/90)

Some people might prefer an if-statement of the form

     <condition> <then clause> <else clause> IF_THEN_ELSE

but nested if-statements would present parsing problems to the human reader.
Even a pair of nested if-statements might cause trouble.

In my opinion, the objection should be levelled at the name of the IF-WORD and
not the whole construct.  If 

     IF were renamed THEN and
     THEN renamed ELSE and
     Else were quietly removed, 

we would be able to write

      <condition> THEN <true part> ELSE <false part>

-- a much better construct!

toma@tekgvs.LABS.TEK.COM (Tom Almy) (02/06/90)

In article <25C9CFEE.22487@maccs.dcss.mcmaster.ca> ns@maccs.dcss.mcmaster.ca (Nick Solntseff) writes:
>we would be able to write

>      <condition> THEN <true part> ELSE <false part>

>-- a much better construct!

True, but you need a keyword after <false part> to resolve the forward
jump around the false part when the condition is true.
How about:
	IF	-->  THEN	( as you propose )
	THEN    -->  ENDIF	( as existed in figForth )
	NOOP	-->  IF		( a dummy for clarity )
so one gets:

	IF  <condition>  THEN  <true part>  ELSE <false part>  ENDIF

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply

rs0@beach.cis.ufl.edu (Bob Slaughter) (02/06/90)

In article <6801@tekgvs.LABS.TEK.COM> toma@tekgvs.LABS.TEK.COM 
 (Tom Almy) writes:
>
>True, but you need a keyword after <false part> to resolve the forward
>jump around the false part when the condition is true.
>How about:
>	IF	-->  THEN	( as you propose )
>	THEN    -->  ENDIF	( as existed in figForth )
>	NOOP	-->  IF		( a dummy for clarity )
>so one gets:
>
>	IF  <condition>  THEN  <true part>  ELSE <false part>  ENDIF
        ^^^^^^^^^^^^^^^

This is the "non-prefix" part that some object to.  perhaps the
following would be good, allowing for the reference, while maintaining
the prefix orientation of Forth:

       <condition> IF-THEN <true part> ELSE <false part> ENDIF

Looks good to me.... (and avoids a no-op instruction).


--
*     Bob Slaughter                           *  This space for rent       *
*     InterNet#1:  rs0@beach.cis.ufl.edu      *    Call 1-800-FOR-RENT     *
*     InterNet#2:  Haldane@Pine.Circa.Ufl.Edu *   Model Railroading        *
*     Bitnet:      Haldane@UFPine             *          is Fun!!          *

bartho@obs.unige.ch (PAUL BARTHOLDI) (02/07/90)

In article <284.UUL1.3#5129@willett.UUCP>, dwp@willett.UUCP (Doug Philips) writes:
> Let me say right off that I am *not* proposing any of this for ANSI Forth.
> 
> One of the things that is an annoying inconsistency is that
> Forth is not fully postfix.  The words ':', 'IF', 'DO', 'ELSE'
> etc. are prefix.  Has anyone out there done real postfix forth?
> 
> For example:
> 
>     {{ I . }} 10 0 ITERATE
> 

I came to the same idea some 15 years ago when I started using Forth, but
arrived at the conclusion that what ever you do, a real language will always
need some 'one word look ahead' .  I think to remember that at that time they
were many article around proving this (in the CS journals, not in forth).

I see now three aspects of the problem :

1. From the programmer point of view, irrespectively of any compiler or code:

I would be happy with       <name> :  <some code> ;  or   4 Four CONSTANT
but not with                {{ <some code> }} <end index> <first index> ITERATE
neither with                ' <name> :  <some code> ; 

The first is very natural, as in some dictionary, the second is 100% artificial,
and the last not much better, but they look purer postfix ...  One more word
about the second construct: will we not end with the Lisp bracket nightmare,
except that now we have 2 { for each ( ...

2. From the compiler point of view :

The first is not very easy to recognize. You can build a temporary entry
for all unrecognized words, and then fix it when you encounter ':', but all
error recovery will be difficult.  The second is quite easy to implement, but
we recognize that the  '{{'  essentialy doing the same thing as  'DO' , and
}} as LOOP (I am talking now at compile time, not execution time!).  Further
we have replaced 2 constructs ( DO, LOOP ) with 3 ( {{ }} ITERATE ). For the 
last, we have in fact a prefix notation which does essentialy the same as ':'
when it takes the 'next' word.  The only advantage is that {{ }} and '
may be used on other situations.

3. From the point of view of the generated code :

The first construct could bring us to 'unbinded' entries, with 'nil' in the cfa,
that could be fixed later dynamicaly.  This is of course used in Lisp, but
Lisp uses heavily symbolic addresses.  I never explored this idea, although
it seems a necessity for AI (?).  I have used FORWARD DEFINE similar to pascal,
and the DOER MAKE from Brodie that do this in some sens.  For the second
construct, we have a choice :  either we compile the {{ }} and ITERATE as and
where thay are in the dictionary, and we have a lot of jumps that I don't like,
or we let ITERATE patch the {{ and }} in such a way for them to do what DO and
LOOP would have done.  I prefer the second solution, but again I am afraid
of the consequence in term of security, that is what happens after an error.


If you look at real life, you find that you use all notation: infix for
dyadic math operator  (three 'and' half ...), postfix for many quantities
(12 $, or 4.75 Volt ...) and prefix for description (name: Paul ...).
I don't see why a computer language should be pure in/pre/post fix.  The nice
things with Forth (compare to Lisp and other pre/in fix languages) is that you
never need explicit brackets, you never need to read more than one word forward,
you can always compile any complicated construct in 1 pass.  All this is due
to postfix notation + one word look ahead.  If you find a 100% pure Postfix
notation that add to this list without drawbacks, I will by it immediately,
but I am afraid you are looking for a paradise that was lost long ago on earth!

                  Good Forth !              Yours, Paul Bartholdi

     +--------------------------------------------------------------+
     |  Dr Paul Bartholdi             bartho@cgeuge54.bitnet        |
     |  Observatoire de Geneve        bartho@obs.unige.ch           |
     |  51, chemin des Maillettes     02284682161350::bartho (psi)  |
     |  CH-1290 Sauverny              20579::ugobs::bartho          |
     |  Switzerland                   +41 22 755 39 83       (fax)  |
     |                                +41 22 755 26 11       (tel)  |
     |                                +45 419 209 obsg ch  (telex)  |
     +--------------------------------------------------------------+