koopman@a.gp.cs.cmu.edu (Philip Koopman) (09/01/88)
We've had a bit of discussion on why Forth is "better" than other languages. I think I have found a good argument in favor of Forth. The reasoning is couched in terms of functional programming, but the arguments apply equally well to Forth, because they hinge on implicit parameter passing and the use of a stack. (Functional programming languages are like Forth in some ways, and some work has been done implementing functional extensions to Forth.) I especially like the reference to glueing pieces of programs together. The following text is borrowed without permission from: John Hughes, "Why Functional Programming Matters", Programming Methodology Group, University of Goteborg and Chalmers University of Technology, 41296 Goteborg, SWEDEN, November 1984 (in English). Phil Koopman koopman@maxwell.ece.cmu.edu Arpanet 5551 Beacon St. Pittsburgh, PA 15217 PhD student at CMU and sometime consultant to Harris Semiconductor. I don't even own up to my own opinions... ----------------------------------------------------- It's helpful to draw an analogy between functional and structured programming. In the past, the characteristics and advantages of structured programming have been summed up more or less as follows. Structured programs contain no 'goto' statements. Blocks in a structured program do not have multiple entries or exits. Strucuted programs are more tractable mathematically than their unstructured counterparts. These "advantages" of structured programming are very similar in spirit to the "advantages" of functional programming we dis- cussed earlier. They are essentially negative statements, and have led to much fruitless argument about "essential 'gotos'" and so on. With the benefit of hindsight, it's clear that these properties of struc- tured programs, although helpful, do not go to the heart of the matter. The most important difference between structured and unstructured programs is that structured programs are designed in a modular way. Modular design brings with it great productivity improvements. First of all, small modules can be coded quickly and easily. Secondly, general purpose modules can be re-used, leading to faster development of subsequent programs. Thirdly, the modules of a pro- gram can be tested independently, helping to reduce the time spent debugging. The absence of 'gotos', and so on, has very little to do with this. It helps with "programming in the small", whereas modular design helps with "pro- gramming in the large". Thus one can enjoy the benefits of structured program- ming in FORTRAN or assembly language, even if it is a little more work. It is now generally accepted that modular design is the key to successful programming, and recent languages such as Modula-II and Ada include features specifically designed to help improve modularity. However, there is a very important point that is often missed. When writing a modular program to solve a problem, one first divides the problem into sub-problems, then solves the sub-problems and combines the solutions. The ways in which one can divide up the original problem depend directly on the ways in which one can glue solutions together. Therefore, to increase ones ability to modularise a problem conceptually, one must provide new kinds of glue in the programming language. Complicated scope rules and provision for separate compilation only help with clerical details, they can never make a great contribution to modu- larisation. One can appreciate the importance of glue by an analogy with carpentry. A chair can be made quite easily by making the parts - seat, legs, bach etc. - and stiching them together in the right way. But this depends on an ability to make joints and wood glue. Lacking that ability, the only way to make a chair is to carve it in one piece out of a solid block of wood, a much harder task. This example demonstrates both the enormous power of modularisation and the vital importance of having the right glue. Now let us return to functional programming. We shall argue in the remainder of this paper that functional languages provide two new, very important kinds of glue. We shall give many examples of programs that can be modu- larised in new, exciting ways, and thereby grealy simplified. This is the key to functional programming's power - it allows greatly improved modularisation. It is also the goal for which functional programmers must strive - smaller and simpler and more general modules, glued togehter with the new glues we shall describe. -------------------------------------------------------------
orr@cs.glasgow.ac.uk (Fraser Orr) (09/06/88)
In article <2853@pt.cs.cmu.edu> koopman@a.gp.cs.cmu.edu (Philip Koopman) writes: >We've had a bit of discussion on why Forth is "better" than other >languages. I think I have found a good argument in favor of Forth. > >The reasoning is couched in terms of functional programming, but >the arguments apply equally well to Forth, because they hinge >on implicit parameter passing and the use of a stack. (Functional >programming languages are like Forth in some ways, and some work >has been done implementing functional extensions to Forth.) >I especially like the reference to glueing pieces of programs together. > >The following text is borrowed without permission from: >John Hughes, "Why Functional Programming Matters", I should say that John Hughes is a prof at my department, and I have discussed this kind of thing with him before (although I haven't read the paper you quote). [Stuff about the usefulness of modularity and the importance of glue deleted] >Now let us return to functional programming. We shall argue in the remainder >of this paper that functional languages provide two new, very important >kinds of glue. We shall give many examples of programs that can be modu- >larised in new, exciting ways, and thereby grealy simplified. This is the key >to functional programming's power - it allows greatly improved modularisation. >It is also the goal for which functional programmers must strive - smaller and >simpler and more general modules, glued togehter with the new glues we shall >describe. > I haven't read the paper in question. But if I know John Hughes, the two forms of glue that he will be talking about are lazy evaluation and higher order functions. Neither of these glues are avaliable is forth. Moreover I know of no proper module facilities in forth like languages (although PostScript - a forth like language- has added object oriented features). To suggest that this paper backs up forth as a wonderful programming language is ridiculous. I does quite the opposite. It says that modularity is crucial in large programming projects, this is not avaliable in forth. It says that glue is crucial, the glue avaliable is forth is the worst glue avaliable in just about any programming language there is (because it is untyped, and unsized, and it has very limited facilities for passing complex structures about). The princliples that undergird functional programming are clarity, explicitness, flexibility and type security. Forth bears absolutely no resemblance to any functional programming language I know, (appartfrom the fact that the both run on a computer of course :^>). In answer to David Murry's question (the one he didn't want an answer to) The language that I probably like best is a functional language called Miranda, although I think it is too slow for all practical purposes just now. Regards, ===Fraser
DAVID@PENNDRLS.BITNET (09/10/88)
Fraser Orr writes: >I haven't read the paper in question. But if I know John Hughes, the two >forms of glue that he will be talking about are lazy evaluation and >higher order functions. Neither of these glues are avaliable is forth. >Moreover I know of no proper module facilities in forth like languages >(although PostScript - a forth like language- has added object oriented >features). > >To suggest that this paper backs up forth as a wonderful programming >language is ridiculous. I does quite the opposite. It says that >modularity is crucial in large programming projects, this is not >avaliable in forth. It says that glue is crucial, the glue avaliable is >forth is the worst glue avaliable in just about any programming language >there is (because it is untyped, and unsized, and it has very limited >facilities for passing complex structures about). The princliples that >undergird functional programming are clarity, explicitness, flexibility >and type security. > >Forth bears absolutely no resemblance to any functional programming >language I know, (appartfrom the fact that the both run on a computer of >course :^>). I'd like to comment on this in two parts. First insofar as it is a response to an earlier posting, and second as a comparison of FORTH and functional programming. First of all, I don't think the original poster was claiming that the paper backed up FORTH as a wonderful programming language, but rather that it singled out modularization as the greatest good; the fact that FORTH makes it easy to completely modularize code then implies that FORTH is a ``good'' language *in this regard*. Obviously, however, you do not agree that FORTH allows easy and complete modularization. I think we need a definition of modularization. I suspect you are in fact referring to language facilities directly aimed at building modules. If so, you are correct, plain FORTH has none. But even the computer scientists agree that modularization is something that happens in the programmer's head, not in the language. So to say that modularization is not available in FORTH is a misstatement. Further, I remember reading of at least one example of adding MODULA style modules to FORTH ``in a few simple screens of definitions.'' (Before you object that this is not part of the standard, keep in mind that most functional programming languages start out with a very simple (but powerful) core to which quite a bit of code must be added before you have an adequate *programming* environment. Sound familiar?) But even (or especially) *without* MODULA style modules FORTH provides a good environment for modularization because it allows the problem to be decomposed in a way that fits the *problem*, not the programming language. (Of course, some traditional languages are better at allowing this same kind of decomposition than others.) A program design book I was reading recently (yes, Fraser, I found a generic one) maintains that the proper way to decompose a program is to design data structures in terms of the operations that may be performed on them (including transformations between data structures). FORTH is excellent for this kind of decomposition, better than any traditional language I know. (C++ and SmallTalk may be as good; I don't know them.) Other points vis-a-vi FORTH and functional programming (this is neither a rebuttal nor an attack, but more of an opening of a discussion): Lazy evaluation: There is no reason why one could not define individual FORTH words that evaluated in a lazy fashion. Still, it is clearly much better to have the system make that decision if it can. Here I would agree that a functional programming language is superior to FORTH. Higher order functions: are functions that operate on other functions as data. FORTH can do this in several ways, since a function can be represented by its address. Agreed, this is not as elegant in practice as true functional programming, but it is closer than FORTRAN or PASCAL can come. Of the current most widespread languages, only C approaches FORTH in its potential for higher order functions. FORTH glue bad because it is untyped: Since when have functional program glues been typed? I didn't think that type checking was part of the fundamental design. Well, Backus' FFP returns undefined if you apply a function to an argument it doesn't handle, but that doesn't help during the ``compilation'' step. Your arguments for type checking were based on informing the programmer of errors *before* running the program. Complex data structures: FORTH can pass data structures of arbitrary complexity; this is one of its strengths. Any data structure is represented by the address of its root. I'm sure you could implement S-expressions in their full glory in FORTH, in fact I suspect someone has by now done so. Clarity: We've been arguing for a while now about what is clear and what is not. You find explicit argument lists clear, another poster found the absence of argument lists clearer. (I agree with the latter.) At first exposure I did not find functional programming notation clearer than I found FORTH or APL at first exposure. In each case the examples have become clearer as I have grown used to the notation. Some algorithms I find easier to comprehend in the (best of) the functional notations I have seen, others I find clearer in well written FORTH. Explicitness: Functional programs may be explicit about what functions are getting what arguments, but you still have to visualize the actual data being handed around to *really* see what is going on. If I see f(g(h(z))) I have to visualize the result of h on z, then of g on that result, then of f on *that* result. Even when the visualization is in symbolic terms, how is that easier than visualizing a three deep stack? Especially if Z is an S-expression (or equivalent) with three or more subexpressions of distinct types? Flexability: Well, you'll never convince us that FORTH is not flexable, so I guess I'll let this one alone. Type security: Again, how does functional programming provide type security? (That's not a challenge, that's an honest question.) FORTH as a functional programming language: As I understand it, the basic characteristic of a functional programming language is that a function always has the same result when given the same input values, regardless of the state of its environment. Many many FORTH words have this characteristic. A number do not, and many of these are critical to the functioning of the FORTH system. It is this latter that makes FORTH appear so un-functional. Good FORTH programs minimize and restrict these state-changing words. Consider how few variables good FORTH programs have relative to traditional programs and FORTH may start to seem more functional. FORTH would appear to be inferior to a true functional programming language because (1) Not all FORTH words are true functions. This reduces their mathematical tractability, ease of comprehension, and ease of maintenance. (2) FORTH cannot perform lazy evaluation automatically. (3) Higher order functions are not easy to write in FORTH. The price the functional programming languages pay for having these features are the complexity of the program interpretation process and the slow speed of execution. This can be alleviated by special purpose hardware, and may have advantages in a massively parallel environment. FORTH programs can be made more functional by reducing non-local variable use. Higher order functions and lazy evaluation of some functions can be introduced if sufficiently desirable. (I'll have to think about that some.) FORTH runs efficiently on current hardware. Until functional programming languages come of age, I'll stick to FORTH. (But I'll try to investigate Miranda.) -- R. David Murray (DAVID@PENNDRLS.BITNET, DAVID@PENNDRLS.UPENN.EDU)