Control structures in APL 
Author Message
 Control structures in APL

Bill Chang:

Quote:
>Broken up into two lines, inside a loop for example.  Within a line
>(ignoring <>), APL is somewhat "functional".  However APL becomes
>very "imperative" across lines, with lots of side-effects, branches
>and loops.  I don't see how these can be evaluated
>"bottom-to-top".
Also:
>I disagree that functional view is best read bottom to top because
>unctional view doesn't work across lines, especially in the precence
>of branches and loops.

This is exactly the point against GOTO.
The main point to remember is that with goto's you have no structure,
only flow.
And as much as loops are an indication of scalar thinking instead of APL
array-thinking,
             GOTO INDICATES (and even forces you into)
             FLOW-THINKING INSTEAD OF STRUCTURE (or Blocks-) THINKING.

Indeed with Goto, bottom to top reading is much harder than with
structured control (in fact, any reading is harder unless the GOTO
is applied very structural). And as the GOTO is often at the
beginning of a block (assuming the programmer thinks in blocks) you
don't know the blockstructure if you enter it reading upwards (just
assuming you do; I know that very few people read a function upwards).
Reading from bottom to top, you see a label which indicates probably
the end of a block, but where does it start? you don't know
immediately.

In the previous days when there was a GOTO war, (long over now in all
languages, except in APL) someone suggested jokingly that he needed a
COMEFROM together with the GOTO. Reading APL in the functional view
(left-right up) this joke has a serious meaning. Because coming up
reading and meeting a label, you want to know where is the GOTO that
belongs to this label.

Bill Chang:

Quote:
>I think "break" and maybe "continue" are definitely needed; rather
>than scratching our heads figuring out what to use, why not a simple -> ?
>There are times when goto is appropriate; "case" and what you wrote below
>are typical examples.  If we can't come up with a really excellent case
>construct, then it's down to -> again.

I agree that CASE is the hardest nut to crack, probably because it is
connected with the problem of blockS (instead of one block).
Nevertheless I have much experience in programming with languages
without CASE, BREAK or CONTINUE. All my programs in those languages
were much better structured than my early APL (now I apply a special
labelling convention that makes blocks clear).
I never needed BREAK or RETURN (yes, when it was available in the
language I used it, but I never felt a problem when it was missing).
      !Remember that BREAK means that a block of
       code follows that you want to skip!
Furthermore (although I like CASE), any structuring even if it misses
CASE and BREAK is much better that GOTO.

If it is back to GOTO, I would rather accept Manugistics wordy structure
than APLs unstructured way.

____________________________________________________________________

Bill Chang repeats that control should be bottom-right or top-left.
I insist it should be bottomleft or topright. Why?
Look at a multiline function.
[3]...[2]...[1]...         [3]...[2]...[1]...
<----------------          ----------------->
parsing view               functional view
Let me give an example that spans several lines.
I will indicate the controlling expression by CCC and the expression to be
executed under control by EEE.

Current flow (label should better be placed at the end of a line [6]
instead of at the beginning):
[6]L3:.....[5].....[4].....[3]->(A>B)/L3 [2].....[1].....
              EEEEEEEEEEEEE   CCCCCCCCCC
My proposal using dyadic -> and { } situated top-right:
[6].....[5]{.....[4].....[3].....}->(A>B) [2].....[1].....
           EEEEEEEEEEEEEEEEEEEEEECCCCCCCC
