Proposal for control structures in APL (SAMSON) 
Author Message
 Proposal for control structures in APL (SAMSON)

I just looked at (again?) Dennis Samson's control operator proposal, in
Vector Jan '94.  There are some resemblances to what we've discussed.
It is elegant, although gets more ambitious and vague towards the appendix.

IF:    (control) -> { 1: then-part <> 0: else-part }
CASE:  (control) -> { val1: val2: part12 <> etc. }
WHILE: {control} -> { ... }  [ends when control does not match any label]

The "block" is an anonymous function with embedded line-breaks.
First part of the proposal is adding constant: labels to a _function_
or block; second part is the control _operator_ ->.  Argument passing
seems difficult or impossible.  Scoping is discussed very briefly at
the end, basically left open.  The appendix fills a couple of holes
in the design and proposes wildcard-like patterns or ranges for the
case labels.

For comparison, "my" proposal (1) was

IF:     (control) -> { then-part } { else-part }  [line-breaks within {}]
CASE:   (control) -> (val1) { part1 } (val2) { part2 } ... () { default }
WHILE:  {control} -> { ... }  [boolean control]

What this suggests to me, is that as far as syntax is concerned there is
convergence (by many?) on the use of {} and -> for non-keyword control
structures.  As for semantics, more people are considering scope issues
in the context of local direct definitions.

David Gurr commented on the entire thread by email and proposed using scheme;
here's a part of my reply:

"I am not quite ready to pronounce dynamic scope a _total_ bust; it is very

("Art of the interpreter--the modularity complex" MIT AI memo).  In any case,
unless your proposed route is taken we are stuck with it--but not completely!
My main point has been that, once delimited nested blocks are added to APL,
static/lexical scope for _local_ functions becomes well-defined and meaningful.
And of course useful, in giving APL structure and perhaps compilability.
My "gosub" proposal is intentionally the weakest form of lexically scoped local
function.  Of course it can be strengthened, if closures can be worked out
(I still have some questions) and "first class" becomes meaningful and useful.
As is, gosub already replaces unstructured goto for if-then-else and case.
I don't see any technical reason why it cannot be added to an existing APL.

"I am not in a position to implement these ideas.  Can you blame me for
"begging"?  What I want, is an APLish language that is terse, flexible,
more structured, and not any less efficient."

My proposal (3) is now something like

DEFN:   label(arg1;...;argN);local1;...;localK : { block }
RETURN: <- optional-return-value
GOSUB:  (val1;...;valN) -> label

A gosub without args replaces several gotos in if-then-else or case:

  ()->(case1,...,caseN)[index]
  case1: {...}
  ...
  caseN: {...}

It can be used as a control structure if something like (1) is unavailable.
Free variables inside the subroutine are resolved within the lexical context,
i.e. are lexically scoped; those that cannot be resolved in the enclosing
function are bound dynamically like other free variables but then become
static.  A subroutine with one or two arguments can be passed to an operator
or used in a called function.  However, it is not first class and is treated
as a local name (like current labels).  A goto out of a subroutine is an
exception escape that exits all intermediary sub-function and subroutine calls.

Finally, Kim Whitelaw's latest proposal is an interesting one, solving the
scoping problem using "strictly" local variables...




Wed, 26 Feb 1997 00:48:15 GMT  
 Proposal for control structures in APL (SAMSON)

Quote:

>The "block" is an anonymous function with embedded line-breaks.

  Is it really a function? { I don't have my copy of the Proceedings
   here, so I can't look it up} That is: it takes arguments, produces
   a result, and doesn't require [don't confuse with "permit"] side
   effects.

Quote:
>structures.  As for semantics, more people are considering scope issues
>in the context of local direct definitions.

>David Gurr commented on the entire thread by email and proposed using scheme;
>here's a part of my reply:

>"I am not quite ready to pronounce dynamic scope a _total_ bust; it is very


I think that dynamic scoping is the root of more problems in APL than
people care to admit. Certainly, about the ONLY argument I have seen
people make seriously in favor of it is:
   "Dynamic scoping lets me easily pass many arguments to a function,
    in an efficient manner."

Let's look at the other side:

