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