APL syntax and symbols

From Wikipedia, the free encyclopedia
Jump to: navigation, search

The APL programming language is distinctive in being symbolic rather than lexical: its primitives are denoted by symbols, not words. These symbols were originally devised as a mathematical notation. APL programmers often assign informal names when discussing functions and operators (for example, product for ×/) but the core functions and operators provided by the language are denoted by non-textual symbols.

Monadic and dyadic functions[edit]

Most symbols denote functions or operators. A monadic function takes as its argument the result of evaluating everything to its right. (Moderated in the usual way by parentheses.) A dyadic function has another argument, the first item of data on its left. Many symbols denote both monadic and dyadic functions, interpreted according to use. For example, ⌊3.2 gives 3, the largest integer not above the argument, and 3⌊2 gives 2, the lower of the two arguments.

Functions and operators[edit]

APL uses the term operator in Heaviside’s sense as a moderator of a function and operator (informally, however not strictly APL correct, as something that operates on data, ref. relational operator and operators generally) is sometimes used (albeit APL-definition incorrectly) as interchangeable with function.[1][2][3][4][5] Early definitions of APL symbols were very specific about how symbols were categorized, ref. IBM's 5100 APL Reference Manual, first edition, circa 1975.[6] For example, the operator reduce is denoted by a forward slash and reduces an array along one axis by interposing its function operand. An example of reduce:

In the above case, the reduce or slash operator moderates the multiply function. The expression ×/ evaluates to a scalar(1 element only) result through reducing an array by multiplication. The above case is simplified, imagine multiplying(adding, subtracting or dividing) more than just a few numbers together. (From a vector, ×/ returns the product of all its elements.)


The above dyadic functions examples[left and right examples] (using the same / symbol, left example) demonstrate how boolean values(0's and 1's) can be used as left arguments for the \ expand and / reduce functions to produce exactly opposite results. On the left side, the 2-element vector {45 67} is expanded where boolean 0's occur to result in a 3-element vector {45 0 67} - note how APL inserted a zero into the vector. Conversely, the exact opposite occurs on the right side - where a 3-element vector becomes just 2-elements; boolean zeroes delete items using the dyadic / slash function. APL symbols also operate on lists(vector) of items using data types other than just numeric, for example a 2-element vector of character strings{"Apples" "Oranges"} could be substituted for numeric vector {45 67} above.

Syntax rules[edit]

In APL there is no precedence hierarchy for functions or operators. APL's syntax rule is therefore different from what is taught in mathematics where, for example multiplication is performed before addition, under order of operations.

The scope of a function determines its arguments. Functions have long right scope: that is, they take as right arguments everything to their right. A dyadic function has short left scope: it takes as its left arguments the first piece of data to its left. For example(leftmost column below is actual program code from an APL user session, indented = actual user input, not-indented = result returned by APL interpreter):


An operator may have function or data operands and evaluate to a dyadic or monadic function. Operators have long left scope. An operator takes as its left operand the longest function to its left. For example:

* The left operand for the diaeresis each ¨ operator is the index ⍳ function. The derived function ⍳¨ ("iota") is used monadically and takes as its right the vector 3 3. The left scope of each is terminated by the reduce operator, denoted by the forward slash. Its left operand is the function expression to its left: the outer product of the equals function. (The syntax and 2-glyph symbol of the outer-product operator are both unhappily anomalous.) The result of ∘.=/ is a monadic function. With a function’s usual long right scope, it takes as its right argument the result of ⍳¨3 3. Thus



Monadic functions[edit]

Name(s) Notation Meaning Unicode codepoint
Roll  ?B One integer selected randomly from the first B integers U+003F
Ceiling B Least integer greater than or equal to B U+2308
Floor B Greatest integer less than or equal to B U+230A
Shape, Rho B Number of components in each dimension of B U+2374
Not, Tilde B Logical: ∼1 is 0, ∼0 is 1 U+223C
Absolute value B Magnitude of B U+2223
Index generator, Iota B Vector of the first B integers U+2373
Exponential B e to the B power U+22C6
Negation B Changes sign of B U+2212
Identity +B No change to B U+002B
Signum ×B ¯1 if B<0; 0 if B=0; 1 if B>0 U+00D7
Reciprocal ÷B 1 divided by B U+00F7
Ravel, Catenate, Laminate ,B Reshapes B into a vector U+002C
Matrix inverse, Monadic Quad Divide B Inverse of matrix B U+2339
Pi times B Multiply by π U+25CB
Logarithm B Natural logarithm of B U+235F
Reversal B Reverse elements of B along last axis U+233D
Reversal B Reverse elements of B along first axis U+2296
Grade up B Indices of B which will arrange B in ascending order U+234B
Grade down B Indices of B which will arrange B in descending order U+2352
Execute B Execute an APL expression U+234E
Monadic format B A character representation of B U+2355
Monadic transpose B Reverse the axes of B U+2349
Factorial  !B Product of integers 1 to B U+0021