a. Dynamic scoping is evil for labels {Branch to a label that's
   undefined in your function, and you branch to the line number
   corresponding to the next outer-most copy of that label.

b. Failure to localize a variable in a function makes YOUR CALLER
   break. Maybe.

c. There is, as pointed out by a number of posters, NO way to
   look at a function and determine what it does without examining
   the entire calling tree below the function.

d. Dynamic scoping does let you pass many arguments and results
   into and out of a function implicitly. Sometimes, as in (a,b,c)
   you don't even know it.

This suggests two things:

a. APL needs an effective way to pass more than two arguments to
   a function. The use of strand assignment and its J friend, the
   copula, I consider inelegant. In addition, I find that strands
   promote code faults, by turning syntax errors into arrays.

   I'd like to see this area worked on.

b. Dynamic scoping is a {*filter*} thing, and APL would be much better off
   without it. This is not news. The LISP community discovered this
   back in the Big Iron Age, and switched to lexical scoping.

   The APL community could move in this direction quite easily.
   Now, please excuse me for offering an implementation rather than
   a design [It really irks me when others do this...]:

      A function which uses ":" rather than ";" to delimit its
      locals will use lexical scoping. In particular, all of its
      locals will be invisible to its subfunctions.
      This also means than non-localized variables in subfunctions
      will not affect variables in the function containing the ":".

   Now, should those non-localized variables change variables ABOVE
   the ":" function on the stack? I think not, but am willing to
   listen to arguments otherwise, based on program maintainability, etc.

   What about non-locals in the ":" function? How should they act?
   I don't want to get into this, but would argue that a completely
   functional approach is superior.
   That is: Non-locals are an error.

The above scheme is:
   - A conforming extension to the ISO APL Standard
   - Implementable on any APL system without affecting existing applications
      (Same as the first assertion)
   - A good step toward lexical scoping
   - Relatively easy to implement, document, and teach.
   - Going to push people very strongly towards methods for passing
     many arguments/getting many results/ to functions.

Bob



Wed, 26 Feb 1997 07:31:23 GMT  
 Proposal for control structures in APL (SAMSON)
Robert Bernecky:
. I think that dynamic scoping is the root of more problems in APL
. than people care to admit. Certainly, about the ONLY argument I
. have seen people make seriously in favor of it is:
.    "Dynamic scoping lets me easily pass many arguments to a function,
.     in an efficient manner."

Dynamic scoping provides a mechanism for defining context in a
controlled fashion.

However, the absence of alternatives is evil.

. Let's look at the other side:

. a. Dynamic scoping is evil for labels {Branch to a label that's
.    undefined in your function, and you branch to the line number
.    corresponding to the next outer-most copy of that label.

The current implementation of labels sometimes requires an aggressive
approach to documentation.  For example, I fixed a bug in a menuing
function.  Several weeks later we tracked down a bug that had caused
occasional sessions to lock up (eating hours of CPU) -- the menuing
function had a branch to LABEL+3, and I'd added an instruction after
that label...

Another fun one is a function which returned values from symbols which
were only defined as labels in the calling function.

. b. Failure to localize a variable in a function makes YOUR CALLER
.    break. Maybe.

Or worse, a some other function somewhere else that was relying on
that variable.  This is basically the same problem that C programmers
face with "pointers".

A decent alternative goes a long way towards fixing this one.  I
prefer to run all my code through a routine derived from "FCL".  This
routine automatically localizes any name which is assigned in a
function [strand notation makes this a little context dependent,
unfortunately].  I've use some trivial comments to describe globals
exported to the calling environment, and to describe names which
should be localized even though they're not explicitly declared in
that function.

. c. There is, as pointed out by a number of posters, NO way to look
.    at a function and determine what it does without examining the
.    entire calling tree below the function.

True.  Sometimes manageable, sometimes not.

. d. Dynamic scoping does let you pass many arguments and results
.    into and out of a function implicitly. Sometimes, as in (a,b,c)
.    you don't even know it.

True.  I kind of like what I've seen about K's notation for functions
with more than two arguments.

. This suggests two things:

. a. APL needs an effective way to pass more than two arguments to a
.    function. The use of strand assignment and its J friend, the
.    copula, I consider inelegant. In addition, I find that strands
.    promote code faults, by turning syntax errors into arrays.

.    I'd like to see this area worked on.

Have you looked at K?

. b. Dynamic scoping is a {*filter*} thing, and APL would be much better
.    off without it. This is not news. The LISP community discovered
.    this back in the Big Iron Age, and switched to lexical scoping.

.    The APL community could move in this direction quite easily.
.    Now, please excuse me for offering an implementation rather than
.    a design [It really irks me when others do this...]:

.       A function which uses ":" rather than ";" to delimit its
.       locals will use lexical scoping. In particular, all of its
.       locals will be invisible to its subfunctions.  This also
.       means than non-localized variables in subfunctions will not
.       affect variables in the function containing the ":".

.    Now, should those non-localized variables change variables ABOVE
.    the ":" function on the stack? I think not, but am willing to
.    listen to arguments otherwise, based on program maintainability,
.    etc.

.    What about non-locals in the ":" function? How should they act?
.    I don't want to get into this, but would argue that a completely
.    functional approach is superior.  That is: Non-locals are an
.    error.

What's the difference between a variable and a function?  In
particularly, consider a niladic function which produces a result.
Compare this to a variable which is not assigned.

I think you've gone way beyond trying to provide a facility into
attempting to enforce that facility.

I would be happy with the following extensions:

Default handling of names may be specified (external/global, localized
  dynamically, localized statically), both on a per-workspace basis
  and on a per-function basis.
Individual names may be declared statically local or global.
Functions are given the same treatment as variables.

I could even suggest an implementation (a character to indicate each
state, a trailing character on line [0] indicates the default for that
routine, a system command to set the workspace default -- which would
only affect later definitions with the del editor, []FX or analog
would inherit default behavior from the routine which calls it).

However, I think that issue hints at a more general problem: an
occasional need to specify both compile time and run time behaviors.
Alternatively, we need to be talking about the action of building code
rather than the actions of the built code.

[Currently, we've just been talking about "user interface" changes,
rather than "computing model" changes.  My experience in maintaining a
large system leads me to believe that dealing with the user interface
allows rapid improvement, but ignoring the computational model
eventually leads to deep inconsistencies which eventually bubble up to
interfere with the user interface.

--
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



Thu, 27 Feb 1997 10:36:30 GMT  
 Proposal for control structures in APL (SAMSON)

Quote:

>Dynamic scoping provides a mechanism for defining context in a
>controlled fashion.

 Somehow, "controlled" is NOT the first word that leaps to my mind.
 Now "random", there's a word...

Quote:
>However, the absence of alternatives is evil.

 Agreed.

Quote:

>Have you looked at K?

No. K is undocumented, for those us in the public. I'll be PLEASED
to read any publically available K reference manual.

Quote:
>What's the difference between a variable and a function?  In
>particularly, consider a niladic function which produces a result.
>Compare this to a variable which is not assigned.

Maybe I'm missing something here, but I was trying to describe a
mechanism which would permit alteration of ONE function's behavior.
What's the relevance of the above comment?

Quote:
>I think you've gone way beyond trying to provide a facility into
>attempting to enforce that facility.

See above.

Bob



Thu, 27 Feb 1997 12:07:09 GMT  
 Proposal for control structures in APL (SAMSON)
After a little thought (an activity I do get involved in
occasionally), I think I've figured out how to simulate dynamic
(dynamically scoped) localization using only static (statically
scoped) locals:

For each item to by dynamically localized, make a static local in your
routine, with a different name.

At the begining of your routine, copy any global value to the static
local.

At the end of the routine, copy the static local to its corresponding
global name.

This assumes
(a) that the no-value can be detected and manipulated by the program.
(b) that exceptions do not bypass the cleanup code.
(c) that global variables may be manipulated by the program.

So, unless I've overlooked something obvious, an APL which implements
only statically scoped locals (and grants my three assumptions) may
mechanically translate a standard apl {quad}CR to an internal for with
equivalent semantics.

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

Personally, I would prefer a system where you declare globals, and
something about their usage and grammar.  Considered in this sort of
scoping scheme, backwards compatability would introduce one more
requirement: the names associated with the global symbol table must be
maintained at runtime for routines built from a {quad}CR which use
execute to construct names of apl objects.

--
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



Fri, 28 Feb 1997 13:05:45 GMT  
 Proposal for control structures in APL (SAMSON)

Quote:
>At the begining of your routine, copy any global value to the static
>local.

>At the end of the routine, copy the static local to its corresponding
>global name.

>This assumes
>(a) that the no-value can be detected and manipulated by the program.
>(b) that exceptions do not bypass the cleanup code.
>(c) that global variables may be manipulated by the program.

Well (b) is the tough one.  When an error occurs and the only way out is ->,
the workspace is shot.  You can keep a "registry" of assignments that must
be reversed in case of error; in effect you will have implemented (half of)
what is called "shallow binding".




Sun, 02 Mar 1997 00:37:05 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Proposal for control structures in APL

2. Proposal for control structures in APL

3. Control structures; discussion or proposal

4. Control Structures in APL

5. Control Structures in APL

6. Control structures in APL

7. APL Control Structures

8. Control structures in APL

9. Control structures in APL

10. control structures in APL

11. Control Structures in APL

12. Control structures in APL

 

 
Powered by phpBB® Forum Software