Your proposal using dyadic -> and { } situated top-left:
[6].....[5]{.....[4].....[3](A>B)->{..... [2].....[1].....
           EEEEEEEEEEEEEEEEECCCCCCC EEEEE

A similar picture arises for the (by me used jokingly) alternative of
control at the bottom.

______________________________________________________________________

Bill also mentiones the problem of diamond.

Quote:
>etc. can be "normal" order (whichever way that is).  The "problem" is that
>an _expression_ of the form

> (expr1) - (control1) { expr
>                        expr
>                        result } - (control2) { expr
>                                                expr
>                                                result } + (expr2)

>has to have the trailing (expr2) evaluated first, then (control2), etc.
>With a lot of nesting this can be hard to read (find).  If + were <>,
>(expr2) would be evaluated last.  An explicit continuation symbol like
>fortran's may be needed as well.  One possibility, is to allow line break
>only after an open {, and/or to disallow controlled expression as the left
>argument of a function (kind of a "tail-recursive continuation").

I did not realise this before, but it is a problem indeed. Again this
illustrates why I have such a love/hate relationship with <>: love because
it enables me to put a number of short related expressions together,
hate because it has an unnatural flow.

Look at the functional flow and the parsing flow when there is no <>:
[6].....[5].....[4].....[3]..... [2].....[1].....

Quote:
>----------------------------------------------> functional flow

<------------------------------------------------ parsing flow

Even with loops (again, ignore the awkward choice of label position):
[6].....[5]->(10>I<-I+1)/L1 [4].....[3]L1:..... [2].....[1].....
<---------- =================================== --------------- parsing view
----------- =================================== --------------- functionalview

But with <> the flow changes to
[6].....[5].....[4]........<>.........[3]..... [2].....[1].....
                                       <--------- 1----------- parsing view
                  <---2-----
                             <---3-----
<----4-----------

( The dyadig left-tag is much better (I would say that I have a
( love/love relationship with left-tag) because I can put things
( together and the flow is not broken.

Yes, I think that for a control structure we should say that <> is
allowed in the controlled expression, but not in the controlling expression.
This is OK:
[6].....[5]{..<>...[4]..<>...[3]..<>...}->A>B [2].....[1].....
           EEEEEEEEEEEEEEEEEEEEEEEEEEEECCCCCCC
But this is not:
[6].....[5]{.....[4].....[3].....}->A>B <>..... [2].....[1].....
           EEEEEEEEEEEEEEEEEEEEEECCCCCCC

................................Eke van Batenburg



Sat, 15 Feb 1997 15:46:44 GMT  
 Control structures in APL
Eke van Batenburg:
. Indeed with Goto, bottom to top reading is much harder than with
. structured control (in fact, any reading is harder unless the GOTO
. is applied very structural). And as the GOTO is often at the
. beginning of a block (assuming the programmer thinks in blocks) you
. don't know the blockstructure if you enter it reading upwards (just
. assuming you do; I know that very few people read a function
. upwards).  Reading from bottom to top, you see a label which
. indicates probably the end of a block, but where does it start? you
. don't know immediately. ...

[much deleted]

I think it's important to distinguish between "APL as it has been" and
"APL as it could be" in this sort of discussion.  Furthermore, I think
it's important to recognize assumptions where they occur.

Here's one of my assumptions:

        The diamond (outside of comments)  is analogous to the current
        treatment of end-of-line.  They may be treated analogously for
        purposes of conceptualizing potential language improvements.

Also,
        APL already has a "block" concept -- the function.  What it's
        missing (except for J) is an "anonymous block".  Also, J's
        "anonymous block" is hard to nest.

......................................................................

Considered practically, here's the issues I'd like to see fixed in
future APLs:

A.      If a line is too long, I can't just break it across a couple
        lines.

B.      I frequently use a looping structure to get around limitations
        of my apl interpreter -- this looping structure occupies at
        least four lines (start/stop for the loop, viewed from the
        outside and from the inside).  I can live with this, but think
        there should be a simpler way of expressing this concept.

C.      I frequently need to write "optional" code -- again to get
        around limitations of the apl interpreter.  Sometimes I use
        execute, sometimes I use branch.  Neither of these makes for
        particularly easy to read code.

D.      I occasionally need to write command parsers.  However I do
        this, I need to somehow come up with a list of options from
        which I select one.  There's no particularly wonderful way of
        doing this (similar problem to C).

E.      I occasionally need to write "fancy" loops, where some
        initialization needs to occur under certain conditions (e.g.
        each time I hit a new file), or where there is more than one
        possible "loop body action" depending on some sort of easily
        tested condition.

F.      Occasionally (about once per "turnkey" application) I need to
        write an "infinite loop" for user interaction, which replaces
        six-space-indent.  Why can't I just install a six-space-indent
        replacement, after doing some initialization?

G.      APL functions of more than two variables get akward (though
        apparently K deals with this issue -- and perhaps others?).

Thinking back over these issues, two of the big problems I'm trying to
address are: data objects too big to fit into the workspace, and
sparse arrays.  Or, maybe these are just one issue viewed from two
different directions?

......................................................................

I think that anybody who implements an APL control structure
improvement should pay attention to existing work in that direction --
particularly if the work is part of a "small, clean" system.  I think
the major failing of INCA is that it doesn't pay attention to any of
the significant improvements in J (or K).  Personally, I place INCA in
the same mental category as QNIAL: it's got some neat stuff, but it's
too big and complex to be worth considering 100% compatability with
that system.

Actually, I place APL2 in a similar category.  First because of the
hidden assumptions of strand notation, second because of the huge
complexity introduced by APs.  J seems to be heading in a similar
direction, by the way (with major parts of the system shoved off to
the WP environment).

Or maybe I'm just being grumpy.

......................................................................

J does something pleasant: functions and operators (verbs, adverbs and
conjunctions) are "first class".  I can give them names, or not, as I
deem appropriate.  However, J implementations have tended to not give
me very efficient access to the underlying machine.  As a result, many
of the projects I've tackled in J have died an early death when it
turned out the machine I was using couldn't perform the calculations
-- or when it turned out that I was having to wait minutes or longer
for my results.

Speed is important.  Speed of program development is APL's "claim to
fame".  But code and data are frequently interchangeable.  And, when
it takes longer to run an APL program than it would to compile an
equivalent C program -- and when the APL program was supposed to be
one that helped in program development -- well, APL starts tasting a
bit bitter.

I think, fundamentally, the issues I'm trying to deal with when
talking about control structures are: speed and program viability.
However, viewed from this direction alone there is an answer which is
too easy: reduce the strength of the language.

Issues that I've left out are: ease in porting the language, ease in
teaching the language, and ease in specifying "the right general case
of the right algorithm".

--
Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

                         NB.  public e, n, y
                         x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q



Sun, 16 Feb 1997 09:01:58 GMT  
 Control structures in APL

Quote:
>Considered practically, here's the issues I'd like to see fixed in
>future APLs:

>A.  If a line is too long, I can't just break it across a couple
>    lines.

A "fix" shouldn't be too hard--allow line-break after <> or primitive
operator or unbalanced ( or [.  The whole thing has only one "line number".
A smart editor could do it, so the interpreter doesn't have to change.

Quote:
>B.  I frequently use a looping structure to get around limitations
>    of my apl interpreter -- this looping structure occupies at
>    least four lines (start/stop for the loop, viewed from the
>    outside and from the inside).  I can live with this, but think
>    there should be a simpler way of expressing this concept.


Quote:
>C.  I frequently need to write "optional" code -- again to get
>    around limitations of the apl interpreter.  Sometimes I use
>    execute, sometimes I use branch.  Neither of these makes for
>    particularly easy to read code.

I use ->(COND)/&+1 <> optional code.

Quote:
>D.  I occasionally need to write command parsers.  However I do
>    this, I need to somehow come up with a list of options from
>    which I select one.  There's no particularly wonderful way of
>    doing this (similar problem to C).


Quote:
>E.  I occasionally need to write "fancy" loops, where some
>    initialization needs to occur under certain conditions (e.g.
>    each time I hit a new file), or where there is more than one
>    possible "loop body action" depending on some sort of easily
>    tested condition.

The body of the loop is a nested if-then-else.

Quote:
>F.  Occasionally (about once per "turnkey" application) I need to
>    write an "infinite loop" for user interaction, which replaces
>    six-space-indent.  Why can't I just install a six-space-indent
>    replacement, after doing some initialization?

>G.  APL functions of more than two variables get akward (though
>    apparently K deals with this issue -- and perhaps others?).

Yes some kind of FUN(X;Y;Z) notation would be nice.  I don't think
it runs into existing notation.

Quote:
>Thinking back over these issues, two of the big problems I'm trying to
>address are: data objects too big to fit into the workspace, and
>sparse arrays.  Or, maybe these are just one issue viewed from two
>different directions?

I think APL2 etc. address these old problems fairly well.  These are
time problems as well as space problems.

Quote:
>I think that anybody who implements an APL control structure
>improvement should pay attention to existing work in that direction --
>particularly if the work is part of a "small, clean" system.  I think
>the major failing of INCA is that it doesn't pay attention to any of
>the significant improvements in J (or K).  Personally, I place INCA in
>the same mental category as QNIAL: it's got some neat stuff, but it's
>too big and complex to be worth considering 100% compatability with
>that system.

I don't know what you refer to by INCA (It's Not Called APL), do you mean
APL*PLUS III?  I don't think it's complex, just a bit rigid for my taste.
You don't have to use all of it, certainly.

Quote:
>I think, fundamentally, the issues I'm trying to deal with when
>talking about control structures are: speed and program viability.
>However, viewed from this direction alone there is an answer which is
>too easy: reduce the strength of the language.

Now that's another religious debate...

Quote:
>Issues that I've left out are: ease in porting the language, ease in
>teaching the language, and ease in specifying "the right general case
>of the right algorithm".

These relate back to the ASCII debate and box-vs-nest... basically everything.
I think, we should try to stay focused on proposing a simple but useful
block structure to APL.




Mon, 17 Feb 1997 22:25:59 GMT  
 Control structures in APL

Quote:
>Bill Chang:
>>I disagree that functional view is best read bottom to top because
>>functional view doesn't work across lines, especially in the precence
>>of branches and loops.

>This is exactly the point against GOTO...
>Indeed with Goto, bottom to top reading is much harder than with
>structured control (in fact, any reading is harder unless the GOTO
>is applied very structural).

I'm not sure it is possible to read bottom to top even with structures.
I still don't think the functional view works across lines, even without ->.

Quote:
>In the previous days when there was a GOTO war, (long over now in all
>languages, except in APL) someone suggested jokingly that he needed a
>COMEFROM together with the GOTO. Reading APL in the functional view
>(left-right up) this joke has a serious meaning. Because coming up
>reading and meeting a label, you want to know where is the GOTO that
>belongs to this label.

Actually there was a goto war in comp.lang.misc just recently, several
hundred messages at least.  Really, this issue is far from settled.
The way I see it, we are kind of stuck with ->.  If I modified a few
lines of a function (add an "if") but still need to goto some old label,
are you saying I'm forbidden from doing it from inside an "if" block?  

Quote:
>Bill Chang:
>>I think "break" and maybe "continue" are definitely needed; rather
>>than scratching our heads figuring out what to use, why not a simple -> ?
>>There are times when goto is appropriate; "case" and what you wrote below
>>are typical examples.  If we can't come up with a really excellent case
>>construct, then it's down to -> again.

>I agree that CASE is the hardest nut to crack, probably because it is
>connected with the problem of blockS (instead of one block).

Well, it is tough also because there are (logically) many controls, which
should be placed near the target code rather than at the "top".  Is it
always "select-one", or "select-many"?  If the latter, then in what order?

Quote:
>I never needed BREAK or RETURN (yes, when it was available in the
>language I used it, but I never felt a problem when it was missing).
>      !Remember that BREAK means that a block of
>       code follows that you want to skip!

Skip many times, if it's a "for" loop.

Quote:
>Furthermore (although I like CASE), any structuring even if it misses
>CASE and BREAK is much better that GOTO.

>If it is back to GOTO, I would rather accept Manugistics wordy structure
>than APLs unstructured way.

Well, Manugistics is adding :LEAVE.

Quote:
>____________________________________________________________________

>Bill Chang repeats that control should be bottom-right or top-left.
>I insist it should be bottomleft or topright. Why?

I'm still confused by your diagrams and the use of [number], hard as I tried.
Are they line numbers?  Or is it all taking place on one line?

Quote:
>Current flow (label should better be placed at the end of a line [6]
>instead of at the beginning):
>[6]L3:.....[5].....[4].....[3]->(A>B)/L3 [2].....[1].....
>              EEEEEEEEEEEEE   CCCCCCCCCC
>My proposal using dyadic -> and { } situated top-right:
>[6].....[5]{.....[4].....[3].....}->(A>B) [2].....[1].....  ?? line-breaks ??
>           EEEEEEEEEEEEEEEEEEEEEECCCCCCCC
>Your proposal using dyadic -> and { } situated top-left:
>[6].....[5]{.....[4].....[3](A>B)->{..... [2].....[1].....  ??????
>           EEEEEEEEEEEEEEEEECCCCCCC EEEEE

[about allowing <> inside control]
What about nested control, {...}->{...}->{...}->(A>B)?  (Here -> is "if".)
Are you saying (agreeing) we should disallow "controlled expressions" and only
allow "controlled statements", i.e. {{{...}->(E>F)}->(C>D)}->(A>B)?




Mon, 17 Feb 1997 23:46:57 GMT  
 Control structures in APL
Raul Deluth Miller:
. >Considered practically, here's the issues I'd like to see fixed in
. >future APLs:
. >
. >A.        If a line is too long, I can't just break it across a couple
. >  lines.

William Chang:
. A "fix" shouldn't be too hard--allow line-break after <> or
. primitive operator or unbalanced ( or [.  The whole thing has only
. one "line number".  A smart editor could do it, so the interpreter
. doesn't have to change.

I was thinking of an even simpler "fix".  Consider the line numbers
([1], ..) as part of the text of the program, with semantics similar
to <>.  Alternatively, allow {quad}CR to include embedded newlines.

. >B.        I frequently use a looping structure to get around limitations
. >  of my apl interpreter -- this looping structure occupies at
. >  least four lines (start/stop for the loop, viewed from the
. >  outside and from the inside).  I can live with this, but think
. >  there should be a simpler way of expressing this concept.

. Well, my style is to use ... <> ->(COND)/& for a one-line loop,

My usual loop style is:

->(LP<-((?VEC)?LOOP),DONE)[J<-#IO]
LOOP:
...
->LP[J<-J+1]
DONE:

Question mark is {rho}.  I can change the first line to something like
->(LP<-(LOOPA,LOOPB)[....],DONE)[J<-#IO]
if I need a decision in my loop.  For most purposes, I like this sort
of expression far better than the "repeat until this exception I'm
testing for" that I'd use for some sort of indefinite I/O situation.

. >C.        I frequently need to write "optional" code -- again to get
. >  around limitations of the apl interpreter.  Sometimes I use
. >  execute, sometimes I use branch.  Neither of these makes for
. >  particularly easy to read code.

. I use ->(COND)/&+1 <> optional code.

My automatic code handling tools run into more problems with this one
than with {execute}(COND)/'expression'

. >D.        I occasionally need to write command parsers.  However I do
. >  this, I need to somehow come up with a list of options from
. >  which I select one.  There's no particularly wonderful way of
. >  doing this (similar problem to C).


. right thing.

Sometimes, but what about menus or other multi-way choices?

. I don't know what you refer to by INCA (It's Not Called APL), do you
. mean APL*PLUS III?  I don't think it's complex, just a bit rigid for
. my taste.  You don't have to use all of it, certainly.

Er.. yeah (oops).  I've not used it because it requires me to use
windows, and I've wasted far more time on windows than I'd ever like
to.

Also, I've had a generic problem with Manugistic's interpreters: many
of the commands have severe restrictions on how much data you can deal
with.  Thus, I'm forever re-writing essentially the same code to
manage the larger chunks of data I wish to throw around.  This is
what's driving my interest in control structures.

APL's primitives have a lot of "control structure" built in to them --
with a major exception for the Manugistics extensions.

--
Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

                         NB.  public e, n, y
                         x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q



Tue, 18 Feb 1997 04:53:54 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Proposal for control structures in APL

2. Proposal for control structures in APL

3. Proposal for control structures in APL (SAMSON)

4. Control Structures in APL

5. Control Structures in APL

6. Control structures in APL

7. Control structures in APL

8. control structures in APL

9. Control Structures in APL

10. Control structures in APL

11. APL Control Structures

12. APL control structures -- new

 

 
Powered by phpBB® Forum Software