[comp.lang.forth] Infix/Postfix notation

koopman@a.gp.cs.cmu.edu (Philip Koopman) (08/23/88)

Several recent postings have debated the merits of infix versus
postfix notation in Forth.  I'd like to present a different
viewpoint for discussion.  Postfix notation is just a side-effect
of a much more important issue: parameter passing for subroutines.

One of the most useful aspects of Forth is implicit parameter
passing.  That eliminates the tedious lists of parameters in
parenthesis found in other languages.  This makes the code much
cleaner and more flexible than other languages.  It also makes
defining words and immediate words handy. 

The arithmetic operators are treated as subroutines just like
any other word.  This allows a blurring of the distinction between
hardware supported primitives and high level routines, improving
transportability and making optimization of inner loops in
assembly language or microcode quite easy.
So, to me, the RPN notation is just an inconvenient side-effect
of the implicit parameter passing mechanism used by the language,
and is not really an important feature itself.

As an aside, real infix notation parsers are relatively simple
to write (for example, the one Chuck Moore wrote for his tiny
BASIC interpretter.)  I think that most people don't bother with
them because most expressions that are evaluated are very simple.

Phil Koopman         koopman@faraday.ece.cmu.edu  Arpanet
Student at CMU, sometime consultant to Harris Semiconductor.

orr@cs.glasgow.ac.uk (Fraser Orr) (08/25/88)

In article <2768@pt.cs.cmu.edu> koopman@a.gp.cs.cmu.edu (Philip Koopman) writes:
>Several recent postings have debated the merits of infix versus
>postfix notation in Forth.  I'd like to present a different
>viewpoint for discussion.  Postfix notation is just a side-effect
>of a much more important issue: parameter passing for subroutines.

A think a more historically accurate point of view would be
that implicit parameter passing is a side effect of postfix :-]

>One of the most useful aspects of Forth is implicit parameter
>passing.  That eliminates the tedious lists of parameters in
>parenthesis found in other languages.  This makes the code much
>cleaner and more flexible than other languages.  It also makes
>defining words and immediate words handy. 

I don't agree that it makes the code either cleaner or more flexible
than other languages, because the parameters are very hard to see
(they are mixed up with all sorts of junk on the stack)
I agree though that in theory "implicit parameter passing is good....

All you need to do is define a syntax that makes it clean, and
explicit. For example consider a procedure that takes (x0,y0)
and (x1,y1) as coordinates, and a string and a colour, and an operation
(XOR, AND or OR) and draws a box on the screen. It uses two
procedures hline and vline, (which draw horizontal and vertical lines)
taking colour and operation as their last parameters. It then prints
a string in the box, with a procedure called showat, that does not
take operation or colour as parameter.
We could define it as follows.

procedure Box (String,x0,y0,x1,y1) (colour,operation)
begin
  hline (x0,x1,y0)...
  hline (x0,x1,y1)...
  vline (x0,y0,y1)...
  vline (x1,y0,y1)...
  showat(x0,y0,String)
end

The first line specifies two parameter lists (the later is
optional). The second specifies which of the parameters are 
to be passed on implicitly.
Now we mark every procedure call that requires the implicit params
with an elipsis (...) and thus you have all the power of
implicit parameter passing, without hiding anything (the
elipsis makes it clear that there is more information that
has been omited, and the second param list show exactly what it is).

Since you might want to do this on a scope less than a whole
procedure, you might also introduce an implicit keyword viz.

procedure Box (String,x0,y0,x1,y1,colour,operation)
begin
  implicit (colour, operation)
    hline (x0,x1,y0)...
    hline (x0,x1,y1)...
    vline (x0,y0,y1)...
    vline (x1,y0,y1)...
    showat(x0,y0,String)
  end
end

This would allow you to vary the parameter list within
the procedure, so that different implicit params could be given.
Can anyone really, honestly deny that this syntax is MUCH
nicer, MUCH clearer, MUCH more flexible than what we currently
have in forth? I was going to write a similar routine in forth
to contrast, but the thought of dealing with a six deep stack
was too much for me!:->
I would though be interested to see your offerings.

>The arithmetic operators are treated as subroutines just like
>any other word.  This allows a blurring of the distinction between
>hardware supported primitives and high level routines, improving
>transportability and making optimization of inner loops in
>assembly language or microcode quite easy.

This is true of most of the newer programming langauguages,
that is '+' is treated as a function taking two arguments,
just that it has a different function call syntax.

>So, to me, the RPN notation is just an inconvenient side-effect
>of the implicit parameter passing mechanism used by the language,
>and is not really an important feature itself.
>
>As an aside, real infix notation parsers are relatively simple
>to write (for example, the one Chuck Moore wrote for his tiny
>BASIC interpretter.)  I think that most people don't bother with
>them because most expressions that are evaluated are very simple.
>
Both these comments lead me to ask again, why don't you
accept the idea of programming in a language that deals with
important issues (syntax, type checking etc) that compiles
quickly into forth? And to say that most expressions are simple
thus making them clearer is not necessary is a terrible argument.
I try to keep my expressions as simple as possible for the sole
reason of making them clearer!

Regards,
===Fraser (orr%cs.glasgow.ac.uk@nss.ucl.ac.uk)

koopman@a.gp.cs.cmu.edu (Philip Koopman) (08/29/88)

