APL Syntax and Semantics This paper presents a working model of APL syntax and semantics that incorporates explicit representations of functions, operators, and syntax, thus providing a basis for the clear and explicit statement of extended facilities in the language, as well as a tool for experimentation upon them. Use of the model is illustrated in the treatment of the syntax of operators, and in the discussion of a number of new or recently-proposed facilities including indirect assignment, the operators axis, derivative, inverse, and til, and the functions link, and from. The entire model is included in an appendix. The model is expressed in SHARP APL as extended in [1] but, because it uses few special features (enclose, disclose, close composition, and dual) it should translate easily into other systems (such as NARS [2] and APL2 [3]) that provide some form of enclosed arrays. We will begin with the overall behaviour of the model as seen in
the definition and use of the two outer
functions APL and S
(the “stack manager” that applies to the
left stack L of the expression to be
evaluated, and a right stack R of intermediate results),
and continue with the tabular definition of syntax,
and the representations of functions
and operators.
0-origin indexing is used throughout, and enclosed
arrays are normally displayed within enclosing vertical bars,
as determined by the setting The function APL accepts literal input and executes the expression entered, using definitions of extended functions and operators already provided. For example:
The function APL and its main supporting function are defined as follows: APL;Z;X;NORE;⎕ps NORE←<< 0 2 3 5 7 ⍴0×⎕ps← ¯1 ¯1 0 3 L1:→(^/' '=X←⍞,⍞←' ')/L1 →('⍝'≠1↑X←(+/∧\' '=X)↓X)/L2 ⍎1↓X →L1 L2:Z←(X←TK X) S '' →('←'=''⍴,>1↑(N X)/X)/L1 →L1,0⍴⎕←⍎((0=⍴⍴>Z)/'>'),'>Z' Z←L S R Z←⍎,>ACT[''⍴AC R] The main action is the application
of the stack manager S to an
empty right stack and a left stack of enclosed individual tokens
(names, primitives, constants, etc.)
produced by the tokenizing function TK .
The function S simply executes one of a set of actions
represented in the vector ACT ,
selection from ACT being determined
by the action and classes
function AC ,
which in turn depends on the
syntax table ST .
The following display of ACT appears in enclosing
bars because of ⍉,¨<ACT |(>''⍴Z)S(1↓Z←L LE 4=1↑,⍴⍤>⍴¨>R),R| |L S((>>R[0]) IS R[2]),3↓R| |L S(2↑R),(R[2]RE R[,3]),4↓R| |L S(1↑R),(R[1]RE R[,2],3↓R| |L S(1↑R),(R[2]RE E R[1 3]),4↓R| |L S(1↑R),(R[2]RE R[,1]),3↓R| |⍎'R[1]',(2<⍴R)/'R not clear∘'| In order to provide convenient tracing of the execution we incorporate in S three uses of a trace function TR as follows: Z←L S R Z←⍎,>ACT[''⍴' ACS' TR AC 'r: ' TR R],0⍴'l: ' TR L The display produced by TR consists of its left argument followed by its right, except that the number of rows displayed is limited by the magnitude of the trace control variable t0 ; if t0 is positive, the display is suppressed (except for a blank line) if the left argument of TR begins (as it does in the first occurrence of TR) with a space. Finally, the display of a function is limited to its primary part, the body and axes. Thus: APL ⍝t0←1 (÷4)+5 l: |(| |÷| |4| |)| |+| |5| r: l: |(| |÷| |4| |)| |+| r: ||5|| l: |(| |÷| |4| |)| r: |||⍝<<(>>⍺)+>>⍵|| ||⍝<<+>>⍵||| ||5|| l: |÷| |4| r: l: |÷| r: ||4|| l: r: |||⍝<<(>>⍺)÷>>⍵|| ||⍝<<÷>>⍵||| ||4|| l: r: |⍝| |||⍝<<(>>⍺)÷>>⍵|| ||⍝<<÷>>⍵||| ||4|| l: r: |⍝| ||0.25|| l: r: ||0.25|| |||⍝<<(>>⍺)+>>⍵|| ||⍝<<+>>⍵||| ||5|| l: r: |⍝| ||0.25|| |||⍝<<(>>⍺)+>>⍵|| ||⍝<<+>>⍵||| ||5|| l: r: |⍝| ||5.25|| 5.25 The five segments of this example beginning
with The “left evaluation” function LE handles the transfer of successive tokens from the input text to the righthand stack of intermediate results. Because the evaluated result in the right stack has no connection with the original names, the treatment of “side-effects” in expressions such as (a←3)(a←+)a←4 is clearly defined. For example: ⍝t0←0 (a←3)(a←+)a←4 0.75 a 3 The example may be repeated with t0 set to 1 . The function LE normally evaluates each token and transfers the evaluated result to the right stack, but if the first element on the right stack is an assignment arrow, the evaluation is suppressed. For example: a←'bcd' ⍝t0←1 a←a,a l: |a| |←| |a| |,| |a| r: l: |a| |←| |a| |,| r: ||bcd|| l: |a| |←| |a| r: |||⍝<<(>>⍺),>>⍵|| ||⍝<<,>>⍵||| ||bcd|| l: |a| |←| r: ||bcd|| |||⍝<<(>>⍺),>>⍵|| ||⍝<<,>>⍵||| ||bcd|| l: |a| r: |←| ||bcd|| |||⍝<<(>>⍺),>>⍵|| ||⍝<<,>>⍵||| ||bcd|| l: |a| r: |←| ||bcdbcd|| l: r: ||a|| |←| ||bcdbcd|| l: r: ||bcdbcd|| l: r: |⍝| ||bcdbcd|| ⍝t0←1 a bcdbcd ⍝→ A. Syntax APL syntax questions may be characterized as old or new, the latter referring to the new questions raised by the general treatment of operators, and the former to old problems introduced by anomalies such as the treatment of brackets and semicolons in indexing, in axis operators, and in mixed output. The old questions will here be treated as obsolescent, that is, nothing will be done to disturb existing definitions, either to invalidate their use in existing programs, or to extend them and encourage their use. The use of semicolons and brackets is therefore ignored in the model; in an actual implementation they could either be treated by established ad hoc mechanisms, or they could be eliminated by a “preprocessing” translation to equivalent normal expressions. The new questions are addressed in the model by the action and classes function AC , which examines the stack of intermediate results to determine what action is to be taken next. In the syntax proposed here, this function depends only on the first four elements of the intermediate results, and depends only on the class of each of these elements. The classes and their numeric encodings are as follows:
The encodings of the first four correspond to the valences of the entities represented (allowing 3 as the sum of the potential valences of a function). They also correspond to the ranks of the arrays whose enclosures represent the entities. Consequently the expression ⍴⍤>⍴¨>⍵ occurring in the function AC determines the class of each element of the argument ⍵ . The syntax rules are, in effect, the manner in which the next action is chosen according to the classes of the intermediate result. This choice is made by the function AC (Action and Classes) in two steps:
The proposed syntax table is defined as follows: ST ¯7 4 ¯7 6 1 1 3 0 ¯7 3 3 3 0 ¯7 3 5 3 0 ¯7 3 4 3 0 ¯7 3 2 0 3 0 2 ¯2 0 3 0 4 ¯2 ¯1 2 ¯7 4 ¯2 ¯1 1 ¯7 5 5 ¯5 ¯7 ¯7 6 ¯7 ¯7 ¯7 ¯7 0 However, it can be studied more easily in a display (produced by the function syntax) which substitutes for each numeric code a more mnemonic representation, and appends the corresponding action chosen from the table ACT . Thus: ⎕ps←-1 1 0 0 i←((-7 5 3 2 1),⍳7)⍳0 ¯1↓ST c←11 7↑'aLFDMvmdf←lr'[i] c,⍕ACT[ST[;,4]] a←ar L S((>>R[0]) IS R[2]),3↓R mfva L S(1↑R),(R[1]RE R[,2]),3↓R ffva L S(1↑R),(R[1]RE R[,2]),3↓R lfva L S(1↑R),(R[1]RE R[,2]),3↓R ←fva L S(1↑R),(R[1]RE R[,2]),3↓R dvfv L S(2↑R),(R[2]RE R[,3]),4↓R Dvfv L S(1↑R),(R[2]RE R[1 3]),4↓R DMda L S(1↑R),(R[2]RE R[1 3]),4↓R DMma L S(1↑R),(R[2]RE R[,1]),3↓R lLaa ⍎'R[1]',(2<⍴R)/'R not clear∘' aaaa (>''⍴Z)S(1↓Z←L LE 4=1↑,⍴⍤>⍴¨>R),R The action and class codes produced by AC are displayed if the trace control is set to a negative value. For example: to←¯1 APL a←3×4 l: |a| |←| |3| |×| |4| r: acs|0| |6| |6| |6| |6| l: |a| |←| |3| |×| r: ||4|| acs|0| |0| |6| |6| |6| l: |a| |←| |3| r: |||⍝<<(>>⍺)×>>⍵|| ||⍝<<×>>⍵||| ||4|| acs|0| |3| |0| |6| |6| l: |a| |←| r: ||3|| |||⍝<<(>>⍺)×>>⍵|| ||⍝<<×>>⍵||| ||4|| acs|0| |0| |3| |0| |6| l: |a| r: |←| ||3|| |||⍝<<(>>⍺)×>>⍵|| ||⍝<<×>>⍵||| ||4|| acs|4| |4| |0| |3| |0| l: |a| r: |←| ||12|| acs|0| |4| |0| |6| |6| l: r: ||a|| |←| ||12|| acs|1| |0| |4| |0| |6| l: r: ||12|| acs|0| |0| |6| |6| |6| l: r: |⍝| ||12|| acs|6| |5| |0| |6| |6| ⍝t0←0 ⍝→ The proposed syntax is that embodied in the table ST , the selection function AC , and the list of actions ACT . Experiments with different syntax rules can be made by changes in any or all of these. Such changes can affect the number of elements R examined, or can even affect the classes and number of elements produced by the actions. Thus, an action could produce 0 or 2 or 3 results rather than 1 as proposed here, and the results could be operators as well as functions and variables. The table ST may be compared with the syntax table of [5], which covers the obsolescent syntax, but not the syntax of operators. As stated in the introduction, parentheses are handled by an immediate recursive application of the model to the enclosed subexpression. With this premise, the remaining detailed syntax rules can be read directly from the display produced by the function syntax . However, the new features that extend the syntax to operators can be summarized as follows: Operators take precedence over functions and have long left scope; that is, an operator applies to the result produced by the entire operator sequence to the left of it. B. Representation of Functions and Operators The primary definition of a function concerns the specification of what result it produces when applied to an individual array of the lowest rank upon which it is properly defined. However, the complete definition of a function also concerns certain attributes which determine the effects of applying various operators to the function. For example, the axis (or axes) of application is an attribute of a function which determines how the function applies to a higher-rank array, an attribute which is modified by an axis operator, as in ⌽[i]a ; the identity element of a function is an attribute that determines the result of the reduction operator in certain cases, as in +/⍳0 or ×/⍳0 . The representation of functions adopted in the present model accommodates thirty attributes (of which 25 are actually used). The cases used are apparent from the following display of PF , the enclosed array (of shape 5 2 3) representing the prototype function: ⎕ps← -1 1 0 3 >PF |dbody| |mbody| |∘| ||7.237e75|| ||7.237e75|| ||7.237e75|| |loparg| |roparg| |∘| |||⍺||| |||⍵||| |||⍵||| |||| |||| |∘| |idf a¨∆| |idf ∆¨a| |idf ∆| |dcase a¨∆| |dcase ∆¨a| |∘| |a¨∆ ⍙| |∆ ¨a⍙| |∆⍙| |variant0| |variant1| |∘| |a¨∆*¯1| |∆¨a*¯1| |∆*¯1| The significance of each of the positions in PF will be made clear in the discussion of the corresponding attribute. The first plane of >PF is the primary definition, that is, the bodies of the dyadic and monadic cases, and the application axes. Bodies are represented in the direct definition form defined in [6], with three modifications:
The three axes accommodated are in the order left dyadic axis,
right dyadic axis, and right monadic axis. The specification of axes
is extended to include negative indexing
(in which ¯1 denotes the
ultimate axis, ¯2 the penultimate, etc.)
and complementary indexing,
in which a leading infinite value
(denoted by the The operator ⍫ (which will be discussed further in Section C), applied in the form f⍫∘ , produces a function that selects any desired section of the representation of a function f . APL d←+⍫∘ d 0 ||⍝<<(>>⍺)+>>⍵|| ||⍝<<+>>⍵|| |∘| |||| |||| |||| d 0 1 |||| |||| |||| +⍫∘ 0 0 0 ||⍝<<(>>⍺)+>>⍵|| As seen in the foregoing, a single index selects a plane (the bodies and axes), two select a plane and a row, and three select a given element. Since a variable is represented by a double enclosure, the last display above shows that the dyadic definition of a function + is the (raw) double enclosure of + applied to the double disclosure of the arguments. A monadic operator must be defined for two cases, a valence 0 argument (variable) and a valence 3 argument (function); a dyadic operator must be defined for four cases, two for each of its arguments. A monadic operator is therefore represented by an enclosed two-element vector, and a dyadic operator by an enclosed 2-by-2 matrix. For example: ⍤ |⍝⍺CONST⍵| || |⍝⍺AXIS⍵⋄⍵←⊃⍵| |⍝⍺COMP⍵| ⌿ || |⍝RED⍵| ∇ |⍝⍺DEL⍵| |∘| |∘| |∘| An example of the detailed definition of an operator may be seen in the function DEL used in the direct definition operator ∇ above. Thus: R←A DEL W R←>PF R[0;0; 0 1]←A,W R[2;0; 0 1]←(< Briefly, the result of ∇ is the prototype function with the bodies replaced by the arguments of ∇ , and with the local names (in row 0 of plane 2) replaced by the names to be localized, as determined by applying the function LOC to each of the arguments of ∇ . For example: APL f←b×b←a ←⍺+⍵'∇'c*c←d ←÷⍵' 2 f 5 49 a 7 f 2 0.7071 d 0.5 f⍫∘0 0 ||b×b←a ←⍺+⍵|| ||c*c←d ←÷⍵|| |∘| f⍫∘2 0 |||b||| |||c||| |∘| b value error LE[2]⍎ b ∧ The details of other operators may be examined in a similar manner by displaying the supporting functions AXIS , COMP , etc. It may be noted that, although some of the definitions of operators must resort to functions in raw APL, some of the definitions may also be expressed in terms of operators defined only in the model. For example, the inverse operator con (denoted by ⊂) is defined as follows: APL ⊂ || |⍵⍫i⍫⍵⍫(⌽i←''⊃4 1 2)| C. An Auxiliary Definition Operator An auxiliary definition operator, denoted by ⍫ and used earlier in the form f⍫∘i to display position i of the representation of a function f , is introduced for the purpose of modelling, and is not proposed as an operator to be incorporated in the language in its present form. Two further eases of it will be used in subsequent sections:
D. Operator Arguments Derived functions (resulting from the application of an operator) are represented in the general form presented in Section B; thus, the body and axes of ,⍤1 2 (ravel along axes 1 and 2) would appear as in the last two lines of the following example: APL f←,⍤1 2 q←2 3 4⍴⍳24 f q 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 F⍫∘ 0 ||⍺F⍵|| ||F⍵|| ||∘|| ||1 2|| ||1 2|| ||1 2|| The definition of a derived function depends upon the arguments of the operator which produced it, as well as upon the arguments to which it is applied; the arguments of the operator are referred to in the body by the names F and G , and are stored in locations 1 0 0 and 1 0 1 , that is, in the locations denoted by loparg and roparg in the prototype function PF . In the function f , the location 1 0 0 (that is, f⍫1 0 0) is the ravel function itself. Thus, 17↑ f⍫ 1 0 0 q 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 The following example illustrates the important fact that the arguments of an operator are bound at the time of its execution, and that subsequent reassignments to the names to which it applied do not affect the derived function produced: r←, g←r⍤ 1 2 r←⍴ g q 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 r⍤1 2 q 3 4 3 4 Because of the binding at execution time, the inverse function (in location 4 1 2 , and denoted by ∆*¯1 in PF) must also appear explicitly in the representation of a function and cannot, in general, consist of a reference to the name of the inverse function. Since this inverse function must likewise contain (in its location 4 1 2) an explicit inverse function, the scheme seems to imply an infinite regression of explicit functions. However, because the inverse of the inverse is the original function, this implied difficulty can be handled in the simple manner shown in the following definition of an inverse operator: ⊂ || |⍵⍫i⍫⍵⍫(⌽i←(<''),<4 1 2)| The definition may be read as follows: ⍵⍫i produces a function in which the whole of the argument function ⍵ (as selected by the empty first element of i) is replaced by element 4 1 2 of the same function, thus yielding the function inverse to ⍵ . The further expression ⍵⍫i⍫⍵ therefore “catenates” the inverse of ⍵ with ⍵ itself, and the final application of ⌽i therefore inserts in location 4 1 2 of the inverse function ⍵ , the original function. For example: l←* ⊂ p←l ⊂ l 3 1.099 p⍫∘ 0 0 1 ||⍝<<*>>⍵|| The analogous problem of explicitly representing successive
derivatives of a function does not yield to the method applied for
inverses, but can be handled by using the derivative
location (3 1 2)
to represent a dyadic function whose left argument k
determines the order of the index;
the index k will appear as the right operator
argument (in location 1 0 1 ,
and referred to by G) and will be
incremented on successive applications of the derivative operator.
E. Some New Functions The convenience of the function representation employed will be illustrated by showing the formal definitions of some new functions:
z←'abc' z abc z←⊣'abc' syntax error IS[1]⍎ no result∘ ∧ In the case of more complex functions, the axes of application may be seen even though the detailed definition of the body is subordinated in raw APL functions: APL {⍫∘0 ||⍝<<(>>⍺)FR2>>⍵|| ||⍝< In what follows we will use ⊃ to denote a form of the link function that encloses its left argument and catenates it to the right, first enclosing the right argument if it is simple. The foregoing function (called from) is defined briefly as follows: i{a is equivalent to inserting >i[j] before the jth semicolon of an expression of the form a[;;; ] . For example: m←4 4⍴⍳16 (2 1⊃3){m 11 7 (<2 1){m 8 9 10 11 4 5 6 7 i←3 2⍴1 0 2 1 3 0 i 1 0 2 1 3 0 i{m 4 9 12 The final case of a simple array to provide “scattered” indexing results from the definition of the left axis of application. The monadic case of { is the cartesian product. For example: { 2 1⊃4⊃6 7 2 4 6 2 4 7 1 4 6 1 4 7 The relation between the monadic and dyadic cases
of the function {
may be seen in the definition of the function FR2 .
F. Some New Operators We will discuss only two operators, the first (to be denoted by } ) because it is both powerful and relatively unknown, and the second (denoted by ¨) because it motivates a number of attributes provided for in the representation of functions. The first operator was introduced in [7] under the name til. It is defined as follows: } |∘| |∘| |∘| |'(G⍵)F⍺'∇'⍵∆⍵'⍫⍺⍫(1 0 0⊃⍳0)⍫⍵⍫(1 0 1⊃⍳0)| The main function is seen in the
expression '(G⍵)F⍺'∇'⍵∆⍵' ;
the rest simply inserts the function
arguments ⍺ and ⍵ in the
“operator argument”
locations The utility of til is discussed in
[7];
the main point is
that As defined in [1], the operator ¨ applied to one function and one array produces a monadic function resulting from providing the array as one argument to the dyadic function. For example, 10¨⍟ is the base 10 logarithm function, and *¨.5 is the square root function. As remarked in [7], two interesting points arise:
G. Indirect Addressing In the normal execution of an APL expression, each of the vector of tokens of the expression (placed in the left stack L in the model) is “evaluated” and the result of the evaluation is transferred to the stack of intermediate results (R in the model). However, a token which immediately precedes an assignment arrow must be exempted from this rule, and must be transferred “without evaluation“. For example: a←'abc' ⌽a cba a←5 a 5 abc value error Parentheses, however, imply that the enclosed expression is to be evaluated, and the result transferred to the stack of intermediate results. In an expression such as (a)←5 this rule conflicts with the stated rule for assignment and, in conventional APL, such an expression is treated as a syntax error. The conflict can be resolved by prescribing an order for the application of the two rules. In the present model, the rule for parentheses is applied first, with the obvious and convenient consequences illustrated by the following sequence: APL a←'abc' (a)←5 a abc abc 5 Since the result of evaluating an APL expression may be an array of enclosed names, the notion can be extended as shown by the following example: n←<⍤>'abcd' n |a| |b| |c| |d| m←4 3⍴⍳12 (n)←m a 0 1 2 d 9 10 11 ⍝→ The detailed definition of this indirect assignment may be seen in the function IS : W←A IS W;X;N1;B1 ⍎(NORE≡W)/'no result∘' →(1∊A∊<⍤>A)/L0 →0,0⍴A IS1 W L0:A←(,A),[0.5],(>>W) NUC1(⍴⍴A)↓⍳⍴⍴>>W L1:→(0=1↑⍴A)/0 X←A[0;] A← 1 0 ↓A →(1∊N1∊<⍤>N1←>X[0])/L2 →L1,0⍴N1 IS1 X[1] L2:→L1,0⍴N1 IS X[1] The auxiliary function IS1 is simple assignment, except for the fact that it handles assignments to graphic symbols as well as to names that are legitimate in raw APL. The function NUC1 encloses the “nuclei” determined by the axes specified by its right argument. Some interesting consequences of the definition of IS are illustrated by the following sequence in which j is assumed to be predefined (as shown): APL b←<4 5 6 b |4 5 6| (<'c')←b c 4 5 6 ⍝⎕ps←-2/1 3 j |¯¯¯¯¯¯¯¯¯| |¯¯¯| ||¯¯¯| |¯|| |bcd| ||abc| |b|| |___| ||___| |_|| | | ||¯| |¯|| ||c| |d|| ||_| |_|| |_________| (j)←j abc abc d d Since expressions of the form used for indirect addressing proposed
here are invalid in conventional APL, their introduction would
produce no conflict.
Their use would, however, conflict with a
different proposed use of parentheses to the left of assignment to
extend the use of indexed assignment to selection functions other than
“bracket” indexing
[3].
It should be noted that the dyadic “merge”
function i¨{ discussed in Section F
illustrates a general scheme for
using the operator ¨ together
with any selection function to provide
the effect of indexed assignment.
It should also be noted that the
explicit result of the
expression H. Index Origin A number of people (among whom Professor Penfield is perhaps the most persuasive) have long maintained that any benefits provided by the choice of index origin in APL are outweighed by the burden of controlling its effects. It is, of course, futile to propose that the present use of index origin be changed in any way; however, in the design of any new functions and operators one may choose to exclude dependence upon index origin, just as the choice was made in the design of APL\360 [8] to exclude dependence on index origin in the definition of the residue function, even though the earlier definition in [9] included it. Problems due to index origin appear to be magnified in the case of operators. For example, in g←f⍤i , are the axes used in the application of g to depend upon the origin in effect at the time of specifying g or at the time of applying g ? Or should it perhaps depend upon the index origins localized within the definitions of f and g as well? In any case, the present proposal is
to adopt a fixed index origin
for all new functions and operators
and to make this origin zero.
I. Idiosyncracies of the Model For practical reasons the model has not been made as general as it could be, and any person using or modifying it should perhaps be aware of some of the limitations and peculiarities, and some of the reasons for them. Thus:
Acknowledgements I am indebted to a number of my colleagues
at I.P. Sharp Associates,
particularly to Arthur Whitney
for material adapted from his earlier model,
and to Roland Pesch for comments arising
from his use of the model.
References
Appendix See the body of the paper for functions APL , S , DEL , D11 , and IS , for variables ST , ACT , and PF , for operators ⍤ , + , and ∇ , and for descriptions of variables P and t0 . Variables M Z1←DE DEX Q;SC;SG;FS;J;Z;AR;⎕trap ⎕trap←'∇ 8 c →L0',0⍴Z←>DE[2] ⍎(>>''⍴⌽AR←>DE[1]),'←''''⍴⌽Q',(⍴Z) SLB Z ⍎(1≠⍴Q)/(>>''⍴AR),'←''''⍴Q' SC←¯1⌽⍳⍴SG←>''⍴DE L0:→(0=SC)/L4 SC←1↓SC,0⍴FS←>SG[''⍴SC] →(∧/' '=FS)/L0 →('⍝'=1↑FS←(J←'→'=1↑FS)↓FS)/L1 →J↓L2,L3,0⍴Z←(TK FS) S '' L1:→J↓L2,L3,0⍴Z←⍎1↓FS L2:→L0,0⍴Z1←Z L3:→L0,SC←,>>Z L4:⎕trap←'∇ 6 C →0,0⍴Z1←NORE' Z1←Z1 CN abcdefghijklmnopqrstuvwxyzABCDEFG HIJKLMNOPQRSTUVWXYZ0123456789⎕¯.a Functions AC⋄(1↑(∧/0>Z)≠(|Z)=(⍴Z←0 ¯1↓ST)⍴X)⌿ST[;4]),X←4↑(,⍴⍤>⍴¨⍵),4⍴6 z←f AXIS i;j z←>''⍴PF,0⍴j←(<<'⍺F⍵'),(<<'F⍵'),(<<'∘') z[0;;]← 2 3 ⍴j,<¨>3⍴>>i z[1;0;0]←f z←<z CF⋄0≠⍴⍵,0⍴⎕ps←1⋄''⋄(⍎(⍺/'<,⍕'),',>1↑W'),(~⍺)CF 1↓⍵ CO⋄(1↑L)CF(L←'∧/⎕vi ⍵'ONA⍵)ENC⍵←⍵ z←a COMP b;q;j q←>''⍴b,0⍴z←>PF q[0;1;]←3⍴<⌊/0⍴j←(<<'(G⍺)F G⍵'),(<<'F G⍵') z[1;0; 0 1]←a,b)[0;1;] z←<z more stuff here TA⋄'(2×~(IQ ⍵)∨⍵∊CN)ENC ⍵'ONA(IQ⍵)ENC⍵ r←a TR r;k;l;z →(0=k←|l←>>t0)/0 z←(¯2↑1,⍴z)⍴z←⍕(t←, 0 1 ↓m←(s∊⍴¨>PF)⌽(<1, 2⌊k),2),[0.5] s←⍴¨>r)↑¨>r ((0>l)∨' '≠1↑a)/((k,⍴,a)⍴a),((k←k⌊1↑⍴z),¯1↑⍴z)↑z z←a UPON b;q z←>PF q←(b←>b)[0;1;] b[0;1;]←3⍴<<⌊/⍳0 z[1;0; 0 1]←a,<b z[0;;]← 2 3 ⍴(<'F⍺G⍵'),(<'F G⍵'),(<<'∘'),q z←<z Operators ⍫ || |⍝⍺D01⍵| |⍝⍺D10⍵| |⍝⍺D11⍵| ⍥ |∘| |∘| |∘| |⍝⍺UPON⍵| Originally appeared in the APL83 Conference Proceedings, APL Quote Quad, Volume 13, Number 3, 1983-03.
|