[net.lang] APL myths

blickstein@orphan.DEC (Dave Blickstein) (06/25/84)

>I have used both FORTRAN and APL (among many other languages) and I
>came to the conclusion that APL is the world's only write-only
>language!  The standard technique for fixing a bug in an APL program is
>to rewrite the whole program ... FINDING the bug in an APL program is
>much more difficult than in any other language I have used.  By the
>way, has anyone ever found a way to write structured APL?
>
>					Rich Strebendt

I'm so tired of statements like this.  APL is not unreadable.  In fact, I
personally find it more readable than FORGOL (my acronym for all the various
FORTRAN dialects: Pascal, ada, PL/I, C, etc.)

First of all, your opinion of APL is probably derived from the basic fact
that APL is different from procedural languages (FORGOL).   You probably
find it hard to understand all those symbols.  But saying that it's unreadable
is like an american saying that Japaneese is unreadable.  It's only unreadable
if you don't understand the symbols.

I'm afraid that you've betrayed your lack of knowlege of APL by asking for
a way to write structured APL (saying that you've used it, is different
than saying that you understand it).   One of the best elements of APL is
that it attempts to substitute powerful notation for procedural specification
(structured programming is a concept of procedural languages which APL tries
NOT to be).  In other words, SP concepts aren't as necessary in APL because
the vast majority of loops and things, are eliminated because of APLs powerful
set of functions and operators.

Another reason why I find APL more readable is its terseness.  One short APL
expression (average) could be several lines (or pages) of FORGOL:

	DCL I integer;
        dcl sum integer;

        sum = 0;
        do i = 1 to length(vector)
	   sum = sum + vector(i);
           end;
        print sum/length(vector);

as opposed to the APL definition (written here in ascii-ized form):

	(+/ VECTOR) % rho VECTOR

(where rho is the greek letter rho which is the APL "shape" (length) function
 and % is the mathmatical divide symbol - overstruck with :).

I guarantee you, an APL programmer will identify the APL version much faster
than the FORGOL programmer can identify the FORGOL version everytime.  The
APL representation is just the definition of average.  The FORGOL program
is the algorithm and has all kinds of superfluous confusing things like
the sum and index variables and the DO loop.

This is an admittedly simple example, but it applies in the general context.

	Dave Blickstein

	(UUCP)  {decvax, ucbvax, allegra}!decwrl!rhea!orphan!blickstein

	(ARPA)  decwrl!rhea!orphan!blickstein@Berkeley
	        decwrl!rhea!orphan!blickstein@SU-Shasta	

phipps@fortune.UUCP (Clay Phipps) (06/27/84)

[beware the jabberwock]

    >I have used both FORTRAN and APL (among many other languages) and 
    >I came to the conclusion that APL is the world's only write-only
    >language!  

Then you have not yet seen some really convoluted C code.
C can be write-only if the programmer exercises sufficient cleverness.

    >The standard technique for fixing a bug in an APL program is
    >to rewrite the whole program ... FINDING the bug in an APL program is
    >much more difficult than in any other language I have used.  

In the early days, it wasn't the notation, it was the diagnostic messages
(if you couldn't buy, beg, or borrow an APL type ball, you didn't use APL).
As someone once said, "APL's error messages consist of only two words,
and one of them is 'error' !"; the other words were "domain", "range", "rank",
"index", "value", &c.  With zillions of functions, even knowing the precise
distinction between, for example, domain and range was often little help.
The definition of the functions was not rigorous, at least in print
(especially for multidimensional arrays where some dimensions were 1)
so you wrote and debugged by trying little pieces of code at a time.
This is the moral equivalent of looking at C compiler source code
to figure out how to write a declaration for an "array of functions 
returning pointers to ...".  But at least APL indicated the precise token
at which the error was detected (as might be obvious, I have not used APL
in a long while; I hope that the diagnostics have improved);
most FORTRAN systems give the poor user a hexadecimal or octal address
for an instruction, and leave the translation of that to a FORTRAN 
statement number as an exercise for the user.
    
    First of all, your opinion of APL is probably derived from the basic fact
    that APL is different from procedural languages (FORGOL).   

APL is different from conventional procedural languages;
however, APL is itself a procedural language:
the programmer must specify everything to be done,
in the order that it is to be done.
The programmer does not need to concern herself with details
that may be irrelevant to a particular program,
e.g., the order in which the elements of a vector are to be accessed
when the entire vector is being manipulated.
That is the big difference.

    You probably find it hard to understand all those symbols.  
    But saying that it's unreadable is like an american saying 
    that Japaneese is unreadable.  It's only unreadable 
    if you don't understand the symbols.

