[comp.lang.forth] Why FORTH is good

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)