Monadic APL Symbols Count(per above table) = 24

Dyadic functions[edit]

Name(s) Notation Meaning Unicode codepoint
Add A+B Sum of A and B U+002B
Subtract AB A minus B U+2212
Multiply A×B A multiplied by B U+00D7
Divide A÷B A divided by B U+00F7
Exponentiation AB A raised to the B power U+22C6
Circle AB Trigonometric functions of B selected by A
A=1: sin(B) A=2: cos(B) A=3: tan(B)
U+25CB
Deal A?B A distinct integers selected randomly from the first B integers U+003F
Membership, Epsilon AB 1 for elements of A present in B; 0 where not. U+2208
Maximum, Ceiling AB The greater value of A or B U+2308
Minimum, Floor AB The smaller value of A or B U+230A
Reshape, Dyadic Rho AB Array of shape A with data B U+2374
Take AB Select the first (or last) A elements of B according to ×A U+2191
Drop AB Remove the first (or last) A elements of B according to ×A U+2193
Decode AB Value of a polynomial whose coefficients are B at A U+22A5
Encode AB Base-A representation of the value of B U+22A4
Residue AB B modulo A U+2223
Catenation A,B Elements of B appended to the elements of A U+002C
Expansion, Dyadic Backslash A\B Insert zeros (or blanks) in B corresponding to zeros in A U+005C
Compression, Dyadic Slash A/B Select elements in B corresponding to ones in A U+002F
Index of, Dyadic Iota AB The location (index) of B in A; 1+⌈/⍳⍴A if not found U+2373
Matrix divide, Dyadic Quad Divide AB Solution to system of linear equations, multiple regression Ax = B U+2339
Rotation AB The elements of B are rotated A positions U+233D
Rotation AB The elements of B are rotated A positions along the first axis U+2296
Logarithm AB Logarithm of B to base A U+235F
Dyadic format AB Format B into a character matrix according to A U+2355
General transpose AB The axes of B are ordered by A U+2349
Combinations A!B Number of combinations of B taken A at a time U+0021
Diaeresis, Double-Dot A¨B Over each, or perform each separately; B = on these; A = operation to perform or using(e.g. iota) U+0308
Less than A<B Comparison: 1 if true, 0 if false U+003C
Less than or equal AB Comparison: 1 if true, 0 if false U+2264
Equal A=B Comparison: 1 if true, 0 if false U+003D
Greater than or equal AB Comparison: 1 if true, 0 if false U+2265
Greater than A>B Comparison: 1 if true, 0 if false U+003E
Not equal AB Comparison: 1 if true, 0 if false U+2260
Or AB Logic: 0 if A and B are 0; 1 otherwise U+2228
And AB Logic: 1 if A and B are 1; 0 otherwise U+2227
Nor AB Logic: 1 if both A and B are 0; otherwise 0 U+2371
Nand AB Logic: 0 if both A and B are 1; otherwise 1 U+2372

Dyadic APL Symbols Count(per above table) = 38

Operators and axis indicator[edit]

Name(s) Symbol Example Meaning (of example) Unicode codepoint sequence
Reduce (last axis), Slash / +/B Sum across B U+002F
Reduce (first axis) +⌿B Sum down B U+233F
Scan (last axis), Backslash \ +\B Running sum across B U+005C
Scan (first axis) +⍀B Running sum down B U+2340
Inner product . A+.×B Matrix product of A and B U+002E
Outer product ∘. A∘.×B Outer product of A and B U+2218, U+002E

Operators APL Symbols Count(per above table) = 6

Total APL Symbols Count listed(per tables above = monadic, dyadic, operators) = 68 (or 24+38+6)

Notes: The reduce and scan operators expect a dyadic function on their left, forming a monadic composite function applied to the vector on its right.

The product operator "." expects a dyadic function on both its left and right, forming a dyadic composite function applied to the vectors on its left and right. If the function to the left of the dot is "∘" (signifying null) then the composite function is an outer product, otherwise it is an inner product. An inner product intended for conventional matrix multiplication uses the + and × functions, replacing these with other dyadic functions can result in useful alternative operations.