Some people do find highly symbolic, as distinct from natural-language-like,
notation difficult to comprehend; it's a human engineering issue.
However, Ken Iverson (who is a mathematician by virtue of his formal
education) and his colleagues involved in the design of APL
did devote considerable effort toward making the notation of APL
consistent with that of formal mathemetics.  Even Iverson admits that 
mathematical notation "lacks universality".  When there was no obvious
notational choice, they considered various historical precedents;
when that failed, they invented their own notation.
Thus the Greek letter rho, which is used in mathematics and physics
to designate the length of a vector (e.g., in cylindrical coordinate systems),
was used in APL to indicate the length or cardinality of the vector
data structure [I don't have the exact rationale for the choice of rho
in front of me, but this should suggest the general ideas].
For a full discussion, see
Kenneth E. Iverson: "Notation As A Tool Of Thought" (1979 Turing Award
Lecture), *CACM* vol. 23, num. 8, August 1980, p. 444 .. 465.
Compare the care used in devising the notation for APL
with the use of in C of countermnemonic symbols like "&" for "address of".
In APL, the question is only "what's that symbol mean ?";
in C, it's often "what is that symbol being used for this time ?".
Personally, I would much rather learn many symbols with distinct meanings,
as in APL, than learn a few symbols with many unrelated meanings, as in C.
Consider the many meanings of parentheses in FORTRAN and C.
    
    >By the way, has anyone ever found a way to write structured APL?

    I'm afraid that you've betrayed your lack of knowlege of APL 
    by asking for a way to write structured APL (saying that you've used it, 
    is different than saying that you understand it).   

Why not answer the question first ?  
Yes, many people have devised their own form of "structured APL".  
For example, there was one in the '70s called APLGOL, 
which embedded APL expressions in Algol-like statements.
The push for a "structured APL" probably peaked in the mid-70s.
There are still probably papers appearing in *APL Quote Quad* describing
new variations on the theme of "structured APL".
The problem has been that the majority of the APL community
has not accepted these graftings (or mongrelizations) of APL
with other languages.  It's like grafting a Winnebago to a Porsche.

    One of the best elements of APL is that it attempts to 
    substitute powerful notation for procedural specification ...
    ... [structured programming] concepts aren't as necessary in APL 
    because the vast majority of loops and things, are eliminated 
    because of APLs powerful set of functions and operators.

Structured programming concepts are still useful
for the decision constructs that APL really does not have.
These are (or at least, were) mostly implemented by programming idioms
involving the built-in functions and operators, e.g., "execute".
This is related to the use of programming idioms conventional languages;
for example, expressing unbounded repetition in C using "for(;;) {...}",
or the same thing in Pascal using "while true do ...",
or loop exits in Pascal with (gasp !  gag !) "goto".

There are shouts about preserving the purity of the language,
but it may well be that no one has done a sufficiently good job
of integrating structured programming features into APL.
But once a part of APL, "structured programming" features 
might not be recognized as such if done properly.  
    
    Another reason why I find APL more readable is its terseness.  
    ...
    The FORGOL program is the algorithm and has all kinds of superfluous 
    confusing things like the sum and index variables and the DO loop.
    
Furthermore, forcing the programmer of a FORTRAN or Algol derivative
to explicitly code irrelevant tasks means that the compiler is forced
to a large degree to perform these irrelevant tasks,
at a sometimes significant cost in execution efficiency.
This has important consequences for parallel and data flow architectures.
As has been mentioned elsewhere in this group, 
extracting the conceptual parallelism from a sequential procedure
is very difficult.  By expressing manipulations of vectors and arrays 
at a high level, APL comes closest of readily available languages
to leaving fundamental parallelism in programs, so that the compiler
or interpreter can deal with parallelism in a straightforward 
and efficient manner.
"Parallel Pascal" or "Vector C" is a language design and implementation 
effort; "Parallel APL" would only be a matter of implementation.

There is much for the language design and programming communities
to learn from APL, if only they can resist the fear of Greek letters.

-- Clay Phipps

-- 
   {cbosgd decvax!decwrl!amd70 harpo hplabs!hpda ihnp4 sri-unix ucbvax!amd70}
   !fortune!phipps

johnl@haddock.UUCP (06/27/84)

#R:decwrl:-198200:haddock:12300006:000:1625
haddock!johnl    Jun 26 11:04:00 1984

I also used to think that APL was unreadable, but discovered that I was
going about it the wrong way.  APL turns out to be quite readable once
you understand how to read it.  Certainly, if you try to read an APL
program the same way you'd read a C or Fortran program, you'd get quite
frustrated.

First, it's OK that it takes longer to read a line of APL that it takes
to read a line of Fortran, because a line of APL does more than a line of
Fortran.

Then, you have to read by idioms.  In Fortran, you can look at this and tell
pretty quickly what it does because you've seen it 1000 times before:

	xmax = 0
	do 100 i = 1, n
	   if(a(i) .gt. xmax) xmax = a(i)
100     continue

In APL, an analogous thing would be

	XMAX gets ceiling / A