In article <1583@crete.cs.glasgow.ac.uk>, orr@cs.glasgow.ac.uk (Fraser Orr)
gave details of a box drawing routine.  A somewhat condensed version is:
> procedure Box (String,x0,y0,x1,y1) 
> begin
>   implicit (colour, operation)
>     hline (x0,x1,y0)...
>     hline (x0,x1,y1)...
>     vline (x0,y0,y1)...
>     vline (x1,y0,y1)...
>     showat(x0,y0,String)
>   end
> end
> 
> This would allow you to vary the parameter list within
> the procedure, so that different implicit params could be given.
> Can anyone really, honestly deny that this syntax is MUCH
> nicer, MUCH clearer, MUCH more flexible than what we currently
> have in forth? I was going to write a similar routine in forth
> to contrast, but the thought of dealing with a six deep stack
> was too much for me!:->
     Nicer, clearer?  Those are judgement calls!  I absolutely
abhor typing in long lists of parameters.  I suppose that comes
from writing too many programs using FORTRAN graphics packages
that are designed this way.  I consider your approach to be less flexible
than Forth.  I do admit that it is difficult to form an objective
counter-argument (I'll have to think about this one.)  As a preliminary
stab, I would say that implicit parameter passing is best when
stringing together sequences of words to create complex functions.
This creates a combinatorial explosion of special-purpose subroutines
in other languages, or creates a lot of excess typing of parameter
lists that don't change.

     I did say earlier that I too do not relish stack twiddling, and I'm 
trying to think up a way to get around it.  A good prospect is some adaptation
of the local variable schemes I have seen for use when the stack
gets too deep.

> Both these comments lead me to ask again, why don't you
> accept the idea of programming in a language that deals with
> important issues (syntax, type checking etc) that compiles
> quickly into forth? And to say that most expressions are simple
> thus making them clearer is not necessary is a terrible argument.
> I try to keep my expressions as simple as possible for the sole
> reason of making them clearer!

     I *do* program in lots of other languages.  Languages I consider
myself proficient in include FORTRAN, BASIC, C, Pascal, and Forth.
Not to mention lots of flavors of assembly language and microcode.
By proficient I mean that I have written single applications that
have 10K to 100K or so lines of code in each language.  I have lost
count of the languages I have dabbled with (LISP, Snobol, etc.)
The point is that I choose to program in Forth when the problem
fits the application.  I don't make a blind decision out of habit.
(I wish some C die-hards saw things that way!)

     The important issues you mention are not always important to
everyone.  I find that the people who use Forth are not computer
scientists, they are engineers.  They have recognized that Forth
allows them to get the job done faster and with lower hardware
cost in the finished product.  The features you talk about are
important for multi-megabuck software projects.  They don't matter
much for small applications with one or two programmers in a hurry
to meet a deadline, which is where Forth is at its best.

     I don't use Forth for applications that require text file I/O or
string handling -- the hooks just aren't there in standard
Forth systems.  I do use Forth for control-flow-intensive applications
and for non-text database applications.  As an example, the functional
simulator for my latest hardware design is being written in Forth,
and is MUCH cleaner and simpler than an implementation in
C ever could be.  Of course trying to prove this is difficult,
but I consider that I have enough experience to be able to tell.

     One of things I think Forth needs most is a standardized full-function
string handling system that is well supported by the compiler (NO,
this DOES NOT mean one of the several string handling word sets,
it DOES mean changing the interpretter so that it knows more about
string variables and text file I/O.)  When this happens I expect to
use Forth a lot more.

     By the way, I have looked at compiling standard languages
into Forth.  What you end up with is a Forth-implemented virtual
execution machine for that language.  The result is not as efficient
on stack machines as writing in Forth because other languages tend to
be used in different ways than people use Forth.
---> The tool colors the method.

     I guess I've run off at the mouth a little, but I think that these
are important subject areas.  Perhaps people would like to break them
off into separate topics.  Thanks for the discussion, keep it up!

  Phil Koopman                koopman@maxwell.ece.cmu.edu   Arpanet
  5551 Beacon St.
  Pittsburgh, PA  15217    
PhD student at CMU and sometime consultant to Harris Semiconductor.

bts@sas.UUCP (Brian T. Schellenberger) (09/01/88)

How I'm not jumping in after everybody's finished having fun with this (I was
gone for a bit), but it seems to me that one of the biggest benefits of Forth's
stack approac has so far gone unmentioned:

	You can *return* multiple values easily.

This tends to be awkward and inefficient in other languages; in Forth, it is so 
natural that apparently nobody's even thought it worthy of comment so far.
-- 
--Brian,                     __________________________________________________
  the man from              |Brian T. Schellenberger   ...!mcnc!rti!sas!bts
  Babble-On                 |104 Willoughby Lane     work: (919) 467-8000 x7783
____________________________|Cary, NC   27513        home: (919) 469-9389 

hjm@cernvax.UUCP (Hubert Matthews) (09/09/88)

One of the other things about infix notation is that it works for two
parameter functions very easily, but three gets a bit tricky (you need
another symbol) and four starts to look kinda crazy.  For n parameters
you need n-1 symbols with infix; with prefix or postfix you need only
one.  Just try adding another argument to an infix function - it's messy!

If you do want infix notation for the if-then-else construct, then why not
use Hoare's notation:

a <| c |> b

where c is the test and a and b are the alternatives; true to the left
and false to the right.  It's just as well that boolean conditions can
have only two values or you would be stuck to extend this notation cleanly.
Or would you go to a four-way branch like this:

     x

     ^
     -

a <| c |> b

     _
     v

     y


Five is really tricky with a standard keyboard :-)

	Hubert Matthews