Some functions can be followed by an axis indicator in (square) brackets, i.e. this appears between a function and an array and should not be confused with array subscripts written after an array. For example, given the ⌽ (reversal) function and a two-dimensional array, the function by default operates along the last axis but this can be changed using an axis indicator:


As a particular case, if the dyadic catenate "," function is followed by an axis indicator (or axis modifier to a symbol/function), it can be used to laminate (interpose) two arrays depending on whether the axis indicator is less than or greater than the index origin [9] (index origin = 1 in illustration below):

  • The Mathematical Shape of Things to Come "Scientific data sets are becoming more dynamic, requiring new mathematical techniques on par with the invention of calculus." by Jennifer Ouellette, October 4, 2013, Quanta Magazine.[10]

Flow control[edit]

The user may define custom functions which, like variables, are identified by name rather than by a non-textual symbol. The function header defines whether a custom function is niladic (no arguments), monadic (one right argument) or dyadic (left and right arguments), the local name of the result (to the left of the ← assign arrow), and whether it has any local variables (each separated by semicolon ';'). User functions:

Niladic function PI or π(pi): Monadic function CIRCLEAREA: Dyadic function SEGMENTAREA, with local variables:
 ∇ RESULT←PI
   RESULT←○1
 ∇
 ∇ AREA←CIRCLEAREA RADIUS
   AREA←PI×RADIUS⋆2
 ∇
 ∇ AREA←DEGREES SEGMENTAREA RADIUS ; FRACTION ; CA
   FRACTION←DEGREES÷360
   CA←CIRCLEAREA RADIUS
   AREA←FRACTION×CA
 ∇

Whether functions with the same identifier but different adicity are distinct is implementation-defined. If allowed, then a function CURVEAREA could be defined twice to replace both monadic CIRCLEAREA and dyadic SEGMENTAREA above, with the monadic or dyadic function being selected by the context in which it was referenced.

Custom dyadic functions may usually be applied to parameters with the same conventions as built-in functions, i.e. arrays should either have the same number of elements or one of them should have a single element which is extended. There are exceptions to this, for example a function to convert pre-decimal UK currency to dollars would expect to take a parameter with precisely three elements representing pounds, shillings and pence.[11]

Inside a program or a custom function, control may be conditionally transferred to a statement identified by a line number or explicit label; if the target is 0 (zero) this terminates the program or returns to a function's caller. The most common form uses the APL compression function, as in the template (condition)/target which has the effect of evaluating the condition to 0 (false) or 1 (true) and then using that to mask the target (if the condition is false it is ignored, if true it is left alone so control is transferred).

Hence function SEGMENTAREA may be modified to abort (just below), returning zero if the parameters (DEGREES and RADIUS below) are of different sign:

∇ AREA←DEGREES SEGMENTAREA RADIUS ; FRACTION ; CA ; SIGN     ⍝ local variables denoted by semicolon(;)
  FRACTION←DEGREES÷360
  CA←CIRCLEAREA RADIUS        ⍝ this APL code statement calls user function CIRCLEAREA, defined up above.
  SIGN←(×DEGREES)≠×RADIUS     ⍝ << APL logic TEST/determine whether DEGREES and RADIUS do NOT (≠ used) have same SIGN 1-yes different(≠), 0-no(same sign)
  AREA←0                      ⍝ default value of AREA set = zero
  →SIGN/0                     ⍝ branching(here, exiting) occurs when SIGN=1 while SIGN=0 does NOT branch to 0.  Branching to 0 exits function.
  AREA←FRACTION×CA
∇

The above function SEGMENTAREA works as expected if the parameters are scalars or single-element arrays, but not if they are multiple-element arrays since the condition ends up being based on a single element of the SIGN array - on the other hand, the user function could be modified to correctly handle vectorized arguments. Operation can sometimes be unpredictable since APL defines that computers with vector-processing capabilities should parallelise and may reorder array operations as far as possible - therefore, test and debug user functions particularly if they will be used with vector or even matrix arguments. This affects not only explicit application of a custom function to arrays, but also its use anywhere that a dyadic function may reasonably be used such as in generation of a table of results:

        90 180 270 ¯90 ∘.SEGMENTAREA 1 ¯2 4
0 0 0
0 0 0
0 0 0
0 0 0