which is as easy to read.  You read larger expressions by recognizing
familiar "idioms" (a term coined by A. J. Perlis, who has published long
lists of his favorite APL idioms.)  For example, "X iota X" is an idiom
used in finding or removing duplicates in a vector where the Nth element
is N if the corresponding entry in X is different from all the previous
ones and less than N if not, and "iota rho X" is the numbers from 1 to
the size of X, i.e. the subscripts of all of the entries in X.  So:

	((iota rho X) = X iota X) / X

turns out to be an expression that is X with the duplicates removed.  But
you look at that, recognize "X iota X" and "iota rho X" as familiar
idioms, and you're well on your way to understanding it.  After a while
you learn to recognize such larger idioms, too.

John Levine, ima!johnl

PS:  I still think that APL's I/O, in whatever version, stinks.

csgt@burdvax.UUCP (Steve Bartels) (06/27/84)

A possible reason why people find APL hard to read is that they compare
the time to understand 1 token in APL vs 1 token in other languages,
without realizing that each APL token is about equivalent to 15 or 20
tokens in Fortran, Algol, etc.  If they compared the time to understand
a program in APL vs a program in another language, APL will probably 
win.

With structure programming, I usually end up with lots of little
procedures that do higher-level operations on higer-level data types
than the language directly supports.  It is only recently that I have
realized that I have actually been defining another language, one that
is more suitable for my particular application needs.  The result is
that anyone looking at my code (or at anyone's SP code) has to know
two languages, this higher-level language and the base language.  And
each program will have a slightly different higher-level language!

APL avoids most of this by having the base language powerful enough
to support very high-level data types with only a few characters.
You don't need to define the little functions since it is easier to
enter what you need right on the line, and avoids any conflicts
between the two languages.

I know that there is alot more to SP than what I have been talking 
about.  However, this is something I noticed I have been doing in
ALGOL and PASCAL alot, and not in APL.  Reading other peoples programs
in PASCAL is a pain because I have to look up all these little
procedures to get their exact definition.  I don't have to look
up anything in APL.

Stephen R. Bartels
(APL programmer for 12 years, implementator for 6)
...!burdvax!csgt
Subject: Re: APL myths
Newsgroups: net.lang

darryl@ism780.UUCP (06/28/84)

#R:decwrl:-198200:ism780:14700004:000:870
ism780!darryl    Jun 26 20:01:00 1984

I must agree that one reads APL differently than most procedural languages.
However, the multitude of symbols can be confusing even when you (think)
you know what you are doing.  For example...  I once programmed John
Conway's "life" in APL.  In most procedural languages, one tries
to be very careful about the bookkeeping because the vanilla algorithm
can run into n^2 time.  No such worries in APL.  Four lines of code was
all (it can be done in less, of course).  The problem was, all I got
was "VALUE ERROR" after the first generation.  A friend, in no way involved
in programming, happened to come by after I had torn my hair out and asked
what my dilema was.  I showed him the "gibberish" and he looked at it for
a couple of seconds.  Then he pointed into the middle of it and said
"Is that a zero or an oh?"

	    --Darryl Richman
	    ...!cca!ima!ism780!darryl

ka@hou3c.UUCP (Kenneth Almquist) (07/04/84)

> Another reason why I find APL more readable is its terseness.  One short APL
> expression (average) could be several lines (or pages) of FORGOL:
>
>	DCL I integer;
>	dcl sum integer;
>
>	sum = 0;
>	do i = 1 to length(vector)
>	   sum = sum + vector(i);
>	   end;
>	print sum/length(vector);
>
> as opposed to the APL definition (written here in ascii-ized form):
>
>	(+/ VECTOR) % rho VECTOR

In PL/1 (one of the languages covered under the term "FORGOL") the
example becomes:
	sum(vector) / dim(vector)

Hardly a big difference from the APL version.

> I'm afraid that you've betrayed your lack of knowlege of APL by asking for
> a way to write structured APL (saying that you've used it, is different
> than saying that you understand it).   One of the best elements of APL is
> that it attempts to substitute powerful notation for procedural specification
> (structured programming is a concept of procedural languages which APL tries
> NOT to be).

If APL tries not to be a procedural language, it certainly does not succeed.
In ADA, I can write "array1 := array2" as a single assignment statement
rather than setting up a loop.  In PL/1 I can go farther, writing
"array1 = array2 + array3".  In FORTRAN, a matrix multiplication
is typically a single subroutine call requiring the programmer to
write no loops.

> In other words, SP concepts aren't as necessary in APL because
> the vast majority of loops and things, are eliminated because of APLs
> powerful set of functions and operators.

The vast majority of loops may be eliminated in APL, but what do you
mean by saying that "things" are eliminated?  I agree that APL frees
the programmer from writing a lot of loops, but I don't see how it
eliminates any other gotos.  Since FORTRAN has a "do" loop, you can
have loops in FORTRAN without using gotos.  So why is there any less
need for Rat-APL than for Ratfor?
				Kenneth Almquist