Array notation design considerations: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
(→‎History: removing irrelevance.)
 
(16 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[File:Array notation syntax.png|thumb|right|[[wikipedia:Railroad diagram|Railroad diagram]] for Dyalog's syntax.]]
This article details the design considerations for [[array notation]] in APL. Feedback may be given via the [[{{TALKPAGENAME}}|Discussion page]] or any other array language [[Chat rooms and forums|chat room or forum]], for example under the [https://forums.dyalog.com/viewtopic.php?f=13&t=1871 Array Notation Discussion topic] on the Dyalog Forums. This design considerations page, and if necessary the [[Array notation#Specification|specification]], will be kept up to date as feedback is received.
This page gives a precise description and history of [[Array notation]] in [[Dyalog APL]].


== Description ==
== Objectives ==
The notation is added to the language by giving meaning to previously invalid statements. The added syntax consists of three constructs that are currently [[SYNTAX ERROR]]s:


* ''broken'' round parentheses
The following requirements were proposed as objectives for an APL array notation:<ref>[[Adám Brudzewsky]]. Internal documents. [[Dyalog Ltd.]] 30 Jun 2017.</ref>
* ''broken'' square brackets
* empty round parentheses: <source lang=apl inline>()</source>


where ''broken'' means interrupted by one or more [[diamond]]s (<source lang=apl inline>⋄</source>) or line breaks (outside of [[dfn]]s).
# No new [[glyph]]s
# Reusing existing glyphs for similar purposes
# Similarity to other languages ([[K]], [[wikipedia:JSON|JSON]], [[wikipedia:CSS|CSS]])
# Visual attractiveness
# Intuitive syntax
# As little [[wikipedia:syntactic sugar|syntactic sugar]] as possible
 
== Specific considerations ==
 
Various alternatives have been considered and the following details each design decision.
 
=== Glyphs ===
 
The design requirement for no new glyphs was contentious, and both [[bi-glyph]] and non-ASCII brackets were considered. Bi-glyphs were rejected out of readability concerns, especially when nested. For example, <syntaxhighlight lang=apl inline>1 1 3⍴2</syntaxhighlight> could have been written as <syntaxhighlight lang=apl inline>[[[[2 2 2]]]]</syntaxhighlight>. Non-ASCII brackets were rejected for font and keyboarding reasons, as well as to make it easier for non-APL systems to generate APL data. For example, <syntaxhighlight lang=apl inline>⟦</syntaxhighlight>…<syntaxhighlight lang=apl inline>⟧</syntaxhighlight> was proposed to denote a collection of [[major cells]], forming a new array of rank one-higher than the rank of the highest-[[rank]] constituent [[cell]]. However, few [[fonts]] support these glyphs.
 
The eventual choice was to go with existing symbols, and this had important implications for the specifics of the notation. While ideally, a notation would have been introduced for a collection of major cells, thereby handling both vectors and higher-rank arrays, a problem presents itself with [[axis|axes]] of length 1, because both square brackets and round parentheses already have meaning with when surrounding a single statement (namely [[function axis]]/[[bracket indexing]] and [[precedence]]/[[function train]]s). Thus, while <syntaxhighlight lang=apl inline>2 ⟦3⟧</syntaxhighlight> could have denoted the [[nested array]] <syntaxhighlight lang=apl inline>2 (1⍴3)</syntaxhighlight>, this isn't viable with <syntaxhighlight lang=apl inline>2 [1⍴3]</syntaxhighlight> because this already denotes indexing <syntaxhighlight lang=apl inline>2</syntaxhighlight> using the indices <syntaxhighlight lang=apl inline>1⍴3</syntaxhighlight>. To disambiguate, at least one statement separator or line break must be present in each level of array notation brackets and parentheses.
 
=== Disambiguating square brackets ===
 
The overloading of square brackets, currently in use only for [[function axis]] and [[bracket indexing]], to mean a higher-rank array, poses a problem of disambiguation in the case where there is only one major cell. For example <syntaxhighlight lang=apl inline>'abc'[3 3]</syntaxhighlight> could be equivalent to <syntaxhighlight lang=apl inline>'cc'</syntaxhighlight> or <syntaxhighlight lang=apl inline>'abc'(1 2⍴3)</syntaxhighlight> depending on whether the brackets are interpreted as indexing or an array. Two proposals have been made, and it is possible to support either or both:
# Square brackets are interpreted as representing an array if no other interpretation is possible, e.g. immediately following an opening round parenthesis, curly brace, or square bracket, or beginning a statement.
# Square brackets are interpreted as representing an array if they are "broken", i.e. contain a diamond or newline that isn't enclosed in another round parenthesis, curly brace, or square bracket.
Option 1 depends on an outer context of the notation, while option 2 depends on the inner content of the notation. The latter has similarity to the manner in which a [[dfn]] is determined to be a function, a monadic operator, or a dyadic operator: If the curly braces ''contain'' <syntaxhighlight lang=apl inline>⍵⍵</syntaxhighlight> then the dfn is a dyadic operator; otherwise, a <syntaxhighlight lang=apl inline>⍺⍺</syntaxhighlight> indicates a monadic operator; and any other dfn is a function.
 
=== Minimum rank of major cells ===
 
While <syntaxhighlight lang=apl inline>⟦⟦3⟧⟧</syntaxhighlight> could denote <syntaxhighlight lang=apl inline>1 1⍴3</syntaxhighlight> using non-ASCII glyphs, an equivalent ASCII scheme instead would have required <syntaxhighlight lang=apl inline>[[3⋄]⋄]</syntaxhighlight> where the inner bracket creates a vector, and the outer creates a [[matrix]]. Using line breaks instead of diamonds, it was found to be counter-intuitive that <syntaxhighlight lang=apl>[
3
5
  ]</syntaxhighlight> was to denote two-[[element]] vector while <syntaxhighlight lang=apl>[
3 4
5 6
    ]</syntaxhighlight> would be a two-row matrix. This is indeed the case in [[dzaima/APL]], as opposed to in [[Dyalog APL]], where a special rule was added to the effect that in such collections of major cells, every cell will be considered to have a rank of at least 1, even if it is  a [[scalar]]. However, this choice introduced the need for a separate notation to allow vectors to be written over multiple lines, and therefore the round parentheses were extended from their traditional use in [[strand notation]] to also denote collections of [[enclose]]d elements.
 
=== Name-value pairs ===
 
As a notation for [[namespace]]s, several details were debated, as detailed below.
 
==== Separators between name-value pairs ====
 
Should <syntaxhighlight lang=apl inline>⋄</syntaxhighlight> or <syntaxhighlight lang=apl inline>;</syntaxhighlight> be used to separate [[wikipedia:name-value pair|name-value pair]]s (in addition to line breaks)?
 
The <syntaxhighlight lang=apl inline>⋄</syntaxhighlight> was chosen to separate name-value pairs, as it is generally exchangeable with a line break, while <syntaxhighlight lang=apl inline>;</syntaxhighlight> though it is used to separate names ― without values ― in [[Defined_function_(traditional)#Semi-colons|headers]] and in [[locals lines]]. Furthermore, it was seen as natural the values would be computed in reading order (left-to-right) just like multiple statements are, and while <syntaxhighlight lang=apl inline>⋄</syntaxhighlight> would imply this, <syntaxhighlight lang=apl inline>;</syntaxhighlight> wouldn't. Indeed, in the statement <syntaxhighlight lang=apl inline>A[B;C]</syntaxhighlight>, expression <syntaxhighlight lang=apl inline>C</syntaxhighlight> is evaluated before expression <syntaxhighlight lang=apl inline>B</syntaxhighlight>. It was briefly considered to have values computed from the right, just line stranding is, but this was rejected because replacing the semi-colons with line breaks would then require evaluation beginning with the last line and working upwards!
 
==== Namespace delimiters ====
 
Should round parentheses (<syntaxhighlight lang=apl inline>(</syntaxhighlight>…<syntaxhighlight lang=apl inline>)</syntaxhighlight>) or square brackets (<syntaxhighlight lang=apl inline>[</syntaxhighlight>…<syntaxhighlight lang=apl inline>]</syntaxhighlight>) be used to enclose namespaces?
 
Round parentheses were chosen because namespaces are seen as (unordered) lists, and so are more similar to vectors than higher-rank arrays. Furthermore, <syntaxhighlight lang=apl inline>[]</syntaxhighlight> already had meaning (indexing all elements of a vector) while <syntaxhighlight lang=apl inline>()</syntaxhighlight> didn't have any existing use, and so could be used to denote a new empty namespace, equivalent to <syntaxhighlight lang=apl inline>⎕NS 0⍴⊂''</syntaxhighlight>.
 
==== Separator between name and value ====
 
Should <syntaxhighlight lang=apl inline>:</syntaxhighlight> or <syntaxhighlight lang=apl inline>←</syntaxhighlight> separate the name from the value?
 
While initially, <syntaxhighlight lang=apl inline>←</syntaxhighlight> was seen as the obvious choice to separate the name and the value, it was soon discovered that a namespace with only one member would be indistinguishable from a parenthesised [[assignment]]. Furthermore, it was noted that value expressions could contain intermediary assignments, and that such assignments were of a fundamentally different nature from the name-value declaration. The intermediary assignments would happen in a temporary scope, with any created variables disappearing once the namespace member value was established.


* A ''broken'' round parenthesis creates a [[namespace]] if every diamond/line break-separated statement is a ''name-value pair''.
==== Scoping ====
* A ''broken'' round parenthesis creates a [[vector]] if every diamond/line break-separated statement is a value expression. In that case, every such statement forms an [[element]] in the resulting vector.
* A ''broken'' square bracket creates a an [[array]] where every diamond/line break-separated statement forms a [[major cell]] in the resulting array.
* <source lang=apl inline>()</source> is equivalent to <source lang=apl inline>(⎕NS 0⍴⊂'')</source>
* A ''name-value pair'' consist of a valid APL identifier, followed by a <source lang=apl inline>:</source> and a value expression.


=== Formal syntax ===
In which scope the value expressions should be evaluated?
The array notation can be described using [[wikipedia:Extended Backus–Naur form|Extended Backus–Naur form]], where an <code>expression</code> is any traditional APL expression:
<pre>
value    ::= expression | list | block | space
list    ::= '(' ( ( value sep )+ value? | ( sep value )+ sep? ) ')'
block    ::= '[' ( ( value sep )+ value? | ( sep value )+ sep? ) ']'
space    ::= '(' sep? ( name ':' value ( sep name ':' value )* )? sep? ')'
sep      ::= [⋄#x000A#x000D#x0085]+
</pre>


== History ==
Value expressions could be evaluated in the newly established namespace (similar to expressions in <syntaxhighlight lang=apl inline>:Namespace</syntaxhighlight> scripts), or in the surrounding scope (similar to inline expressions in [[wikipedia:JavaScript|JavaScript]]'s object notation). It was envisioned that a main usage of the literal notation would be to collect existing values into a namespace, and evaluating inside the new namespace would force the use of <syntaxhighlight lang=apl inline>##.</syntaxhighlight> to fetch values in the surrounding scope. In a departure from JavaScript, it was found most natural that such intermediate assignments be local to the value expression, similar to assignments in dfns. Global assignment is still available using <syntaxhighlight lang=apl inline>⎕THIS.name←value</syntaxhighlight>, just as in dfns.
 
After publication of the formal proposal,<ref name=formprop/> Peter Mikkelsen, a then recently hired [[Dyalog Ltd]] employee<ref>[[Dyalog Ltd]]. [https://www.dyalog.com/meet-team-dyalog.htm#Peter Meet Teem Dyalog: Peter]. Retrieved May 2nd, 2023.</ref>, pointed out an inconsistency between value expressions in namespace and vector notation:
 
<syntaxhighlight lang=apl inline>g←1 ⋄ (a:g←2 ⋄ b:g)</syntaxhighlight> would make <syntaxhighlight lang=apl inline>(a:2 ⋄ b:1)</syntaxhighlight> but <syntaxhighlight lang=apl inline>g</syntaxhighlight> remains <syntaxhighlight lang=apl inline>1</syntaxhighlight>
 
while
 
<syntaxhighlight lang=apl inline>g←1 ⋄ (g←2 ⋄ g)</syntaxhighlight> would make <syntaxhighlight lang=apl inline>(2 ⋄ 2)</syntaxhighlight> updating <syntaxhighlight lang=apl inline>g</syntaxhighlight> to be <syntaxhighlight lang=apl inline>2</syntaxhighlight>.
 
Because of this, the specification was changed on May 5, 2023 to follow JavaScript; that assignments inside value expressions then affect the surrounding scope. Auto-localisation of temporary variables used in building the value can then be achieved by wrapping the expression in an anonymous [[dfn]].
 
== Timeline ==


=== 1996 ===
=== 1996 ===


The publication of [[John Scholes' ''Dynamic Functions in Dyalog APL'' <ref>[[John Scholes|Scholes, John M.]] https://www.dyalog.com/uploads/documents/Papers/dfns.pdf Dynamic Functions in Dyalog APL]</ref> showed that a number of expressions could be grouped together within paired delimiters and separated by line-ends. This hinted at the possibility of doing a similar thing between brackets and parentheses to solve a problem for which Phil Last had been seeking a solution for a decade.  
The publication of [[John Scholes]]' ''Dynamic Functions in Dyalog APL'' <ref>[[John Scholes|Scholes, John M.]] https://www.dyalog.com/uploads/documents/Papers/dfns.pdf Dynamic Functions in Dyalog APL]</ref> showed that a number of expressions could be grouped together within paired delimiters and separated by line-ends. This hinted at the possibility of doing a similar thing between brackets and parentheses to solve a problem for which Phil Last had been seeking a solution for a decade.


=== 2010 ===
=== 2010 ===


At the 2010 APL Conference in Berlin Dyalog introduced experimental interpreter [[APL#]]. This included a notation for namespaces as name-value pairs between paired double brackets with major and minor separators being line-end and assignment arrow: <source inline>[[name←value ⋄ ...]]</source>; and a sort of extended, multiple expression separated by line-ends and between paired parentheses.  
At the 2010 APL Conference in Berlin Dyalog introduced experimental interpreter [[APL#]]. This included a notation for namespaces as name-value pairs between paired double brackets with major and minor separators being line-end and assignment arrow: <syntaxhighlight lang=text inline>[[name←value ⋄ ...]]</syntaxhighlight>; and a sort of extended, multiple expression separated by line-ends and between paired parentheses.  


=== 2013 ===
=== 2013 ===


Phil Last sent a proposal to Dyalog outlining two possible executable notations for creating multi-dimensional arrays without function application. One using potential new system construct :Array and :Cell to be used in tradfns and another using line-ends between balanced brackets to define arrays of rank-2 or greater in both dfns and tradfns.
Phil Last sent a proposal to Dyalog outlining two possible executable notations for creating multi-dimensional arrays without function application. One using potential new system construct <syntaxhighlight lang=text inline>:Array</syntaxhighlight> and <syntaxhighlight lang=text inline>:Cell</syntaxhighlight> to be used in tradfns and another using line-ends between balanced brackets to define arrays of rank-2 or greater in both dfns and tradfns.


It became RFE 9458: Large and higher rank literal values.  See [[File:Embedding data.pdf]]
It became RFE 9458: Large and higher rank literal values.  See [[File:Embedding data.pdf]]
Line 53: Line 103:


=== 2015 ===
=== 2015 ===
At [[Dyalog '15]], [[Phil Last]] explained that he considered the lack of such a notation a big hole in APL notation and gave a suggestions for such a notation. He presented a model using square brackets to indicate collections of [[major cell]]s of [[rank]] 1 or higher, delimited by line breaks and/or [[diamond]]s, for example <source lang=apl inline>[1 2 3 ⋄ 4 5 6]</source> would be equivalent to <source lang=apl inline>2 3⍴1 2 3 4 5 6</source>. He also proposed that if the delimited expressions were [[assignment]]s, then the notation would instead declare members of an anonymous [[namespace]], for example for example <source lang=apl inline>[a←3 ⋄ b←6]</source>. He pointed out that this overloading of the symbols meant that the array notation could only represent constants, as allowing general expressions would lead to ambiguity. He also mentioned that doubled symbols or [[Unicode]] brackets could be used instead.<ref>[[Phil Last|Last, Phil]]. [https://dyalog.tv/Dyalog15/?v=9-HAvTMhYao APL Array Notation] ([https://www.dyalog.com/uploads/conference/dyalog15/presentations/U07_APL_Array_Notation.pdf transcript]). [[Dyalog '15]].</ref>
At [[Dyalog '15]], [[Phil Last]] explained that he considered the lack of such a notation a big hole in APL notation and gave a suggestions for such a notation. He presented a model using square brackets to indicate collections of [[major cell]]s of [[rank]] 1 or higher, delimited by line breaks and/or [[diamond]]s, for example <syntaxhighlight lang=apl inline>[1 2 3 ⋄ 4 5 6]</syntaxhighlight> would be equivalent to <syntaxhighlight lang=apl inline>2 3⍴1 2 3 4 5 6</syntaxhighlight>. He also proposed that if the delimited expressions were [[assignment]]s, then the notation would instead declare members of an anonymous [[namespace]], for example for example <syntaxhighlight lang=apl inline>[a←3 ⋄ b←6]</syntaxhighlight>. He pointed out that this overloading of the symbols meant that the array notation could only represent constants, as allowing general expressions would lead to ambiguity. He also mentioned that doubled symbols or [[Unicode]] brackets could be used instead.<ref>[[Phil Last|Last, Phil]]. [https://dyalog.tv/Dyalog15/?v=9-HAvTMhYao APL Array Notation] ([https://www.dyalog.com/uploads/conference/dyalog15/presentations/U07_APL_Array_Notation.pdf transcript]). [[Dyalog '15]].</ref>


After the presentation, Phil Last had a conversation with [[Adám Brudzewsky]] who had recently joined [[Dyalog Ltd.]], the [[language developer|language developer]] of [[Dyalog APL]], and who was inspired to begin an internal Dyalog research project on the matter. Meanwhile, Acre Desktop, a project manager that Last co-develops, moved from storing APL items in [[component file]]s to storing them in text files, necessitating a literal notation for arrays, and his notation for arrays was adopted. Acre stores unscripted namespaces as directories, so the need for a literal namespace notation only arises when a namespace is an element in a larger array, something that is quite unlikely for application constants.
After the presentation, Phil Last had a conversation with [[Adám Brudzewsky]] who had recently joined [[Dyalog Ltd.]], the [[language developer|language developer]] of [[Dyalog APL]], and who was inspired to begin an internal Dyalog research project on the matter. Meanwhile, Acre Desktop, a project manager that Last co-develops, moved from storing APL items in [[component file]]s to storing them in text files, necessitating a literal notation for arrays, and his notation for arrays was adopted. Acre stores unscripted namespaces as directories, so the need for a literal namespace notation only arises when a namespace is an element in a larger array, something that is quite unlikely for application constants.


=== 2016 ===
=== 2016 ===
Phil Last published a more formal proposal in the [[Vector Journal]]. Again, the notation was only described as a serialisation format; not as an integral part of the language. He added escape sequences to [[string]]s, further distancing the notation from compatibility with existing APL code.<ref>Last, Phil. [http://archive.vector.org.uk/art10501450 A Notation for APL array Embedding and Serialization]. Vector Journal, Volume 26, number 4. [[British APL Association]]. 2016.</ref>
Phil Last published a more formal proposal in the [[Vector Journal]] where he emphasised the need for such a notation to become an integral part of the language. He added escape sequences to [[string]]s, further distancing the notation from compatibility with existing APL code.<ref>Last, Phil. [http://archive.vector.org.uk/art10501450 A Notation for APL array Embedding and Serialization]. Vector Journal, Volume 26, number 4. [[British APL Association]]. 2016.</ref>


[[File:D11 Literal Notation for Arrays and Namespaces - Summary of notations.png|thumb|right|Array notation at [[Dyalog '17]].]]
[[File:D11 Literal Notation for Arrays and Namespaces - Summary of notations.png|thumb|right|Array notation at [[Dyalog '17]].]]
===2017===
===2017===
At [[Dyalog '17]], Adám Brudzewsky proposed an alternative notation using round parentheses to indicate collections of major cells of any rank, thus allowing the notation to express [[nested]] vectors though [[scalar]] major cells, for example <source lang=apl inline>(⊂1 2 3 ⋄ ⊂4 5 6)</source> would be equivalent to <source lang=apl inline>(1 2 3)(4 5 6)</source>. This notation had a striking similarity to the informal notation used in the [[NARS]] reference manual over 35 years prior. For namespace, he proposed using colon (<source lang=apl inline>:</source>) to delimit [[wikipedia:name-value pair|name-value pair]]s, inspired by [[wikipedia:JSON|JSON]] in which colon is used in the same manner, despite assignment being denoted by <source lang=javascript inline>=</source> in [[wikipedia:JavaScript|JavaScript]], from which JSON was derived. This distinction allowed arbitrary expressions in arrays, opening the possibility of full integration into the language, while also allowing a namespace with no members to be denoted <source lang=apl inline>()</source>. Last's proposal required <source lang=apl inline>[:]</source> to distinguish it from [[bracket indexing]] into a vector while eliding the indices, a technique used to address all [[element]]s.
At [[Dyalog '17]], Adám Brudzewsky proposed an alternative notation using round parentheses to indicate collections of major cells of any rank, thus allowing the notation to express [[nested]] vectors though [[scalar]] major cells, for example <syntaxhighlight lang=apl inline>(⊂1 2 3 ⋄ ⊂4 5 6)</syntaxhighlight> would be equivalent to <syntaxhighlight lang=apl inline>(1 2 3)(4 5 6)</syntaxhighlight>. This notation had a striking similarity to the informal notation used in the [[NARS]] reference manual over 35 years prior. For namespace, he proposed using colon (<syntaxhighlight lang=apl inline>:</syntaxhighlight>) to delimit [[wikipedia:name-value pair|name-value pair]]s, inspired by [[wikipedia:JSON|JSON]] in which colon is used in the same manner, despite assignment being denoted by <syntaxhighlight lang=javascript inline>=</syntaxhighlight> in [[wikipedia:JavaScript|JavaScript]], from which JSON was derived. This distinction allowed arbitrary expressions in arrays, opening the possibility of full integration into the language, while also allowing a namespace with no members to be denoted <syntaxhighlight lang=apl inline>()</syntaxhighlight>. Last's proposal required <syntaxhighlight lang=apl inline>[:]</syntaxhighlight> to distinguish it from [[bracket indexing]] into a vector while eliding the indices, a technique used to address all [[element]]s.


In addition to the main array notation, Brudzewsky also proposed allowing line breaks between quotes in [[string]]s to represent a vector of character vectors (with leading and trailing spaces trimmed).<ref>[[Adám Brudzewsky|Brudzewsky, Adám]]. [https://dyalog.tv/Dyalog17/?v=CRQNzL8cUQE Literal Notation for Arrays and Namespaces]. [[Dyalog '17]]</ref> While not included in the live presentation, Brudzewsky's slide deck included a discussion of whether expressions resulting in a scalar should be treated as [[singleton]] vectors or not. It concluded that if they were treated as [[vector]]s, then an alternative notation in the form of a [[wikipedia:line continuation|line continuation]] character would be necessary to allow writing large vectors over multiple lines of code.<ref>Brudzewsky, Adám [https://www.dyalog.com/uploads/conference/dyalog17/presentations/D11_Literal_Notation_for_Arrays_and_Namespaces.pdf Literal Notation for Arrays and Namespaces] (slides). [[Dyalog '17]]</ref>
In addition to the main array notation, Brudzewsky also proposed allowing line breaks between quotes in [[string]]s to represent a vector of character vectors (with leading and trailing spaces trimmed).<ref>[[Adám Brudzewsky|Brudzewsky, Adám]]. [https://dyalog.tv/Dyalog17/?v=CRQNzL8cUQE Literal Notation for Arrays and Namespaces]. [[Dyalog '17]]</ref> While not included in the live presentation, Brudzewsky's slide deck included a discussion of whether expressions resulting in a scalar should be treated as [[singleton]] vectors or not. It concluded that if they were treated as [[vector]]s, then an alternative notation in the form of a [[wikipedia:line continuation|line continuation]] character would be necessary to allow writing large vectors over multiple lines of code.<ref>Brudzewsky, Adám [https://www.dyalog.com/uploads/conference/dyalog17/presentations/D11_Literal_Notation_for_Arrays_and_Namespaces.pdf Literal Notation for Arrays and Namespaces] (slides). [[Dyalog '17]]</ref>
Line 69: Line 120:
At [[Dyalog '18]], Adám Brudzewsky returned with a solution to the issue on whether scalars should be regarded as 1-element vectors (thus increasing the rank of the containing array) or left as scalars (thus forming a vector). He reintroduced square brackets as collections of major cells of rank 1 or higher, repurposing round parentheses as vectors.
At [[Dyalog '18]], Adám Brudzewsky returned with a solution to the issue on whether scalars should be regarded as 1-element vectors (thus increasing the rank of the containing array) or left as scalars (thus forming a vector). He reintroduced square brackets as collections of major cells of rank 1 or higher, repurposing round parentheses as vectors.


The namespace notation remained as before, using round parentheses so the empty namespace could be written in a consistent manner, but he presented formalised scoping rules for the value expressions, namely that these would run in the surrounding namespace, but within their own scope, so any assignment done during such an expression. For example <source lang=apl inline>(a:b,b←1 2)</source> would neither populate the new namespace with a member <source lang=apl inline>b</source>, nor create such a variable in the global scope.<ref>Brudzewsky, Adám.  [https://dyalog.tv/Dyalog18/?v=GAdQuOtPcfM Array Notation Mk III]. [[Dyalog '18]].</ref> Acre quickly adopted this notation.
The namespace notation remained as before, using round parentheses so the empty namespace could be written in a consistent manner, but he presented formalised scoping rules for the value expressions, namely that these would run in the surrounding namespace, but within their own scope, so any assignment done during such an expression. For example <syntaxhighlight lang=apl inline>(a:b,b←1 2)</syntaxhighlight> would neither populate the new namespace with a member <syntaxhighlight lang=apl inline>b</syntaxhighlight>, nor create such a variable in the global scope.<ref>Brudzewsky, Adám.  [https://dyalog.tv/Dyalog18/?v=GAdQuOtPcfM Array Notation Mk III]. [[Dyalog '18]].</ref> Acre quickly adopted this notation.


[[File:D09 Array Notation RC1 - Questions.png|thumb|right|Array notation at [[Dyalog '20]]]]
[[File:D09 Array Notation RC1 - Questions.png|thumb|right|Array notation at [[Dyalog '20]]]]
===2020===
===2020===
In the spring of 2020, [[dzaima/APL]] adopted the proposed array notation with the exception of forcing the result of statements in square brackets to rank 1 or higher.<ref>Stack Exchange user [https://codegolf.stackexchange.com/users/59183/dzaima dzaima]. [https://github.com/dzaima/APL dzaima/APL]. Git commit "[https://github.com/dzaima/APL/commit/dfebe5de3699b2e3f838a60f72c6b9a9f66317e7 <source lang=apl inline>[1 2⋄3 4]</source>,  <source lang=apl inline>⎕AV</source>,]". GitHub.</ref>
In the spring of 2020, [[dzaima/APL]] adopted the proposed array notation with the exception of forcing the result of statements in square brackets to rank 1 or higher.<ref>Stack Exchange user [https://codegolf.stackexchange.com/users/59183/dzaima dzaima]. [https://github.com/dzaima/APL dzaima/APL]. Git commit "[https://github.com/dzaima/APL/commit/dfebe5de3699b2e3f838a60f72c6b9a9f66317e7 <syntaxhighlight lang=apl inline>[1 2⋄3 4]</syntaxhighlight>,  <syntaxhighlight lang=apl inline>⎕AV</syntaxhighlight>,]". GitHub.</ref>


At [[Dyalog '20]], Adám Brudzewsky presented the notation as ''Release Candidate 1'' and showed how [[Dyalog APL 18.0]]'s updated version of [https://github.com/Dyalog/link/wiki Link] (a simple interface for using source code in text files, synchronising the file system and the [[workspace]]) includes experimental support the array notation, including a facility to use multi-line array notation inside functions. He estimated that Dyalog APL 20.0 would include native interpreter support for the notation in 2022.
At [[Dyalog '20]], Adám Brudzewsky presented the notation as ''Release Candidate 1'' and showed how [[Dyalog APL 18.0]]'s updated version of [https://github.com/Dyalog/link/wiki Link] (a simple interface for using source code in text files, synchronising the file system and the [[workspace]]) includes experimental support the array notation, including a facility to use multi-line array notation inside functions. He estimated that Dyalog APL 20.0 would include native interpreter support for the notation in 2022.
Line 79: Line 130:
[[APL Germany]]'s 2020 journal also included a description of the notation, including a discussion of potential issues with [[assignment]].<ref>Brudzewsky, Adám. [https://apl-germany.de/wp-content/uploads/2021/11/APL_Journal_2020_1u2.pdf#page=34 A Notation for APL Arrays]. APL-Journal, Volume 2020, number 1-2. [[APL Germany|APL-Germany e.V.]] 2020.</ref>
[[APL Germany]]'s 2020 journal also included a description of the notation, including a discussion of potential issues with [[assignment]].<ref>Brudzewsky, Adám. [https://apl-germany.de/wp-content/uploads/2021/11/APL_Journal_2020_1u2.pdf#page=34 A Notation for APL Arrays]. APL-Journal, Volume 2020, number 1-2. [[APL Germany|APL-Germany e.V.]] 2020.</ref>


== Design considerations ==
===2021===
 
At [[Dyalog '21]], [[Morten Kromberg]] implied that comunity feedback would have been solicited, and implementation would begin in time for [[Dyalog APL 19.0]]. However, this proved a bit optimistic.<ref>Kromberg, Morten. [https://www.youtube.com/watch?2dQr58vcUjM&t=1688s The Road Ahead].  [[Dyalog '21]]. October 10, 2022.</ref>
In creating the notation's specification, various alternatives were considered. The following requirements were proposed:<ref>[[Adám Brudzewsky]]. Internal documents. [[Dyalog Ltd.]] 30 Jun 2017.</ref>
 
# No new [[glyph]]s
# Reusing existing glyphs for similar purposes
# Similarity to other languages ([[K]], [[wikipedia:JSON|JSON]], [[wikipedia:CSS|CSS]])
# Visual attractiveness
# Intuitive syntax
# As little [[wikipedia:syntactic sugar|syntactic sugar]] as possible
 
=== Glyphs ===
 
The design requirement for no new glyphs was contentious, and both [[bi-glyph]] and non-ASCII brackets were considered. Bi-glyphs were rejected out of readability concerns, especially when nested. For example, <source lang=apl inline>1 1 3⍴2</source> could have been written as <source lang=apl inline>[[[[2 2 2]]]]</source>. Non-ASCII brackets were rejected for font and keyboarding reasons, as well as to make it easier for non-APL systems to generate APL data. For example, <source lang=apl inline>⟦</source>…<source lang=apl inline>⟧</source> was proposed to denote a collection of [[major cells]], forming a new array of rank one-higher than the rank of the highest-[[rank]] constituent [[cell]]. However, few [[fonts]] support these glyphs.
 
The eventual choice was to go with existing symbols, and this had important implications for the specifics of the notation. While ideally, a notation would have been introduced for a collection of major cells, thereby handling both vectors and higher-rank arrays, a problem presents itself with [[axis|axes]] of length 1, because both square brackets and round parentheses already have meaning with when surrounding a single statement (namely [[function axis]]/[[bracket indexing]] and [[precedence]]/[[function train]]s). Thus, while <source lang=apl inline>2 ⟦3⟧</source> could have denoted the [[nested array]] <source lang=apl inline>2 (1⍴3)</source>, this isn't viable with <source lang=apl inline>2 [1⍴3]</source> because this already denotes indexing <source lang=apl inline>2</source> using the indices <source lang=apl inline>1⍴3</source>. To disambiguate, at least one statement separator or line break must be present in each level of array notation brackets and parentheses.  
 
=== Disambiguating square brackets ===
The overloading of square brackets, currently in use only for [[function axis]] and [[bracket indexing]], to mean a higher-rank array, poses a problem of disambiguation in the case where there is only one major cell. For example <source lang=apl inline>'abc'[3 3]</source> could be equivalent to <source lang=apl inline>'cc'</source> or <source lang=apl inline>'abc'(1 2⍴3)</source> depending on whether the brackets are interpreted as indexing or an array. Two proposals have been made, and it is possible to support either or both:
# Square brackets are interpreted as representing an array if no other interpretation is possible, e.g. immediately following an opening round parenthesis, curly brace, or square bracket, or beginning a statement.
# Square brackets are interpreted as representing an array if they are "broken", i.e. contain a diamond or newline that isn't enclosed in another round parenthesis, curly brace, or square bracket.
The design used in this article, which corresponds to the design proposed by [[Dyalog Ltd]], uses only the first option.
=== Minimum rank of major cells ===
 
While <source lang=apl inline>⟦⟦3⟧⟧</source> could denote <source lang=apl inline>1 1⍴3</source> using non-ASCII glyphs, an equivalent ASCII scheme instead would have required <source lang=apl inline>[[3⋄]⋄]</source> where the inner bracket creates a vector, and the outer creates a [[matrix]]. Using line breaks instead of diamonds, it was found to be counter-intuitive that <source lang=apl>[
3
  5
  ]</source> was to denote two-[[element]] vector while <source lang=apl>[
3 4
5 6
    ]</source> would be a two-row matrix. Therefore, a special rule was added to the effect that in such collections of major cells, every cell would be considered to have a rank of at least 1, even if it was a [[scalar]].
 
In turn, this choice introduced the need for a separate notation to allow vectors to be written over multiple lines, and therefore the round parentheses was extended from its traditional use in [[strand notation]] to also denote a collection of [[enclose]]d elements.
 
=== Name-value pairs ===
 
As a notation for [[namespace]]s, several details were debated:
 
# Whether to use <source lang=apl inline>⋄</source> or <source lang=apl inline>;</source> to separate [[wikipedia:name-value pair|name-value pair]]s (in addition to line breaks)
# Which enclosure glyphs to use, <source lang=apl inline>(</source>…<source lang=apl inline>)</source> or <source lang=apl inline>[</source>…<source lang=apl inline>]</source>
# Which glyph should separate the name from the value, <source lang=apl inline>:</source> or <source lang=apl inline>←</source>
# In which scope the value expressions should be evaluated


The <source lang=apl inline>⋄</source> was chosen to separate name-value pairs, as it is generally exchangeable with a line break, while <source lang=apl inline>;</source> though it is used to separate names ― without values ― in [[Defined_function_(traditional)#Semi-colons|headers]] and in [[locals lines]]. Furthermore, it was seen as natural the values would be computed in reading order (left-to-right) just like multiple statements are, and while <source lang=apl inline>⋄</source> would imply this, <source lang=apl inline>;</source> wouldn't. Indeed, in the statement <source lang=apl inline>A[B;C]</source>, expression <source lang=apl inline>C</source> is evaluated before expression <source lang=apl inline>B</source>. It was briefly considered to have values computed from the right, just line stranding is, but this was rejected because replacing the semi-colons with line breaks would then require evaluation beginning with the last line and working upwards!
[[File:D02 The Road Ahead - Literal Array Notation.png|thumb|right|Array notation at [[Dyalog '22]]]]
===2022===
At [[Dyalog '22]], Morten Kromberg announced that Dyalog Ltd was close to having the notation working.<ref>Kromberg, Morten. [https://www.youtube.com/watch?C6E3mSYSGJ&t=1144s The Road Ahead]. [[Dyalog '22]]. October 10, 2022.</ref>


Round parentheses were chosen because namespaces are seen as (unordered) lists, and so are more similar to vectors than higher-rank arrays. Furthermore, <source lang=apl inline>[]</source> already had meaning (indexing all elements of a vector) while <source lang=apl inline>()</source> didn't have any existing use, and so could be used to denote a new empty namespace, equivalent to <source lang=apl inline>⎕NS 0⍴⊂''</source>.
===2023===
On April 21, 2023, Dyalog Ltd published a blog post by Morten Kromberg announcing to the [[community]] the formal proposal for an APL array notation.<ref name=formprop>Kromberg, Morten. [https://www.dyalog.com/blog/2023/04/formal-proposal-for-apl-array-notation-seeking-feedback/ Formal Proposal for APL Array Notation – Seeking Feedback]. Formal Proposal for APL Array Notation – Seeking Feedback. April 21, 2023.</ref>


While initially, <source lang=apl inline>←</source> was seen as the obvious choice to separate the name and the value, it was soon discovered that a namespace with only one member would be indistinguishable from a parenthesised [[assignment]]. Furthermore, it was noted that value expressions could contain intermediary assignments, and that such assignments were of a fundamentally different nature from the name-value declaration. The intermediary assignments would happen in a temporary scope, with any created variables disappearing once the namespace member value was established.
On May 5, 2023, the specification for scoping in namespaces was changed due to feedback from Dyalog Ltd employee Peter Mikkelsen. Assignments inside value expressions would now affect the surrounding scope rather than having [[dfn]]-like auto-localisation, which can instead be achieved by wrapping the expression in an anonymous dfn.  


Value expressions could be evaluated in the newly established namespace (similar to expressions in <source lang=apl inline>:Namespace</source> scripts), or in the surrounding scope (similar to inline expressions in [[wikipedia:JavaScript|JavaScript]]'s object notation). It was envisioned that a main usage of the literal notation would be to collect existing values into a namespace, and evaluating inside the new namespace would force the use of <source lang=apl inline>##.</source> to fetch values in the surrounding scope. In a departure from JavaScript, it was found most natural that such intermediate assignments be local to the value expression, similar to assignments in dfns. Global assignment is still available using <source lang=apl inline>⎕THIS.name←value</source>, just as in dfns.
{{Template:Comparison of array notations}}


== References ==
== References ==
<references/>
<references/>
{{APL syntax}}[[Category:APL syntax]][[Category:Nested array model]]
{{APL syntax}}[[Category:APL syntax]][[Category:Nested array model]]

Latest revision as of 12:26, 5 May 2023

This article details the design considerations for array notation in APL. Feedback may be given via the Discussion page or any other array language chat room or forum, for example under the Array Notation Discussion topic on the Dyalog Forums. This design considerations page, and if necessary the specification, will be kept up to date as feedback is received.

Objectives

The following requirements were proposed as objectives for an APL array notation:[1]

  1. No new glyphs
  2. Reusing existing glyphs for similar purposes
  3. Similarity to other languages (K, JSON, CSS)
  4. Visual attractiveness
  5. Intuitive syntax
  6. As little syntactic sugar as possible

Specific considerations

Various alternatives have been considered and the following details each design decision.

Glyphs

The design requirement for no new glyphs was contentious, and both bi-glyph and non-ASCII brackets were considered. Bi-glyphs were rejected out of readability concerns, especially when nested. For example, 1 1 3⍴2 could have been written as [[[[2 2 2]]]]. Non-ASCII brackets were rejected for font and keyboarding reasons, as well as to make it easier for non-APL systems to generate APL data. For example, was proposed to denote a collection of major cells, forming a new array of rank one-higher than the rank of the highest-rank constituent cell. However, few fonts support these glyphs.

The eventual choice was to go with existing symbols, and this had important implications for the specifics of the notation. While ideally, a notation would have been introduced for a collection of major cells, thereby handling both vectors and higher-rank arrays, a problem presents itself with axes of length 1, because both square brackets and round parentheses already have meaning with when surrounding a single statement (namely function axis/bracket indexing and precedence/function trains). Thus, while 2 ⟦3⟧ could have denoted the nested array 2 (1⍴3), this isn't viable with 2 [1⍴3] because this already denotes indexing 2 using the indices 1⍴3. To disambiguate, at least one statement separator or line break must be present in each level of array notation brackets and parentheses.

Disambiguating square brackets

The overloading of square brackets, currently in use only for function axis and bracket indexing, to mean a higher-rank array, poses a problem of disambiguation in the case where there is only one major cell. For example 'abc'[3 3] could be equivalent to 'cc' or 'abc'(1 2⍴3) depending on whether the brackets are interpreted as indexing or an array. Two proposals have been made, and it is possible to support either or both:

  1. Square brackets are interpreted as representing an array if no other interpretation is possible, e.g. immediately following an opening round parenthesis, curly brace, or square bracket, or beginning a statement.
  2. Square brackets are interpreted as representing an array if they are "broken", i.e. contain a diamond or newline that isn't enclosed in another round parenthesis, curly brace, or square bracket.

Option 1 depends on an outer context of the notation, while option 2 depends on the inner content of the notation. The latter has similarity to the manner in which a dfn is determined to be a function, a monadic operator, or a dyadic operator: If the curly braces contain ⍵⍵ then the dfn is a dyadic operator; otherwise, a ⍺⍺ indicates a monadic operator; and any other dfn is a function.

Minimum rank of major cells

While ⟦⟦3⟧⟧ could denote 1 1⍴3 using non-ASCII glyphs, an equivalent ASCII scheme instead would have required [[3⋄]⋄] where the inner bracket creates a vector, and the outer creates a matrix. Using line breaks instead of diamonds, it was found to be counter-intuitive that

[
 3
 5
  ]

was to denote two-element vector while

[
 3 4
 5 6
    ]

would be a two-row matrix. This is indeed the case in dzaima/APL, as opposed to in Dyalog APL, where a special rule was added to the effect that in such collections of major cells, every cell will be considered to have a rank of at least 1, even if it is a scalar. However, this choice introduced the need for a separate notation to allow vectors to be written over multiple lines, and therefore the round parentheses were extended from their traditional use in strand notation to also denote collections of enclosed elements.

Name-value pairs

As a notation for namespaces, several details were debated, as detailed below.

Separators between name-value pairs

Should or ; be used to separate name-value pairs (in addition to line breaks)?

The was chosen to separate name-value pairs, as it is generally exchangeable with a line break, while ; though it is used to separate names ― without values ― in headers and in locals lines. Furthermore, it was seen as natural the values would be computed in reading order (left-to-right) just like multiple statements are, and while would imply this, ; wouldn't. Indeed, in the statement A[B;C], expression C is evaluated before expression B. It was briefly considered to have values computed from the right, just line stranding is, but this was rejected because replacing the semi-colons with line breaks would then require evaluation beginning with the last line and working upwards!

Namespace delimiters

Should round parentheses (()) or square brackets ([]) be used to enclose namespaces?

Round parentheses were chosen because namespaces are seen as (unordered) lists, and so are more similar to vectors than higher-rank arrays. Furthermore, [] already had meaning (indexing all elements of a vector) while () didn't have any existing use, and so could be used to denote a new empty namespace, equivalent to ⎕NS 0⍴⊂''.

Separator between name and value

Should : or separate the name from the value?

While initially, was seen as the obvious choice to separate the name and the value, it was soon discovered that a namespace with only one member would be indistinguishable from a parenthesised assignment. Furthermore, it was noted that value expressions could contain intermediary assignments, and that such assignments were of a fundamentally different nature from the name-value declaration. The intermediary assignments would happen in a temporary scope, with any created variables disappearing once the namespace member value was established.

Scoping

In which scope the value expressions should be evaluated?

Value expressions could be evaluated in the newly established namespace (similar to expressions in :Namespace scripts), or in the surrounding scope (similar to inline expressions in JavaScript's object notation). It was envisioned that a main usage of the literal notation would be to collect existing values into a namespace, and evaluating inside the new namespace would force the use of ##. to fetch values in the surrounding scope. In a departure from JavaScript, it was found most natural that such intermediate assignments be local to the value expression, similar to assignments in dfns. Global assignment is still available using ⎕THIS.name←value, just as in dfns.

After publication of the formal proposal,[2] Peter Mikkelsen, a then recently hired Dyalog Ltd employee[3], pointed out an inconsistency between value expressions in namespace and vector notation:

g←1 ⋄ (a:g←2 ⋄ b:g) would make (a:2 ⋄ b:1) but g remains 1

while

g←1 ⋄ (g←2 ⋄ g) would make (2 ⋄ 2) updating g to be 2.

Because of this, the specification was changed on May 5, 2023 to follow JavaScript; that assignments inside value expressions then affect the surrounding scope. Auto-localisation of temporary variables used in building the value can then be achieved by wrapping the expression in an anonymous dfn.

Timeline

1996

The publication of John Scholes' Dynamic Functions in Dyalog APL [4] showed that a number of expressions could be grouped together within paired delimiters and separated by line-ends. This hinted at the possibility of doing a similar thing between brackets and parentheses to solve a problem for which Phil Last had been seeking a solution for a decade.

2010

At the 2010 APL Conference in Berlin Dyalog introduced experimental interpreter APL#. This included a notation for namespaces as name-value pairs between paired double brackets with major and minor separators being line-end and assignment arrow: [[name←value ⋄ ...]]; and a sort of extended, multiple expression separated by line-ends and between paired parentheses.

2013

Phil Last sent a proposal to Dyalog outlining two possible executable notations for creating multi-dimensional arrays without function application. One using potential new system construct :Array and :Cell to be used in tradfns and another using line-ends between balanced brackets to define arrays of rank-2 or greater in both dfns and tradfns.

It became RFE 9458: Large and higher rank literal values. See File:Embedding data.pdf

Description: Proposal for a mechanism to specify large and higher rank literal values directly in code.

After which in the following year ...

2014

At Dyalog '14, Morten Kromberg said:

The emphasis on using scripts to store source code means that it's probably time for us to come up with a notation for constants in the language so that in your script you can declare matrices and so on in a nice readable fashion.

Although no concrete proposal was made at the time, he set the expectation of this being the subject of a presentation the following year.[5]

2015

At Dyalog '15, Phil Last explained that he considered the lack of such a notation a big hole in APL notation and gave a suggestions for such a notation. He presented a model using square brackets to indicate collections of major cells of rank 1 or higher, delimited by line breaks and/or diamonds, for example [1 2 3 ⋄ 4 5 6] would be equivalent to 2 3⍴1 2 3 4 5 6. He also proposed that if the delimited expressions were assignments, then the notation would instead declare members of an anonymous namespace, for example for example [a←3 ⋄ b←6]. He pointed out that this overloading of the symbols meant that the array notation could only represent constants, as allowing general expressions would lead to ambiguity. He also mentioned that doubled symbols or Unicode brackets could be used instead.[6]

After the presentation, Phil Last had a conversation with Adám Brudzewsky who had recently joined Dyalog Ltd., the language developer of Dyalog APL, and who was inspired to begin an internal Dyalog research project on the matter. Meanwhile, Acre Desktop, a project manager that Last co-develops, moved from storing APL items in component files to storing them in text files, necessitating a literal notation for arrays, and his notation for arrays was adopted. Acre stores unscripted namespaces as directories, so the need for a literal namespace notation only arises when a namespace is an element in a larger array, something that is quite unlikely for application constants.

2016

Phil Last published a more formal proposal in the Vector Journal where he emphasised the need for such a notation to become an integral part of the language. He added escape sequences to strings, further distancing the notation from compatibility with existing APL code.[7]

Array notation at Dyalog '17.

2017

At Dyalog '17, Adám Brudzewsky proposed an alternative notation using round parentheses to indicate collections of major cells of any rank, thus allowing the notation to express nested vectors though scalar major cells, for example (⊂1 2 3 ⋄ ⊂4 5 6) would be equivalent to (1 2 3)(4 5 6). This notation had a striking similarity to the informal notation used in the NARS reference manual over 35 years prior. For namespace, he proposed using colon (:) to delimit name-value pairs, inspired by JSON in which colon is used in the same manner, despite assignment being denoted by = in JavaScript, from which JSON was derived. This distinction allowed arbitrary expressions in arrays, opening the possibility of full integration into the language, while also allowing a namespace with no members to be denoted (). Last's proposal required [:] to distinguish it from bracket indexing into a vector while eliding the indices, a technique used to address all elements.

In addition to the main array notation, Brudzewsky also proposed allowing line breaks between quotes in strings to represent a vector of character vectors (with leading and trailing spaces trimmed).[8] While not included in the live presentation, Brudzewsky's slide deck included a discussion of whether expressions resulting in a scalar should be treated as singleton vectors or not. It concluded that if they were treated as vectors, then an alternative notation in the form of a line continuation character would be necessary to allow writing large vectors over multiple lines of code.[9]

Array notation at Dyalog '18.

2018

At Dyalog '18, Adám Brudzewsky returned with a solution to the issue on whether scalars should be regarded as 1-element vectors (thus increasing the rank of the containing array) or left as scalars (thus forming a vector). He reintroduced square brackets as collections of major cells of rank 1 or higher, repurposing round parentheses as vectors.

The namespace notation remained as before, using round parentheses so the empty namespace could be written in a consistent manner, but he presented formalised scoping rules for the value expressions, namely that these would run in the surrounding namespace, but within their own scope, so any assignment done during such an expression. For example (a:b,b←1 2) would neither populate the new namespace with a member b, nor create such a variable in the global scope.[10] Acre quickly adopted this notation.

Array notation at Dyalog '20

2020

In the spring of 2020, dzaima/APL adopted the proposed array notation with the exception of forcing the result of statements in square brackets to rank 1 or higher.[11]

At Dyalog '20, Adám Brudzewsky presented the notation as Release Candidate 1 and showed how Dyalog APL 18.0's updated version of Link (a simple interface for using source code in text files, synchronising the file system and the workspace) includes experimental support the array notation, including a facility to use multi-line array notation inside functions. He estimated that Dyalog APL 20.0 would include native interpreter support for the notation in 2022.

APL Germany's 2020 journal also included a description of the notation, including a discussion of potential issues with assignment.[12]

2021

At Dyalog '21, Morten Kromberg implied that comunity feedback would have been solicited, and implementation would begin in time for Dyalog APL 19.0. However, this proved a bit optimistic.[13]

Array notation at Dyalog '22

2022

At Dyalog '22, Morten Kromberg announced that Dyalog Ltd was close to having the notation working.[14]

2023

On April 21, 2023, Dyalog Ltd published a blog post by Morten Kromberg announcing to the community the formal proposal for an APL array notation.[2]

On May 5, 2023, the specification for scoping in namespaces was changed due to feedback from Dyalog Ltd employee Peter Mikkelsen. Assignments inside value expressions would now affect the surrounding scope rather than having dfn-like auto-localisation, which can instead be achieved by wrapping the expression in an anonymous dfn.

Comparison of array notations

The following systems support list or vector notation in some form, beyond simple strand notation. The separators ; in A+ and K, and in APL and BQN, indicate any separator, including a line break.

System Vectors High-rank Namespaces Function arrays Assignable
Nial [,] No N/A Special No
A+ (;) No N/A First-class Yes
K (;) N/A [key:val;] First-class Yes
BQN[15] ⟨⋄⟩ [⋄] {key⇐val⋄} First-class Yes
dzaima/APL (⋄) [⋄] (key:val⋄) Special No
Dyalog Link (⋄) [⋄] (key:val⋄) No No
Acre Desktop[16] (⋄) [⋄] [key←val⋄] No N/A
TinyAPL ⟨⋄⟩ [⋄] ⦃key←val⋄⦄ First-class Yes

Nial and A+ do not support namespaces, while K does not support high-rank arrays, so any such notation is not applicable. The "Function arrays" column indicates whether functions can be placed in array notation. "First class" indicates that functions are first class, so this is possible without special consideration. "Special" indicates creating a special vectors of functions that can be applied to arguments to return a list of results. The "Assignable" column indicates that array notation can be used as an assignment target to perform destructuring. BQN's namespaces don't use a dedicated construction; instead, any block (like a dfn) with statements returns a namespace reference. Acre Desktop only uses array notation for storing literal arrays; it cannot appear in executable code.

References

  1. Adám Brudzewsky. Internal documents. Dyalog Ltd. 30 Jun 2017.
  2. 2.0 2.1 Kromberg, Morten. Formal Proposal for APL Array Notation – Seeking Feedback. Formal Proposal for APL Array Notation – Seeking Feedback. April 21, 2023.
  3. Dyalog Ltd. Meet Teem Dyalog: Peter. Retrieved May 2nd, 2023.
  4. Scholes, John M. https://www.dyalog.com/uploads/documents/Papers/dfns.pdf Dynamic Functions in Dyalog APL]
  5. Kromberg, Morten. Technical Road Map. Dyalog '14.
  6. Last, Phil. APL Array Notation (transcript). Dyalog '15.
  7. Last, Phil. A Notation for APL array Embedding and Serialization. Vector Journal, Volume 26, number 4. British APL Association. 2016.
  8. Brudzewsky, Adám. Literal Notation for Arrays and Namespaces. Dyalog '17
  9. Brudzewsky, Adám Literal Notation for Arrays and Namespaces (slides). Dyalog '17
  10. Brudzewsky, Adám. Array Notation Mk III. Dyalog '18.
  11. Stack Exchange user dzaima. dzaima/APL. Git commit "[1 2⋄3 4], ⎕AV,". GitHub.
  12. Brudzewsky, Adám. A Notation for APL Arrays. APL-Journal, Volume 2020, number 1-2. APL-Germany e.V. 2020.
  13. Kromberg, Morten. The Road Ahead. Dyalog '21. October 10, 2022.
  14. Kromberg, Morten. The Road Ahead. Dyalog '22. October 10, 2022.
  15. Lochbaum, Marshall. BQN: Array notation and display; Array literals. Retrieved 2022-09-01.
  16. The Carlisle Group. APL Array Notation. Acre Desktop Wiki. GitHub. Retrieved 2022-09-01.
APL syntax [edit]
General Comparison with traditional mathematicsPrecedenceTacit programming (Train, Hook, Split composition)
Array Numeric literalStringStrand notationObject literalArray notation (design considerations)
Function ArgumentFunction valenceDerived functionDerived operatorNiladic functionMonadic functionDyadic functionAmbivalent functionDefined function (traditional)DfnFunction train
Operator OperandOperator valenceTradopDopDerived operator
Assignment MultipleIndexedSelectiveModified
Other Function axisBracket indexingBranchStatement separatorQuad nameSystem commandUser commandKeywordDot notationFunction-operator overloadingControl structureComment