A more concise way and sometimes better way - to formulate a function is to avoid explicit transfers of control, instead using expressions which evaluate correctly in all or the expected conditions. Sometimes it is correct to let a function fail when one or both input arguments are incorrect - precisely to let user know that one or both arguments used were incorrect. The following is more concise than the above SEGMENTAREA function. The below importantly correctly handles vectorized arguments:

 ∇ AREA←DEGREES SEGMENTAREA RADIUS ; FRACTION ; CA ; SIGN
   FRACTION←DEGREES÷360
   CA←CIRCLEAREA RADIUS
   SIGN←(×DEGREES)≠×RADIUS
   AREA←FRACTION×CA×~SIGN  ⍝ this APL statement is more complex, as a one-liner - but it solves vectorized arguments: a tradeoff - complexity vs. branching
 ∇

        90 180 270 ¯90 ∘.SEGMENTAREA 1 ¯2 4
0.785398163 0           12.5663706
1.57079633  0           25.1327412
2.35619449  0           37.6991118
0           ¯3.14159265 0

Avoiding explicit transfers of control also called branching, if not reviewed or carefully controlled - can promote use of excessively complex "one liners," veritably "misunderstood and complex idioms" and a "write-only" style, which has done little to endear APL to influential commentators such as Edsger Dijkstra[1]. Conversely however APL idioms can be fun, educational and useful - if used with helpful comments ⍝, for example including source and intended meaning/functionality of the idiom(s). Here is an APL idioms list, an APL2 idioms list here and another idiom library here.

Miscellaneous[edit]

Name(s) Symbol Example Meaning (of example) Unicode codepoint
High minus ¯ ¯3 Denotes a negative number U+00AF
Lamp, Comment ⍝This is a comment Everything to the right of ⍝ denotes a comment U+235D
RightArrow, Branch, GoTo →This_Label →This_Label sends APL execution to This_Label: U+2192
Assign, LeftArrow, Set to B←A B←A sets values and shape of B to match A U+2190

APL's "high minus" applies to the single number that follows, while the monadic minus function changes the sign of the entire array to its right.


Most APL implementations support a number of system variables and functions, usually preceded by the ⎕ (quad) and or ")" (hook=close parenthesis) character. Particularly important and widely-implemented is the ⎕IO (Index Origin) variable, since while the original IBM APL based its arrays on 1 some newer variants base them on zero:

User Session with APL Interpreter: Description:
        X←⍳12
        X
1 2 3 4 5 6 7 8 9 10 11 12
        ⎕IO
1
        X[1]
1

X set = to vector of 12 consecutive integers.

Initial index origin ⎕IO value = 1. Therefore the first position in vector X or X[1] = 1 per vector of iota values {1 2 3 4 5 ...}.

        ⎕IO←0
        X[1]
2
        X[0]
1
Index Origin ⎕IO now changed to 0. Therefore the 'first index position in vector X changes from 1 to 0. Consequently X[1] then references or points to 2 from {1 2 3 4 5 ...} and X[0] now references 1.
        ⎕WA
41226371072
Quad WA or ⎕WA, another dynamic system variable, shows how much Work Area remains unused or 41,226 megabytes or about 41 gigabytes of unused/additional total free work area available for the APL workspace/program to process using. If this number gets low or approaches zero - the computer may need more RAM, hard drive space or some combination of the two to increase virtual memory.
        )VARS
X
)VARS a system function in APL(see "The Workspace - System Functions", toward bottom of the web page), )VARS shows user variable names existing in the current workspace.

There are also system functions available to users for saving the current workspace e.g. )SAVE and terminating the APL environment, e.g. )OFF - sometimes called hook commands or functions due to the use of a leading right parenthesis or hook - see also APL language ref. pdf file. There is some standardization of these quad and hook functions.

Fonts[edit]

The Unicode Basic Multilingual Plane includes the APL symbols in the Miscellaneous Technical block,[12] which are therefore usually rendered accurately from the larger Unicode fonts installed with most modern operating systems. These fonts are rarely designed by typographers familiar with APL glyphs. So, while accurate, the glyphs may look unfamiliar to APL programmers or be difficult to distinguish from one another.

Some Unicode fonts have been designed to display APL well: APLX Upright, APL385 Unicode, and SimPL.

Before Unicode, APL interpreters were supplied with fonts in which APL characters were mapped to less commonly used positions in the ASCII character sets, usually in the upper 128 codepoints. These mappings (and their national variations) were sometimes unique to each APL vendor's interpreter, which, prior to 1987 (unicode created) made the display of APL programs on the Web, in text files and manuals - frequently problematic.

