Strand notation
1 2 3
|
Strand notation, or stranding, is the convention that multiple (more than one) arrays written next to each other are automatically combined into a vector. In flat APLs it applies to numeric literals only and is generally called vector notation, while nested dialects allow arbitrary array expressions, as well as stranded assignment where it is used on the left hand side of an assignment. Stranding can make code easier to read by eliminating punctuation when writing small arrays. It can also cause frustration when programming if unrelated arrays are stranded together. This issue occurs when operators are allowed to take array operands, and can be resolved by inserting extra parentheses or identity functions into the expression.
A few recent array languages abandon the typical "invisible" stranding notation in favor of an explicit stranding character, the "ligature" ‿ in BQN and TinyAPL and underscore _ in Uiua. Array notation is an alternative way to form arrays from elements in languages that define it, and A+ uses the word "stranding" to refer to its vector notation, which is written like (a;b;c).
Examples
In all APLs, a sequence of numeric literals separated by spaces forms a vector. The traditional display shows numeric arrays with numbers separated only by whitespace, matching this syntax.
3.1 4 1 5 3.1 4 1 5
A strand is formed with higher precedence than function application, so it doesn't have to be parenthesized when used as an argument.
1 0 1 0/'abcd' ac
Nested APL extensions
In nested APLs, any sequence of arrays forms a strand. Below, a vector is formed from three elements 3.1, 'xyz', and ⍳4. The examples above are special cases of this behavior: when all elements are simple scalars, they form a simple vector.
3.1 'xyz' (⍳4) 3.1 xyz 1 2 3 4
In stranded assignment, variables on the left-hand side of an assignment are stranded together to assign to several at once. Most dialects don't require parentheses around a b c, but some such as APLX, ngn/apl, and Kap do.
(a b c) ← 2⍴¨⍳3
a c
1 1 3 3
Unexpected stranding
An example in which stranding interferes with the most obvious way of writing a program in modern APL is shown below. Consider applying the function f to 0.8 three times using the Power operator:
f⍣3 0.8
In a language which strands before function application, this expression is equivalent to the derived function f⍣(3,0.8). Not what was intended! The two numbers must be separated somehow, for instance with parentheses or a tack function.
(f⍣3)0.8 f⍣3⊢0.8
For operators that take array operands, such as the Rank operator, stranding before operator application can be beneficial. Without it, a function with two ranks such as ⊥⍤0 1 would have to be written with parentheses ⊥⍤(0 1).
Precedence
In APL\360, stranding has the highest possible precedence. Any other grouping could only lead to errors: for example, in 1 2 3[2], performing indexing 3[2] first would give a RANK ERROR, but even ignoring this would then result in an expression made up of two arrays, which isn't defined. Frequently this form of stranding is described as part of token formation rather than execution. Besides early flat APLs, languages with numeric stranding include SHARP APL, A+, J, and K.
APL2's extension of stranding to arbitrary arrays came with a reworking of the precedence, placing bracket indexing and the binding of a right operand before stranding. Because APL2 defines Replicate as an operator, stranding in the left operand could not be broken without changing the meaning of common expression like 1 1 0/A. The change to bracket indexing did however break backwards compatibility for expressions like 1 2 3[2], which changed from a meaningful result to an error.[1] Furthermore, in APL2 assignment binds tightly to its target, so that stranded assignment requires parentheses. While APLX and NARS2000 followed APL2's definitions precisely, other dialects generally perform all stranding before operator binding, and may or may not do it before bracket indexing or assignment.
| Dialects | stranding before: | operand before brackets? | ||
|---|---|---|---|---|
| assignment? | right operand? | brackets? | ||
| APL+Win | )EvLevel 1 | )EvLevel 1 | ||
| NARS, Dyalog | Yes | Yes | Yes | Yes |
| dzaima/APL | Yes | Yes | Yes | No |
| ISO/IEC 13751:2001 | N/A | Yes | Yes | No |
| Kap | Error | Yes | No | No |
| ngn/apl | No | Yes | No | No |
| GNU APL | No | Numbers | No | No |
| APL2, APLX, NARS2000 | No | No | No | No |
The ISO/IEC 13751:2001 standard supports nested arrays, but it defines stranding of numeric literals only, like a flat array language. GNU APL has a set of rules with special cases not found in other APLs, including dedicated parsing rules for the Rank and Power operators.
History
Vector notation was invented by Adin Falkoff during APL\360 development, before its 1966 release.[2] In IVSYS/7090, numeric vectors had been written with the Catenate function, echoing the parentheses and commas of sequence notation in mathematics and A Programming Language.
Strand notation as a generalization of vector notation was defined by Trenchard More in 1973, as part of his theory of nested arrays.[3] It was included along with stranded assignment in NARS in 1981 and APL2 in 1984. Despite the immediate adoption in nested APLs, it became a significant point of contention in the broader array model debate. Bob Smith and Jim Brown advocated for it as the natural adaptation of vector notation to a nested language and promoted the benefits of stranded assignment, while Ken Iverson questioned "whether the complexity of its full definition does not make its introduction unpalatable, particularly since it appears to offer less facility than the two straightforward functions link and pair."[4] He and Adin Falkoff pointed to new concerns exposed by allowing arbitrary subexpressions for elements, with Falkoff raising the question of order of evaluation in (A ← 2) B + A.[5] Later array languages in the SHARP APL lineage, including A+, J, and K, retain purely-numeric vector notation.
In 2020 the character ‿ was chosen as an explicit alternative by BQN's designer Marshall Lochbaum, who credited Richard Park for the concept.[6] It was adopted without changes in TinyAPL but modified for Uiua's _ syntax: to better fit the flat array model, rather than becoming elements of a vector, the entries must have the same shape and become cells of an array.
External links
Documentation
References
- ↑ Jim Brown. The Principles of APL2. IBM technical report. 1984-03.
- ↑ Adin Falkoff and Ken Iverson. The Evolution of APL (web) § 5. A Detailed Example. ACM SIGPLAN Notices, Volume 13, Number 8. 1978-08.
- ↑ Trenchard More. Axioms and Theorems for a Theory of Arrays. IBM Journal of Research and Development, Volume 17, Issue 2. 1973-03. p. 139.
- ↑ Ken Iverson, Bob Smith, and Jim Brown, ed. Arthur Anger. Correspondence: "On Strand Notation". APL Quote-Quad Volume 11, Number 3. 1981-03. p. 3-8.
- ↑ Adin Falkoff. Correspondence: "More on Strand Notation". APL Quote-Quad Volume 12, Number 2. 1981-12. p. 7-8.
- ↑ Marshall Lochbaum. BQN's development history § Array notation. Accessed 2025-09-05.