APL2 Keyboard Functions/Symbols Mapping
Note the APL On/Off Key - topmost-rightmost key, just below. Also note the keyboard had some 55 unique(68 listed per tables above, including comparative symbols but several symbols appear in both monadic and dyadic tables) APL symbol keys(55 APL functions/operators are listed in IBM's 5110 APL Reference Manual), thus with the use of alt, shift and ctrl keys - it would theoretically have allowed a maximum of some 59(keys) *4(with 2-key pressing) *3(with tri-key pressing, e.g. ctrl-alt-del) or some 472 different maximum key combinations, approaching the 512 EBCDIC character max(256 chars times 2 codes for each keys-combination). Again, in theory the keyboard pictured below would have allowed for about 472 different APL symbols/functions to be keyboard-input, actively used. In practice early versions were only using something roughly equivalent to 55 APL special symbols(excluding letters, numbers, punctuation, etc. keys). Thus early APL was then only using about 11%(55/472) of a symbolic language's at-that-time utilization potential, based on keyboard # keys limits, again excluding numbers, letters, punctuation, etc. In another sense keyboard symbols utilization was closer to 100%, highly efficient, since EBCDIC only allowed 256 distinct chars, and ASCII only 128.
APL2 Keyboard

How to Create an APL or Math Symbols Keyboard Layout[13]
Technical Keys including APL Keys, Unicodes tables and Symbol representations
More modern APL keyboard layout information

References[edit]

  1. ^ Baronet, Dan. "Sharp APL Operators". http://archive.vector.org.uk. Vector - Journal of the British APL Association. Retrieved 13 January 2015. 
  2. ^ MicroAPL. "Primitive Operators". http://www.microapl.co.uk. MicroAPL. Retrieved 13 January 2015. 
  3. ^ MicroAPL. "Operators". http://www.microapl.co.uk. MicroAPL. Retrieved 13 January 2015. 
  4. ^ Progopedia. "APL". http://progopedia.com. Progopedia. Retrieved 13 January 2015. 
  5. ^ Dyalog. "D-functions and operators loosely grouped into categories". http://dfns.dyalog.com. Dyalog. Retrieved 13 January 2015. 
  6. ^ IBM. "IBM 5100 APL Reference Manual". http://bitsavers.trailing-edge.com. IBM. Retrieved 14 January 2015. 
  7. ^ Iverson, Kenneth E. (1983). "APL syntax and semantics". ACM SIGAPL APL Quote Quad 13 (3): 223 – 231. doi:10.1145/800062.801221. Retrieved 18 January 2015. 
  8. ^ Gffer, M. (1989). "A Future APL: Examples and Problems". ACM SIGAPL APL Quote Quad 19 (4): 158 – 163. doi:10.1145/75144.75166. Retrieved 18 January 2015. 
  9. ^ Brown, Jim (1978). "In defense of index origin 0". ACM SIGAPL APL Quote Quad 9 (2): 7 – 7. doi:10.1145/586050.586053. Retrieved 19 January 2015. 
  10. ^ Ouellette, Jennifer. "The Mathematical Shape of Things to Come". https://www.quantamagazine.org. Quanta Magazine. Retrieved 19 January 2015. 
  11. ^ Berry, Paul "APL\360 Primer Student Text", IBM Research, Thomas J. Watson Research Center, 1969.
  12. ^ Unicode chart "Miscellaneous Technical (including APL)". 
  13. ^ Lee, Xah. "How to Create an APL or Math Symbols Keyboard Layout". http://xahlee.info. Xah Lee. Retrieved 13 January 2015. 

Further reading[edit]

  • Polivka, Raymond P.; & Pakin, Sandra (1975). APL: The Language and Its Usage. Prentice-Hall. ISBN 0-13-038885-8. 
  • Reiter, Clifford A.; Jones, William R. (1990). APL with a Mathematical Accent (1 ed.). Taylor & Francis. ISBN 978-0534128647. Retrieved 28 January 2015. 
  • Thompson, Norman D.; Polivka, Raymond P. (2013). APL2 in Depth (Springer Series in Statistics) (Paperback) (Softcover reprint of the original 1st ed. ed.). Springer. ISBN 978-0387942131. 
  • Gilman, Leonard; Rose, Allen J. (1976). A. P. L.: An Interactive Approach (Paperback) (3rd ed.). ISBN 978-0471093046. 

External links[edit]