J语言

J语言，是一种阵列编程语言，由肯尼斯·艾佛森許國華英语Roger Hui於1990年代初發明。J语言是APL語言的一种方言[7][8]，延续了APL鲜明的簡潔性，它在數學统计学程式設計上十分高效，特別是在需要进行矩陣运算的场合。

编程范型 阵列、隐式、反射式、函数式 APL Kenneth E. Iverson、許國華（英语：Roger Hui） JSoftware 1990年，​33年前[1] j902 (2020年12月9日)[2] 动态类型 跨平台: Windows, Linux, macOS GPLv3 www.jsoftware.com J SHARP APL Dyalog APL, NARS2000, I, BQN, SuperCollider[3], Octave[4], NumPy[5]

简介

Ken Iverson（右）和Roger Hui在1996年的照片[9]

J语言最初起步于Kenneth E. Iverson在1987年发表的《APL字典》[10]，它实现了其中至关重要的的概念[11]。J语言提供隐式定义机制包括、叉子（fork）[12]和多种[13]，特别是其中有等价于组合子逻辑S组合子的钩子（hook）[14]，并介入了作为头等对象动名词（gerund），用以建立控制结构[15]，它常被作为隱式編程的典范之一[16]

J语言的运算符，承袭APL传统，没有优先级并且最右先行，2 * 3 + 4按照2 * (3 + 4)来运算。以历史上APL使用的典型符号为例，符号/被用来指示折叠函数fold，所以+/1 2 3等价于1 + 2 + 3；在APL中，除法被表示为数学除号÷，它将减号和冒号一起重复打印英语overstrikeEBCDICASCII二者的纸质文本终端上；J语言使用%表示除法，是对除号的一种近似或提示。

J语言不再支持从1968年的APL\360就有的[;]形式的方括号索引，转而支持叫做“来自”（from）的索引机制[18]，它起源自Kenneth E. Iverson于1978年在《算子和函数》中提出的，依据基数解码定义[19]，并用符号⌷表示的索引[20]

J语言承袭IBM APL\360采用了平坦阵列模型[21]，不支持由NARS（嵌套阵列研究系统）于1981年介入[22]，并被IBM APL2所采纳的嵌套阵列模型[23]；J语言增加了Kenneth E. Iverson于1978年在《算子和函数》中提出的盒装数据类型[24]，它由SHARP APL于1981年介入，并于1983年在研究报告《理性化APL》中，列入与APL2相比较的“限定子集”（RS）而著重强调[25]

J语言支持AVX2指令集进行SIMD运算[26]。为了包装面向对象编程语言开发的API和框架，J语言提供了层级命名空间机制[27]，这里所有名字都存在于特定语境（locale）中[28]，可以避免软件包之间的名字冲突，并能有效的用作基于类面向对象编程框架[29]

J语言解释器默认装载标准[30]。通过包管理器[31]，可以安装各种插件[32]。J语言拥有常规调试机制，还有叫做Dissect的可视调试器[33]。除了科学计算和统计分析，它还被用于关系数据库管理系统如Jd[34]极限编程[35]网络性能分析[36]

2011年3月，J语言采用了GNU通用公共许可证版本3，从而成为自由和开源软件[37]，人们还可以在Jsoftware的商业许可证下利用源代码[38]

J术语 APL术语

起步示例

J语言可以写出非常精简的程序，特别是存在重度的对符号的函数重载，以至于一些编程者将它称为难以阅读的只写语言。在计算机的终端上执行ijconsole，即可进入J语言的REPL解释器界面。

Hello, World!

J语言的“Hello, World!”程序：

   'Hello, world!'
Hello, world!


#!/usr/bin/ijconsole
echo 'Hello, world!'
exit ''


$ijconsole test01.ijs Hello, world!$ chmod +x test01.ijs # 另一种执行方式，授予这个文件可执行权限
$./test01.ijs Hello, world!  平均 在J语言中函数一般称为动词，例如定义一个叫做avg的动词，计算一序列数的平均  avg=: +/ % # avg 1 2 3 4 2.5  一元动词#“计数”（tally），总计阵列中项目的总个数。动词+“加”（plus）和副词/“插入”（insert），派生出的动词+/，合计这个阵列的项目的总和。二元动词%“除”（divide）将这个总和除以这个总个数。而用户定义的动词avg，用到了由连串（strand）的三个动词（+/%#）构成的一个“叉子”（fork）。叉子(f g h) y(f y) g (h y)，这里的fgh指示动词，而y指示一个名词。 使用avg的一些例子：  ]a=: ?. 20$100  NB. 产生100以内20个随机整数的一个向量
94 56 8 6 85 48 66 96 76 59 33 72 63 1 89 52 17 20 9 65
avg a
50.75
4 avg\ a         NB. 周期大小为4的移动平均
41 38.75 36.75 51.25 73.75 71.5 74.25 66 60 56.75 42.25 56.25 51.25 39.75 44.5 24.5 27.75
10,11,12
13,14,15


数据类型

J语言支持三种简单类型：

• 数值
• 文字（字符）
• 盒装

数值

J语言的数值类型之一是“”。位有两个值：01。位还可以形成列表，例如1 0 1 0 1 1 0 0，是8个位的列表。在语法上，J分析器将位当作一个字。空格字符被识别为字形成字符，它处在属于其他数值字的字符之间。

J语言支持任意长度的列表。J语言进一步的在这些位列表之上，支持所有常见二元运算，比如动词*.“与”（and）、+.“或”（or）、-.“非”（not）、|.“反转·旋转”（reverse·rotate）、|.!.f“移位”（shift）等。J语言还支持位的二维、三维等阵列。上面的运算同样运行在这些阵列之上。

   0j15 ": o. 1   NB. π在双精度浮点数下精确值的位数
3.141592653589793
<[email protected]o. 10x ^50  NB. π乘以扩展精度10的50次幂
314159265358979323846264338327950288419716939937510


文字

J语言还支持文字即字符类型。文字包围在撇号'之间，比如'a''b'。文字的列表，通过将多个字符用撇号包围起来的常规字符串约定来表示，比如'abcdefg'。在字符串内的''表示'字符本身。单个的文字，典型的是8宽即单字节ASCII字符，此外J语言还支持Unicode文字。

盒装

? 动词 掷骰（roll）· 发牌英语Random permutation（deal） 3 ? 10
1


定义

J语言支持用户进行显式定义[69]，和{{……}}形式的直接定义英语Direct function[70]。下面以五种复合作为显式定义的例子：

at=: conjunction define
u (v y)
:
u (x v y)
)
atop=: conjunction def '(u at v)"v'
beside=: conjunction define
u (v y)
:
x u (v y)
)
appose=: conjunction define
u (v y)
:
(v x) u (v y)
)
compose=: conjunction def '(u appose v)"(0{v b.0)'


   a=: ? @ $&1000 @: >: 4?10 b=: |: a p=: a (+/ . *) b matmul=: {{x u@:v"(1 _) y}} (a (+/ matmul *) b) -: p 1 inner=: {{x (u@:v"1)"(1 _) y}} (a (+/ inner * 0&|:) b) -: p 1 outer=: {{x u@(v/"_1~ |:)~"(2 _) y}} (a (+/ outer *) b) -: p 1 revmul=: {{x (i.<:#$y)&|:@(u@:v"(_ 1)~ |:)~"(2 _) y}}
(a (+/ revmul * 0&|:) b) -: p
1


APL传统上的将内积Pf.gQ解释为f/PgQ[52]，J语言的矩阵乘法要求写为Pf/ .gQ，不隐含的为左运算元f附加一元/。转置也是有较大的运算，不同的有不同的参照局部性

• matmul通过"(1 _)[email protected]:v的右参数从向量扩展为一般阵列，它用于右参数为阵列的情况。在向量与向量列表二者诸项之间逐对的进行乘积累加运算，是BLAS的标准算法[71]
• inner采用了两向量之间的点积运算[email protected]:v"1，它适宜直接用于右参数为阵列的情况。在右参数为行主序阵列之时，需要如例子代码这样，对右参数阵列进行二元转置0&|:，这里的0指示将第一轴安排至最后位置而其他轴保持原序前移。这种基于点积的实现，通常需要进一步加以。
• outer可以看作matmul的变体，它首先对左参数阵列进行转置，然后进行多组的向量与一般阵列之间二元的张量积运算v/"_1[50]，最后在各组结果的列表上进行u计算，每组运算之后参与其中的左右两阵列的元素不会被其他组的运算再次访问。
• revmulinner一样适宜直接用于右参数为列主序阵列的情况，但采用了同matmul类似的计算方法，它在乘法之前对左参数阵列和在乘法之后对结果要做转置，matmulrevmul的关系如同${\displaystyle (\mathrm {AB} )^{\mathsf {T}}=\mathrm {B} ^{\mathsf {T}}\mathrm {A} ^{\mathsf {T}}}$ matmul一次性访问左参数阵列，反复多次访问右参数阵列；revmul一次性访问右参数阵列，反复多次访问左参数阵列。

   i. 3 4
0 1  2  3
4 5  6  7
8 9 10 11
(<<1 2) { i. 3 4
4 5  6  7
8 9 10 11
(<1 2;0 2 3) { i. 3 4
4  6  7
8 10 11
(<a:;0 2 3) { i. 3 4
0  2  3
4  6  7
8 10 11
(<a:;0 2 3)
┌──────────┐
│┌──┬─────┐│
││┌┐│0 2 3││
│││││     ││
││└┘│     ││
│└──┴─────┘│
└──────────┘


   (<1 2) { i. 3 4
6
((<0 0),(<2 2),(<1 1)) { i. 3 4
0 10 5
(<0 0),(<2 2),(<1 1)
┌───┬───┬───┐
│0 0│2 2│1 1│
└───┴───┴───┘


重排轴

• 两次连续的二元转置，可以变换成等价形式：p|:q|:A(p{q)|:A，即先将后者置换向量p对前者置换向量q进行置换，然后用结果的置换向量做一次二元转置。
• 对二元转置后的阵列，进行原子项目的选取，可以变换成等价形式：(<k){p|:A(<(/:p){k){A，即先用置换向量p的逆置换向量/:p，对选取向量k进行置换，然后用结果的选取向量来选取未转置阵列。

   a=: ? @ $&1000 @: >: 4?10 n=: # @$ a
p=: ?~ n
q=: ?~ n
(/:/:p) -: p
1
((/:p) { p) -: i. n
1
(/: p{q) -: (/:q) { /:p
1
(p |: q|:a) -: (p{q) |: a
1
t=. <"1 @ (i[email protected](<./)@({. $) */ #&1@[) ({~ (+/x)&t) @ (|:~ x&s) y}}  这里局部定义了s，它的左右参数同于给diag的参数，它生成二元转置需要的置换向量，这是由要安排到前导位置上的那些轴的位置索引，和余下其他轴的位置索引串接而成。接着局部定义了t，它的左参数是给diag的布尔值列表中真值1的个数，右参数是要对其指定数目的前导轴进行对角线选取的阵列，它生成对角线选取所需要的一层盒装选取列表。最后的表达式先进行指定的二元转置，再对其结果进行相应的对角线选取。下面是简单用例：  >:i. 3 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 1 diag >:i. 3 5 1 7 13 i. 2 3 2 0 1 2 3 4 5 6 7 8 9 10 11 1 1 diag i. 2 3 2 0 1 8 9 0 2 1 |: i. 2 3 2 0 2 4 1 3 5 6 8 10 7 9 11 1 0 1 diag i. 2 3 2 0 2 4 7 9 11  快速排序 J语言提供的排序机制基于了稳定排序算法，下面的例子代码是快速排序的直接定义[80] cmp=: * @ - quicksort=: {{ if. 1 >: #y do. y else. s=. y u y {~?# y (u quicksort (s<0)#y),((s=0)#y),(u quicksort (s>0)#y) end. }}  这里定义一个动词cmp，它通过逐个做两个数的差并取其符号，得到取值为_101平衡三进制值。cmp将作为左运算元传递给副词quicksort quicksort的定义中，向局部变量s赋值的表达式，第一步随机选择支点（pivot）运算，首先计算?#y，生成在数据总个数范围内的随机数，接着在其上计算{~，选择出在随机数指定的位置上的支点值；它的第二步运算，将运算元u，应用到其左参数的数据列表，和右参数的支点值二者之上。 随后是串接分治运算结果，首先将平衡三进制值列表，分别与0做逐项的三分法比较，得到三个布尔值列表；然后以这种列表中的01作为件数，复制出数据列表的符合这个条件一个新的子列表，其中两个作为参数传递给递归调用进行排序。 下面的快速排序实现，展示了隐式编程，即将函数复合在一起，而不显式的引用任何变量，不提及要应用于其上的形式参数。这里将前面代码中向局部变量s赋值时所求值的表达式改为隐式定义，进而以作为钩子的第一步运算的方式，代入引用这个变量的表达式之中，并且采用钩子的参数复制机制消隐了形式参数y  cmp=: * @ - quicksort=: {{((($:@#~ <&0),(#~ =&0),($:@#~ >&0)) (u ({~ [email protected]#))) ^: (1<#)}} cmp quicksort 2 0 4 7 15 9 8 0 4 9 18 8 1 18 0 0 1 2 4 4 7 8 8 9 9 15 18 18  提供给连词^:的左侧运算元，外层是个一元钩子，它将提供给它的单一右数据参数，重复放置在它的左数据参数位置上。这个外层一元钩子的第一步运算，是生成平衡三进制值列表的嵌套的二层一元钩子(u ({~ [email protected]#))；而外层一元钩子的第二步运算，将生成的三个子列表串接起来。生成三个子列表的表达式，以数据列表是作为左参数，以平衡三进制值列表作为右参数；这里的三个二元钩子首先生成布尔值列表，接着进行对换了左右参数位置的二元复制运算，最后它们中有两个通过自引用$:进行了递归调用。

4 6 4


   perm1=: (,~ !) $,@(0&,[email protected]:+&1@p@-&1 {"(_ 1) \:"1@(=/~)@i.)$ perm1 4
24 4


(perm 4) -: p 4
1


t=. -r+s=. r+$y (1&,:|[email protected](>&1@#@$)n) u;._3 t&{.s&{. y}}


   4 4 $>: i. 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 < stencil 2 3 ] 4 4$ >: i. 9
┌─────┬─────┬─────┬─────┐
│0 1 2│1 2 3│2 3 4│3 4 0│
│0 5 6│5 6 7│6 7 8│7 8 0│
├─────┼─────┼─────┼─────┤
│0 5 6│5 6 7│6 7 8│7 8 0│
│0 9 1│9 1 2│1 2 3│2 3 0│
├─────┼─────┼─────┼─────┤
│0 9 1│9 1 2│1 2 3│2 3 0│
│0 4 5│4 5 6│5 6 7│6 7 0│
└─────┴─────┴─────┴─────┘


   life=: {{3=s-y*.4=s=. (+/@,) stencil 3 3 ] y}}
] glider=: 5 5$0 0 1 0 0 1 0 1 0 0 0 1 1,12$0
0 0 1 0 0
1 0 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
life glider
0 1 0 0 0
0 0 1 1 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
{&((u:16b25cb),u:16b25cf) &.> (i.8) {{life ^:x ] y}} &.> <glider
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│○○●○○│○●○○○│○○●○○│○○○○○│○○○○○│○○○○○│○○○○○│○○○○○│
│●○●○○│○○●●○│○○○●○│○●○●○│○○○●○│○○●○○│○○○●○│○○○○○│
│○●●○○│○●●○○│○●●●○│○○●●○│○●○●○│○○○●●│○○○○●│○○●○●│
│○○○○○│○○○○○│○○○○○│○○●○○│○○●●○│○○●●○│○○●●●│○○○●●│
│○○○○○│○○○○○│○○○○○│○○○○○│○○○○○│○○○○○│○○○○○│○○○●○│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘


   life=: (=&3@] +. (*. =&4)) (+/@,) stencil 3 3


   load 'dev/fold/foldr'
{&((u:16b25cb),u:16b25cf) &.> (< , <F:.(life@])&(i.7)) glider


键分组

key=: {{
(<"0 ~. y) u (y </. i.#y)
:
(<"0 ~. x) u (x </. y)}}


   x=: 'Mississippi'
[ key x
┌─┬─┬─┬─┐
│M│i│s│p│
└─┴─┴─┴─┘
] key x
┌─┬────────┬───────┬───┐
│0│1 4 7 10│2 3 5 6│8 9│
└─┴────────┴───────┴───┘
,. key x
┌─┬────────┐
│M│0       │
├─┼────────┤
│i│1 4 7 10│
├─┼────────┤
│s│2 3 5 6 │
├─┼────────┤
│p│8 9     │
└─┴────────┘
([ ,. #&.>@]) key x
┌─┬─┐
│M│1│
├─┼─┤
│i│4│
├─┼─┤
│s│4│
├─┼─┤
│p│2│
└─┴─┘


   ]a=: <;._1 ' pats spat teas sate taps etas past seat eats tase star east seta'
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│pats│spat│teas│sate│taps│etas│past│seat│eats│tase│star│east│seta│
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
/:~ &.> a
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│apst│apst│aest│aest│apst│aest│apst│aest│aest│aest│arst│aest│aest│
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
(]key~  /:~&.>) a
┌─────────────────────┬─────────────────────────────────────────┬──────┐
│┌────┬────┬────┬────┐│┌────┬────┬────┬────┬────┬────┬────┬────┐│┌────┐│
││pats│spat│taps│past│││teas│sate│etas│seat│eats│tase│east│seta│││star││
│└────┴────┴────┴────┘│└────┴────┴────┴────┴────┴────┴────┴────┘│└────┘│
└─────────────────────┴─────────────────────────────────────────┴──────┘


随机数

   ran=: (I.~ (+/\ % +/))~ [email protected]$&0 wt=: 7 5 6 4 7 2 0.4 # t=: wt ran 1e6 1000000 10 {. t 0 1 1 5 0 1 3 4 4 0 ] r=: wt (+/@(=/ i[email protected]#)~ % #@]) t NB. 实测的出现比率 0.222618 0.159083 0.19152 0.127394 0.222795 0.06378 0.01281 ] p=: (% +/) wt NB. 期望的出现概率 0.22293 0.159236 0.191083 0.127389 0.22293 0.0636943 0.0127389 0j6 ": r - p _0.000312 _0.000153 0.000437 0.000005 _0.000135 0.000086 0.000071  这里首先通过[email protected]$&0，生成指定数目的在区间(0,1)中的随机浮点数，它也可以写为等价的[email protected]($0:)。然后在叉子+/\ % +/中，使用一元副词\“前缀”修饰动词+/，从而计算权重向量的前缀和英语Prefix sum，再用前缀和除以总和得出累积分布函数。最后通过区间索引，在有随机浮点数落入特定区间的时候，生成这个区间对应的随机整数 动词ran的表达式是个二层二元钩子，外层钩子的第二步运算只应用到右参数上，它的第一步运算即内层钩子，整体修饰了二元副词~“被动”而对换了两个参数的位置。内层钩子的第二步运算+/\ % +/只应用到实际上的左参数上，它的第一步运算I.修饰了~，而将前面单独针对左右两参数的运算结果，再次对换回到原先的左右位置上。 下面是将区间索引和键分组结合起来的例子，演示了－列维中心极限定理[89]:  histogram =: {{ {&('.',u:16b258c) @ ((|.i.x)&(</)) @ (>[email protected]*&x) @ (% >./) y}} summary=: {{ l=. 0 [ r=. 1 -&1@#/.~ @ ((i.x)&,) @ ((l+(}.i.x)*%&x(r-l))&I.) y}} sampleMean=: {{%&m @ (+/) @ (m&,$ v@*&m) y}}
20&histogram @ (80&summary) @ (10 sampleMean ([email protected]$&0)) 1e6 ......................................▌▌▌▌...................................... .....................................▌▌▌▌▌▌..................................... ....................................▌▌▌▌▌▌▌▌.................................... ...................................▌▌▌▌▌▌▌▌▌▌................................... ..................................▌▌▌▌▌▌▌▌▌▌▌▌.................................. ..................................▌▌▌▌▌▌▌▌▌▌▌▌.................................. .................................▌▌▌▌▌▌▌▌▌▌▌▌▌▌................................. ................................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌................................ ................................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌................................ ...............................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌............................... ...............................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌............................... ..............................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌.............................. .............................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌............................. ............................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌............................ ............................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌............................ ...........................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌........................... ..........................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌.......................... ........................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌........................ ......................▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌...................... .........▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌........ lineChart=: {{ s=. (|.i.x)&(</) @ (>[email protected]*&x) @ (% >./) t=. >&0 @ (2&(-/\)) @ (2&(-~/\))"1 @ ,.&1 @ (1&,.) {&('.',u:16b2588) @ (2&(-~/\)@(0&,) +. t) @ s y}} 24&lineChart @ (+/\) @ (80&summary) @ (10 sampleMean ([email protected]$&0)) 1e6
....................................................████████████████████████████
..................................................██............................
................................................██..............................
...............................................█................................
..............................................█.................................
............................................██..................................
............................................█...................................
...........................................█....................................
..........................................█.....................................
.........................................█......................................
........................................█.......................................
.......................................█........................................
.......................................█........................................
......................................█.........................................
.....................................█..........................................
....................................█...........................................
...................................█............................................
...................................█............................................
.................................██.............................................
................................█...............................................
...............................█................................................
.............................██.................................................
...........................██...................................................
.........██████████████████.....................................................


   ratio=: -&1@#/[email protected](,~ i.)~ % #@]
10&histogram @ ((#wt)&ratio) @ (wt&ran) 1e6
random=: #@[ %~ ([email protected]$&0@] + ((I.~ (+/\ % +/))~ [email protected]$&0))
20&lineChart @ (80&summary) @ (wt&random) 1e6
20&lineChart @ (80&summary) @ (2 sampleMean (wt&random)) 1e6
20&lineChart @ (80&summary) @ (4 sampleMean (wt&random)) 1e6


SQLite插件

   load 'pacman'                NB. 加载包管理器
'install' jpkg 'data/sqlite' NB. 安装SQLite数据库插件
getbin_psqlite_ ''           NB. 安装SQLite数据库的共享库


SQLite数据库的简单用例：

   load 'data/sqlite'                   NB. 加载SQLite数据库插件
sqltables__db ''                     NB. 查看所有表格名字
┌─┬─┬──┐
│p│s│sp│
└─┴─┴──┘
sqlmeta__db 's'                      NB. 查看表格s的结构
┌───┬──────┬────┬───────┬──────────┬──┐
│cid│name  │type│notnull│dflt_value│pk│
├───┼──────┼────┼───────┼──────────┼──┤
│0  │sid   │text│0      │NULL      │1 │
│1  │name  │text│0      │NULL      │0 │
│2  │status│int │0      │NULL      │0 │
│3  │city  │text│0      │NULL      │0 │
└───┴──────┴────┴───────┴──────────┴──┘
ds=: sqlread__db 'select * from s'   NB. 读取表格s，结果表格形状扁长不适合直接展示
dict=: |: @:>                        NB. 以字典方式显示表格数据
] rs=: dict ds
┌──────┬──────────────────────────────────┐
│sid   │┌──┬──┬──┬──┬──┐                  │
│      ││s1│s2│s3│s4│s5│                  │
│      │└──┴──┴──┴──┴──┘                  │
├──────┼──────────────────────────────────┤
│name  │┌─────┬─────┬─────┬─────┬─────┐   │
│      │└─────┴─────┴─────┴─────┴─────┘   │
├──────┼──────────────────────────────────┤
│status│20 10 30 20 30                    │
├──────┼──────────────────────────────────┤
│city  │┌──────┬─────┬─────┬──────┬──────┐│
│      ││london│paris│paris│london│athens││
│      │└──────┴─────┴─────┴──────┴──────┘│
└──────┴──────────────────────────────────┘
rs -: sqldict__db 's'
1
cols=: {: @:>                       NB. 表格数据的诸列列表
cs=: cols ds
cs -: sqlexec__db 's'
1
('s_'&, &.> @ {. @:> ds) =: cs      NB. 将表格的诸列并行赋值给添加了表名前缀的诸列名
s_status
20 10 30 20 30
s_sid
┌──┬──┬──┬──┬──┐
│s1│s2│s3│s4│s5│
└──┴──┴──┴──┴──┘
({. @:> ds) -: sqlcols__db 's'
1
reads=: ({. , (,@> &.>)@}.) @:>    NB. 格式化显示表格数据
┌───┬─────┬──────┬──────┐
│sid│name │status│city  │
├───┼─────┼──────┼──────┤
│s1 │smith│20    │london│
│s2 │jones│10    │paris │
│s3 │blake│30    │paris │
│s4 │clark│20    │london│
└───┴─────┴──────┴──────┘
$@ (2&{:: @ {:) rs NB. 第3列数据的形状 5 1 rs -: sqlreads__db 's' 1 readm=: ({. ; <@|:@:(< @ > @ >)@{:) @:> NB. 以矩阵显示表格数据 ] rs=: readm ds ┌──────────────────────┬────────────────────┐ │┌───┬────┬──────┬────┐│┌──┬─────┬──┬──────┐│ ││sid│name│status│city│││s1│smith│20│london││ │└───┴────┴──────┴────┘│├──┼─────┼──┼──────┤│ │ ││s2│jones│10│paris ││ │ │├──┼─────┼──┼──────┤│ │ ││s3│blake│30│paris ││ │ │├──┼─────┼──┼──────┤│ │ ││s4│clark│20│london││ │ │├──┼─────┼──┼──────┤│ │ ││s5│adams│30│athens││ │ │└──┴─────┴──┴──────┘│ └──────────────────────┴────────────────────┘ rs -: sqlreadm__db 's' 1 cp=: '~addons/data/sqlite/db/sandp.db' ; '~/test_sandp.db' db=: sqlcopy_psqlite_ cp NB. 复制数据库并打开复本 cls=: sqlcols__db 's' NB. 得到表格s的列名列表 dat=: ('s6';'s7') ; ('brown';'eaton') ; 40 10 ;< 'rome';'madrid' sqlinsert__db 's' ; cls ;< dat NB. 将数据插入表格s 0 3 sqltail__db 's' NB. 返回最后3个格式化记录 ┌───┬─────┬──────┬──────┐ │sid│name │status│city │ ├───┼─────┼──────┼──────┤ │s5 │adams│30 │athens│ │s6 │brown│40 │rome │ │s7 │eaton│10 │madrid│ └───┴─────┴──────┴──────┘ sqlclose__db '' NB. 关闭数据库 1  字典类 J语言采用命名语境实现，采用编号语境实现对象，下面示例建立字典 cocurrent 'Dict' create=: {{o [ DEFAULT__o=: 0$0 [ o=. conew 'Dict'}}
get=: {{". 'ITEM_',y}}
set=: {{
('ITEM_',y)=: DEFAULT
:
('ITEM_',y)=: x}}
del=: {{erase 'ITEM_',y}}
pop=: {{r [ del y [ r=. get y}}
default=: {{DEFAULT=: y}}
filt=: {~ I[email protected]:({[email protected]('ITEM_'&E.)@>)
len=: {{# filt namelist 0}}
list=: {{5&}.&.> filt namelist 0}}
in=: {{+/@:(-:&y@>) list ''}}
clear=: {{#@,@:(erase @>) filt namelist 0}}
copy=: {{o=. conew 'Dict'
o [ "[email protected](,&'__o=:',(5!:5)@<)&.> 'DEFAULT';filt namelist 0}}
destroy=: codestroy
cocurrent 'base'


   load '~/dict.ijs'
conl 0            NB. 检视命名语境
┌────┬────┬─┬────────┬──────┬─────┬─┐
└────┴────┴─┴────────┴──────┴─────┴─┘
namelist_Dict_ 3  NB. 检视Dict类的动词
┌─────┬────┬──────┬───────┬───┬───────┬────┬───┬──┬───┬────┬───┬───┐
│clear│copy│create│default│del│destroy│filt│get│in│len│list│pop│set│
└─────┴────┴──────┴───────┴───┴───────┴────┴───┴──┴───┴────┴───┴───┘
d=: create_Dict_ ''
d                 NB. 变量保存的是盒装字符串
┌─┐
│0│
└─┘
namelist__d 0     NB. 检视d对象的名词
┌─────────┬───────┐
│COCREATOR│DEFAULT│
└─────────┴───────┘
conl 1            NB. 检视编号语境
┌─┐
│0│
└─┘
copath <'0'       NB. 检视编号语境的查找路径
┌────┬─┐
│Dict│z│
└────┴─┘
set__d 'i1'

(2 3) set__d 'i2'
2 3
'abc' set__d 'i3'
abc
len__d ''
3
list__d ''
┌──┬──┬──┐
│i1│i2│i3│
└──┴──┴──┘
e=: copy__d ''
get__d 'i2'
2 3
del__d 'i2'
1
in__d 'i3'
1
pop__d 'i3'
abc
clear__d ''
1
list__e ''
┌──┬──┬──┐
│i1│i2│i3│
└──┴──┴──┘


引用

1. ^ Roger K.W. Hui, Kenneth E. Iverson, , . APL\?. 1990 [2022-06-12]. （原始内容存档于2022-06-14）. This paper describes a version of APL based upon the dictionary, but significantly simplified and enhanced, and directly usable on any machine that provides ASCII characters. It also describes salient features of a C implementation that has been tested on several machines, and is available as freeware.
2. ^
3. ^ SuperCollider documentation, Adverbs for Binary Operators. [2020-04-18]. （原始内容存档于2020-12-11）.
4. ^ GNU Octave Manual, Broadcasting. [2022-06-25]. （原始内容存档于2022-06-27）.
5. ^ NumPy fundamentals, Broadcasting. [2022-06-21]. （原始内容存档于2022-07-03）.
6. ^ 903-release-b. [2022-04-28]. （原始内容存档于2022-04-28）.
7. ^ K. E. Iverson. A Personal View of APL. 1991 [2022-06-12]. （原始内容存档于2022-06-12）. Roger and I then began a collaboration on the design and implementation of a dialect of APL (later named J by Roger), first deciding to roughly follow “A Dictionary of APL” and to impose no requirement of compatibility with any existing dialect. We were assisted by suggestions from many sources, particularly in the design of the spelling scheme (E.B. Iverson and A.T. Whitney) and in the treatment of cells, items, and formatting (A.T. Whitney, based on his work on SHARP/HP and on the dialect A reported at the APL89 conference in New York).
8. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. In 1989, Iverson, together with Roger Hui and with input from Arthur Whitney, produced J, with a goal of providing a “shareware” APL implementation for use in teaching. The special APL characters were abandoned because it was felt that they require technical solutions which at that time were still prohibitively expensive in an educational environment. ……
J was clearly a “rationalization” of SHARP APL. ……
ACM SIGAPL, the ACM Special Interest Group on APL, reinterpreted the “APL” in its name in early 2009 as Array Programming Languages, so that J, k, Nial, etc. would be included in its purview.
9. ^ Roger Hui earns the Iverson Award. [2022-07-30]. （原始内容存档于2022-07-30）.
10. ^ Kenneth E. Iverson. A Dictionary of APL. 1987 [2022-06-08]. （原始内容存档于2022-06-12）. A dictionary should not be read as an introduction to a language, but should rather be consulted in conjunction with other material that uses the language in some context of interest to the reader. Even the general section on grammar, which may be intelligible even to the beginner, should perhaps be studied only after a certain amount of other exposure to the language.
On the other hand, a dictionary should not be used only to find the meanings of individual words, but should also be studied to gain an overall view of the language. In particular, the grammar may be profitably reviewed again and again in the light of increased knowledge of the language, and the study of groups of related verbs and adverbs can reveal important relationships otherwise easily overlooked.
11. ^ Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. Nuclear Axis Operators － The nuax operator (denoted by ⍤) applies to a function left argument and a variable right argument to specify the axes which define the nuclei to which the function is to apply. ……The coax operator ⍥ is also provided; its argument specifies the axes complementary to the nuclear axes.
Kenneth E. Iverson. Rationalized APL. 1983 [2022-06-19]. （原始内容存档于2022-07-22）. In conventional APL, the scalar functions (which apply to scalar elements and produce scalar results) extend to higher rank arrays according to simple general rules; no corresponding general rules exist for the remaining so-called mixed functions. ……
Function rank is the most important notion needed to provide a simple and systematic basis for the uniform treatment of all “mixed” or non-scalar functions. ……
If f has rank r, then f⍵ is determined by applying f to each of the “cells” of shape (-r)↑⍴⍵, producing a common shape s for each, and assembling the whole into a result of shape ((-r)↓⍴⍵),s. ……
If the function g←f⍤r is to be applied dyadically as well as monadically (the only cases addressed in the preceding sections), then it is necessary that r specify three independent ranks, the monadic, the left, and the right. The general argument r is therefore a three-element vector that specifies the ranks in the order just indicated. Moreover, r is extended by reshape if necessary, so that f⍤r ←→ f⍤(⌽3⍴⌽r).
12. Kenneth E. Iverson, . Phrasal Forms. APL 89 Conference Proceedings. August 1989 [2022-06-09]. （原始内容存档于2022-06-12）. Curry [Cu31] defines a formalizing combinator, Φ, in prefix notation, such that Φfghx means f(gx)(hx). In common mathematical infix notation this would be designated by (g(x))f(h(x)). An example of this form is Φ+sin2cos2θ, meaning sin2θ+cos2θ. The fork (f g h)⍵ has the same meaning, namely (f⍵)g(h⍵). Curry named this the formalizing combinator because of its role in defining formal implication in terms of ordinary implication.
Iverson and Whitney have made several earlier suggestions of ways to achieve what the fork form provides: the scalar operators of [Iv78], [Iv79a], [Iv 79b], the til operator of [Iv82], the union and intersection conjunctions of [Iv87], and the yoke adverb of [Iv88]. Benkard [Bk87] has also suggested a way to achieve the meaning of this form, in his proposal for ↑g/(f h)⍺ ⍵, using the notion of function pair (↑ is APL2’s first function). The present proposal has significant advantages over these earlier ones.
13. ^ Roger K.W. Hui, Kenneth E. Iverson, . Tacit Definition. 1991 [2022-06-11]. （原始内容存档于2022-07-06）. To appreciate the more general use of tacit definition, it is necessary to understand three key notions of J: cells and rank, forks, and composition.……
The conjunction & is called with, and applies to nouns (variables) a and b as well as to verbs f and g as follows:
a&g y is a g y
f&b y is x f y
f&g y is f g y
x f&g y is (g x) f (g y)
……
A number of other constructs in J similarly enhance the utility of tacit definitions. The more important are the under (or dual), atop (a second form of composition), the power conjunction ^:, and further forms of partitions.

Jsoftware. Changes in Version 3.2, 1991 06 02. 1991 [2022-11-07]. （原始内容存档于2022-06-14）.
@.    agenda
@:    at
&:    appose
14. Kenneth E. Iverson, . Phrasal Forms. APL 89 Conference Proceedings. August 1989 [2022-06-09]. （原始内容存档于2022-06-12）. In combinatory logic one of the most useful primitive combinators is designated by S [Sch24]. Curry defines Sfgx in prefix notation to be fx(gx) [CuFeCr74]. In common mathematical infix notation this would be given by (x)f(g(x)), which one can write in APL as xfgx, and this is the hook form (fg)x. The combinatory logician appreciates this form because of its great expressiveness: it can be shown that S, along with K, the constancy combinator, suffice to define all other combinators of interest [Ro50]. (The constancy combinator K is defined in infix notation so that cKx has the value c for all x.) Users of APL will appreciate the hook for the same reasons.
15. ^ , Roger K. W. Hui. Gerunds and representations. 1991 [2022-06-12]. （原始内容存档于2022-06-12）. Gerunds, verbal forms that can be used as nouns, are recognized as having utility in the realm of programming languages. We show that gerunds can be viewed as arrays of atomic repmentations of verbs (functions), in a way which is consistent with the syntax and semantics of APL, and which allows verbs to be first class objects in the language. We define derivations of verbs from gerunds in the J dialect of APL, and show how these derivations provide control structures for sequencing, selection (in the sense of generalized forms of CASE or SWITCH statements and IF/THEN/ELSE), iteration (DO UNTIL), recursion, and parallel computation (MIMD, or Multiple Instruction, Multiple Data). We conclude with alternative representations of verbs which are useful in other contexts.
Jsoftware. Changes in Version 4.0, 1991 11 23. 1991 [2022-06-12]. （原始内容存档于2022-06-14）.
:1    replaced by u^:v
:4    replaced by m~
:5    replaced by @.
16. Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. For years, Iverson struggled to achieve in APL the effect of f+g and f×g as they are written in calculus. …… Finally, trains AKA forks were invented [Iverson and McDonnell 1989]. ……
Moreover, (f … h p q r) ↔ (f … h (p q r)), and an isolated sequence of two functions is also assigned a meaning (atop, described below), so that a train of any length, even or odd, is interpreted. ……
Subsequently, it was realized that trains greatly increase the possibilities for “tacit definition”, expressions consisting of compositions of functions which do not explicitly mention the arguments [Hui et al. 1991]. Trains are implemented in several dialects: J [Hui et al. 1991], NARS2000 [Smith 2020], NGN APL [Nickolov 2013], and Dyalog APL [Scholes 2013]. ……
The expressive completeness of trains depends on an atop composition of two functions …… Dyalog APL defines 2-trains as atop. That, together with the functions ⊣(left) and ⊢(right), allows many common compositions to be written as trains.
17. ^ Vocabulary/Words. [2020-05-18]. （原始内容存档于2016-03-07）.
18. Kenneth E. Iverson. Rationalized APL. 1983. The enclose function as defined in [Operators and Enclosed Arrays] has made it possible to produce by straightforward APL functions the “index lists” required in indexing expressions of the form a[i;j], and therefore makes it possible to define a corresponding indexing function, which will be denoted by { and called from:
i{a ←→ a[>i[0];>i[1]; ...]
Since the disclose function > is permissive, the selection of any single element of a can be written without enclosures as, for example, 1 2 3{a3. Moreover, the left rank of { is 1 and its right rank is infinite, so that …… a simple left argument i of rank greater than 1 produces an array of shape ¯1↓⍴i of elements chosen by the index vectors along its last axis, yielding what is sometimes called “scattered” indexing. For examp1e:
(3 2⍴⍳6){a2 ←→ a2[0;1],a2[2;3],a2[4;5]
……
In forming the left arguments of the indexing function, it will often be convenient to use the link function ⊃ defined as follows:
⊃b ←→ <b if b is simple
b if b is non-simple
a⊃b ←→ (<a),⊃b
For example, (2 3⊃4⊃∘⊃5 6){a4 ←→ a[2 3;4;;5 6].
The indexing function { as defined thus far provides all of the facilities provided by conventional indexing, and “scattered” and “complementary” indexing as well. Its power is further enhanced by allowing negative indexing …….

Roger Hui. Some Uses of { and }. 1987. Dyadic { encompasses all computations expressible by [;] indexing of APL\360, as well as the new negative indexing and complementary indexing.
19. IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. For vectors R and X, the decode(or base-value) function R⊥X yields the value of the vector X evaluated in number system with radices R[1],R[2],...,R[⍴R]. ……
Scalar(or one-element vector) arguments are extended to conform, as required. ……
the decode function is extended to arrays in the manner of the inner product: each of the radix vectors along the last axis of the first argument is applied to each of the vectors along the first axis of the second argument.

J语言的#.并未继承IBM对APL解码函数⊥的扩展规定，它可以实现为：
   decode=: {{x #."(1 _) (0|: y)}}

20. Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. We also introduce a form of indexing called from denoted by ⌷, ……. The basic definition is:
i⌷a ↔ (,a)[⍉(⍴a)⊥⍉i]
The function ⌷ distributes over any scalar function; thus, i⌷a+b ↔ (i⌷a)+(i⌷b). …… For example:
m←3 4⍴⍳12
m
0 1  2  3
4 5  6  7
8 9 10 11
2 2 ⌷ m
10
……
(3 2⍴3|⍳6)⌷m
1 8 6

J语言在定义上述的⌷（from）之时，解码前后不需要专门进行一元转置⍉运算：
   from=: {{(($y) #. x) {::"(0 _) (, y)}} ]m=: 3 4$i.12
0 1  2  3
4 5  6  7
8 9 10 11
2 2 from m
10
3 2$3|i.6 0 1 2 0 1 2 (3 2$3|i.6)from m
1 8 6

21. ^ IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. APL functions apply to collections of individual items called arrays. Arrays range from scalars, which are dimensionless, to multi-dimensional arrays of arbitrary rank and size.
22. ^ Bob Smith. Nested arrays, operators, and functions. 1981 [2022-06-19]. （原始内容存档于2022-06-20）. The data structures of APL are rectangular, multi-dimensional, and flat -- the latter term meaning that all items of arrays are simple scalars. ……
In general, a system with nested arrays extends the power of APL by being able to represent data of non-zero depth. Also, in keeping with the past, the system includes a set of primitive functions and operators, tailor-made for manipulating these new data structures.
Continuing the above example, the names of the months of the year are best represented in a 12-item vector whose items are each character vectors. This structure has a depth of one. Note that because the individual names are in separate items, we need no longer resort to artifices like pad characters. Moreover, explicit delimiters are not needed as the separation between items is represented through structure rather than data. This particular representation is called a vector of vectors, and can be created as follows:
MONTHS ← ('JANUARY') ('FEBRUARY') ...
The above line also illustrates strand notation, used to enter a nested vector in a simple and convenient manner. ……
Of the several new operators, the only one specific to nested arrays is the each operator(symbol ¨), which is monadic as an operator, and produces an ambivalent derived function. It is used to apply the f unction which is its argument to the items of an array to produce corresponding items in the result. For example, to determine the length of the names of the months in the above example, use
⍴¨MONTHS
(7) (8) (5) (5) (3) (4) (4) (6) (9) (7) (8) (8)
Since monadic rho returns a vector , each item of the above result is a vector (specifically in these cases a one-item vector). The parentheses in the display indicate that the item is not a simple scalar.
23. ^ . The Principles of APL2. TR 03.247. IBM Santa Teresa Laboratory, San Jose, California. 1984 [2022-06-23]. （原始内容存档于2022-06-12）. APL2 is based on this writer' s PhD Thesis [Br1], the array theory of Trenchard More [Mo1] and most of all on APL1. ……
The arrays of APL2 are finite rectangular arrays which contain arrays as items. When the term array is used, it means this subset of all possible arrays.
The arrays of APL2 are the same as the arrays of Array Theory and in particular empty arrays have structure as defined by Array Theory [Mo1 etc.].
An array one of whose items is other than a single number or character (a simple scalar) is called a nested array. An array containing only numbers or containing only characters is called a homogeneous array. An array all of whose items are either single numbers or single characters is called a simple array. The arrays of APL1 are simple and homogeneous.
In some sense every array in APL2 is nested because it contains other arrays. The term is reserved for those which contain at least one item which is not a single number or character. Thus the universe of arrays is partitioned into two subsets: simple arrays and nested arrays. ……
A function is pervasive if pick distributes over it. ……
Since the pick function may select an item at an arbitrary depth in a nested array, it may select deep enough to access a simple scalar (because nested arrays have finite depth). Thus a pervasive function may be thought of as applying independently to each simple scalar in its argument(s). ……
In APL2 the scalar functions and only the scalar functions are pervasive.
24. Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. The enclose function (denoted by <) produces a scalar representation of its argument in the sense that the result is of rank zero, and that there exists an inverse function (called disclose, and denoted by >) such that a ↔ ><a for all a. Any result producible by an expression which does not employ the enclose function is called a simple array, or is said to be simple.
Selection and reshaping functions apply without change to non-simple arrays. However, non-simple arrays are outside the domain of all other functions except for enclose, disclose, and equality (together with those functions such as ≠ and ∊ which are defined in terms of equality).
The equality function is extended to non-simple scalar arguments as follows:
1. (<a)≠a for all a
2. If a equals b(in rank, shape, and all elements), then (<a)=(<b) yields 1
……
The disclose function is scalar in the sense that it applies to each element of its argument, the new axes disclosed becoming the final axes of the result. ……
The disclose function applied to a simple array a produces a result identical to a. Thus (<a)=<>a is a test for whether a is simple.
25. ^ Kenneth E. Iverson. Rationalized APL. 1983. APL2 provides two significant facilities which apply at “depth” in the enclosure structure of an argument, the dyadic pick function, and the pervasive functions. RS provides no primitive corresponding to pick; it could be defined recursively by:
pick←''∇('→2+0=⍴⍺'⊃'(>0{⍺){(1↓⍺)∆⍵'⊃'⍵')
……
Since pervasiveness is a property assigned to functions, it would, in the framework of RS, be provided by an operator. Such an operator could be applied to any function (defined or derived as well as primitive) and, if defined to be dyadic, could provide greater variety. ……
If each essential space in an expression is counted as a character, then the link function and strand notation used to form non-simple vectors from simple vectors require expressions of nearly identical length. ……
RS does not include the heterogeneous arrays of APL2, and the production of equivalent constructs requires greater use of enclosure. However, the structure of RS does not preclude their introduction. ……
The monadic enclose functions defined in RS (<) and in APL2 (⊂) differ in one respect: if s is a simple scalar, then s≡⊂s, but ~s≡<s. Although < can therefore produce some structures not producible by ⊂, the differences between them (in the contexts of the respective systems) cannot, in most cases, be discerned.
26. ^ Guides/AVX. [2021-12-20]. （原始内容存档于2021-12-20）.
27. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. In order to provide users with access to APIs and frameworks, APL language designers searched for ways to integrate into APL, where everything is an array, selected aspects of the OO paradigm, where everything is an object. ……
Some interpreters, like APL+Win, avoided incorporating objects into the APL heap (or “workspace”). ……
Other systems added features which allowed variables, functions and operators to be organized in dynamic objects in the workspace. The resulting containers are known as namespaces (Dyalog APL) and locales (J). k implements dictionaries, which are also containers for arrays, but are typically used to contain arrays representing the columns of a relational table. …… The same language features which supported namespaces or classes within APL were used to wrap the external objects used by object oriented APIs, or platforms like the Microsoft’s OLE and .NET frameworks.
The choice of syntax for referring to a member name of an object emp was not straightforward. ……
Most APL systems did adopt the notation from other OO languages — with a few exceptions.
emp.name    in most APL systems
name__emp   in J (retaining right-to-left evaluation)
emp[name]  in k (using a symbol within index brackets to select from a dictionary)
……
Although APL interpreters have had extensive support for object oriented programming for nearly two decades, most APL users still feel that object and array paradigms are an awkward fit. …… Many of the benefits of OO are related to taking advantage of types, while much of the strength of the APL family is that you can write code which is shape, rank, and type agnostic — achieving many of the same goals as OO through radically different mechanisms.
28. ^ 语境. [2022-09-29]. （原始内容存档于2022-09-29）.
29. Chris Burke. J4 and OOP. 1998 [2022-11-08]. （原始内容存档于2022-11-08）.
Roger Stokes. Chapter 25: Object-Oriented Programming. 2015 [2020-05-18]. （原始内容存档于2020-06-25）.
30. ^ J9 base library. [2022-10-20]. （原始内容存档于2022-12-19）.
标准库页面存档备份，存于互联网档案馆
31. ^ 包管理器. [2020-05-22]. （原始内容存档于2021-04-06）.
32. ^ 插件页面存档备份，存于互联网档案馆
33. ^ Run a sentence and produce a 2D display of results. [2022-10-30]. （原始内容存档于2022-10-30）.
剖析页面存档备份，存于互联网档案馆
34. ^ Jdatabase (Jd) is a relational database management system (RDBMS) from Jsoftware that is implemented in J. [2022-09-25]. （原始内容存档于2022-12-06）.
35. ^ Bussell, Brian; Taylor, Stephen, Software Development as a Collaborative Writing Project, Extreme programming and agile processes in software engineering, Oulu, Finland: Springer: 21–31, 2006, ISBN 978-3-540-35094-1, In practice, competence in the business and in writing software coincide only where the business requires mathematical skills. In consequence, highly abstract executable notations such as APL, A+, J, K, Q, R and S flourish primarily among actuaries, financial traders and statisticians. ……
A key technique to the success of this has been programmers and users collaborating on writing the source code. ……
Programmers have made this possible by constructing local, domain-specific executable notations. The vocabulary of these notations is drawn from the users’ talk about the work. ……
Users and programmers can now converge quickly on and verify a common understanding. The notation enables them to avoid ambiguity; it is a “tool for thought” in the sense of Iverson’s Turing Award lecture [11]. Because the notation is executable (and interpreted), the running system animates the described behaviour in front of them.
36. ^ Holt, Alan, Network Performance Analysis: Using the J Programming Language, Springer, 2007, ISBN 978-1-84628-822-7
37. ^ Eric Iverson. J Source GPL. J programming mailing list. 1 March 2011 [2020-05-18]. （原始内容存档于2016-09-23）.
38. ^ Jsoftware's sourcing policy. [2020-05-18]. （原始内容存档于2021-01-26）.
39. ^ 名词页面存档备份，存于互联网档案馆
40. ^ 动词页面存档备份，存于互联网档案馆
41. ^ 定语页面存档备份，存于互联网档案馆
42. ^ NuVoc页面存档备份，存于互联网档案馆
43. ^ 词类页面存档备份，存于互联网档案馆
44. ^ 入门页面存档备份，存于互联网档案馆
45. ^ 字典页面存档备份，存于互联网档案馆
46. IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. For example, the grade function ⍋ is commonly used to produce indices needed to reorder a vector into ascending order (as in X[⍋X]), but may also be used in the treatment of permutations as the inverse function, that is, ⍋P yields the permutations as the inverse to P.
47. ^ Read and write CSV files and strings. [2022-06-14]. （原始内容存档于2022-07-07）.
48. ^ Roger K.W. Hui. Extended Integers in J. 1996 [2022-06-24]. （原始内容存档于2022-06-28）. Some verbs v signal domain error on some extended arguments because the result is not integral; however, <[email protected] and >[email protected] are closed on extended arguments.
49. ^ J Memory Mapped File. [2022-10-20]. （原始内容存档于2022-10-20）.
内存映射文件页面存档备份，存于互联网档案馆
50. IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. The outer product operator, denoted by by the symbols ∘. preceding the function symbol, applies to any dyadic primitive scalar function, so that the function is evaluated for each member of the left argument paired with each member of the right argument. ……
Such tables may be better understood if labelled in a way widely used in elementary arithmetic texts: values of the arguments are placed beside and above the table, and the function whose outer product is being computed is shown at the corner.
51. ^ K.E. Iverson. Determinant-Like Functions Produced by the Dot Operator. 1982. The operator denoted by the dot has been extended to provide a monadic function (as in -.×m) as well as the established dyadic inner product function (as in n+.×m). ……
The determinant of a square matrix m is defined as the alternating sum (i.e. reduction by -) of the !n←1↑⍴m products over n elements chosen (in each of the !n possible ways) one from each row and column. Analogous calculations in which other function pairs are substituted for - and × lead to other useful functions; examples include the pairs ⌈⌊, ∧∨, and +×, the last (called the permanent) being useful in combinatorics.
52. IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. If P and Q are vectors of the same shape, then the expression +/P×Q has a variety of useful interpretations. ……
The inner product produces functions equivalent to expressions in this form; it is denoted by a dot and applies the two function surround it. Thus P+.×Q is equivalent to +/P×Q, and P×.⋆Q is equivalent to ×/P⋆Q, and, in general, Pf.gQ is equivalent to f/PgQ, if P and Q are vectors.
The inner product is extended to arrays other than vectors along certain fixed axes, namely the last axis of the first argument and the first axis of the last argument. the lengths of these axes must agree. the shape of the result is obtained by deleting these axes and chaining the remaining shape vectors together. ……
The inner product M+.×N is commonly called the matrix product. ……
Either argument of the inner product may be a scalar or a one-element vectors; it is extended in the usual manner.
53. ^ Kenneth E. Iverson. A Dictionary of APL. 1987. The case 3⍤v also has left rank 2 , and ⍺3⍤v⍵ applies v to each element produced by a tessellation of ⍵, using a size 1{⍺, and beginning points that are multiples of the “shift” 0{⍺.
54. ^ 页面存档备份，存于互联网档案馆
55. ^ 动词信息. [2022-06-04]. （原始内容存档于2022-07-06）.
56. 框架填充. [2022-06-07]. （原始内容存档于2022-07-06）.
57. ^ 定语生成的动词的秩. [2022-06-04]. （原始内容存档于2022-07-07）.
58. ^ Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. The dual operator, denoted by ⍢, is a slight extension of the notion of dual functions implicit in deMorgan’s law (∨⍢~ ↔ ^ and ≠⍢~ ↔ =), the extension being to include a monadic left argument, as in ⌊⍢-x ↔ ⌈x. ……
Composition and the dual operator applied to a divalent left argument and a monadic (or divalent) right argument yield parallel definitions of divalent derived functions as follows:
……
Dual:  f⍢g y ↔ (g⍣¯1) f (g y)
x f⍢g y ↔ (g⍣¯1) (g x) f (g y)
It should be noted that the extension of the dual to include the monadic definition makes the identities ⌈⍢- ↔ ⌊ and ⌊⍢- ↔ ⌈ hold for both the monadic case (floor and ceiling) and for the dyadic case (minimum and maximum). Moreover, for the dyadic case the exponential function yields the identities ×⍢* ↔ + and +⍢⍟ ↔ ×, the latter of which provides the basis for the use of natural logarithms in multiplication, just as the identity +⍢(10¨⍟) ↔ x forms the basis for the use of base ten logarithms.
59. ^ Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. The expression f⍢> produces a derived function which applies the function f to its argument in an “item-wise” fashion, by disclosing each element of the argument, applying f, and enclosing the result to produce the corresponding element of the overall result.
60. ^ Roger Hui. Remembering Ken Iverson. 2004 [2022-11-05]. （原始内容存档于2019-12-20）. Ken and I had in mind to implement A Dictionary of APL [8] together with hooks and forks (phrasal forms) [20]. ……
The choice to implement forks was fortuitous and fortunate. We realized only later [32] that forks made tacit expressions (operator expressions) complete in the following sense: any sentence involving one or two arguments that did not use its arguments as an argument to an operator, can be written tacitly with fork and @:(compose) and [(left) and ](right) and constant functions. If @: were replaced by the equivalent special fork [: f g, then a sentence can be written as an unbroken train (sequence of forks). ……
Meanwhile, Ken was concerned about the usefulness of forks, and worked hard at finding examples of forks beyond those in Phrasal Forms [20]. After a while, it seemed that everything was a fork. The explanation lies in the proof of completeness for tacit definition [32]: if the root (last) function in a sentence is applied dyadically, then a fork is required to write the sentence tacitly.
61. ^ Function composition. [2022-06-09]. （原始内容存档于2022-07-06）.
62. ^ Kenneth E. Iverson. A Dictionary of APL. 1987 [2022-06-08]. （原始内容存档于2022-06-12）.
u⍥v    Rank: mv lv rv    Upon; Upon
The monad u is applied to the result of v, that is:
u⍥v ⍵ ←→ u v ⍵ ←→ u⍤v ⍵
⍺ u⍥v ⍵ ←→ u ⍺ v ⍵
63. ^ Kenneth E. Iverson. A Dictionary of APL. 1987 [2022-06-08]. （原始内容存档于2022-06-12）.
u⍤v    Rank: mv mv mv    On; On
Monad. In the simplest case u⍤v ⍵ is equivalent to u v ⍵. …… more generally, the rank of the derived function u⍤v is the rank of v; that is, the expression u v is applied to each of the cells of ⍵ relative to v. ……
Dyad. The left and right ranks of u⍤v are both the monadic rank of v. Therefore ⍺ u⍤v ⍵ is equivalent to (v⍺) u v ⍵.
64. ^ Kenneth E. Iverson. A Dictionary of APL. 1987 [2022-06-08]. （原始内容存档于2022-06-12）. Withe (u⍩v) is similar to (u⍤v), but applies v only to the right argument:
⍺ u⍩v ⍵ ←→ ⍺ u v ⍵
u⍩v ⍵ ←→ ⍵ u v ⍵
65. ^ Kenneth E. Iverson. A Dictionary of APL. 1987 [2022-06-08]. （原始内容存档于2022-06-12）.
u¨v    Rank: mv mv mv    Under; Under
This function is equivalent to composition (u⍤v) except that the function inverse to v is applied to the result of each cell. …… The function u¨v is often called “the dual of u with respect to v”, but the phrase “u under v” is probably better, suggesting that u is performed after preparatory work by v, and before the task is sewn up by reversing the effect of v. The expression u¨v is valid only if v possesses an inverse.
66. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. One of the HOPL IV badges has an APL expression on it: ÷+/÷(e≠0)/e, the reciprocal of the sum of the reciprocals of the non-zero values of e. The expression computes the total resistance of components connected in parallel, whose resistance values are the vector e.
There is an alternative phrasing in modern APL: +⌿⍢÷e~0, sum under reciprocal (§3.5), without 0s. If arithmetic were extended to infinity (§4.6), in particular if ÷0 ↔ ∞ and ÷∞ ↔ 0, then the expression would simplify to +⌿⍢÷e, without the without 0 (~0).
67. ^ Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. The power operator, denoted by ⍣, applies to a monadic function left argument f and an integer right argument k to produce the kth power of f in the following sense: f⍣k ↔ f f⍣k-1, and f⍣1 ↔ f. In particular, f⍣0 is the identity function and f⍣¯1 is the inverse of f. Moreover, f⍣_ denotes the limit of f, that is, the limiting function f⍣n for n large. Similarly, f⍣¯ denotes the limit of the inverse of f.
68. ^ Vocabulary/Inverses. [2022-10-23]. （原始内容存档于2022-12-05）.
69. ^ Kenneth E. Iverson, Peter K. Wooster. A Function Definition Operator. APL Quote Quad, Volume 12, Number 1, Proceedings of APL81, ACM. September 1981 [2022-06-29]. （原始内容存档于2022-06-29）. This paper proposes two related extensions to APL: the extension of assignment to allow a name F to be assigned to a derived function by an expression of the form F←+.x, and the introduction of a dyadic operator ∇ to apply to character arrays D and M so that D∇M produces an ambivalent function in which the dyadic case is defined by D and the monadic case by M.
Kenneth E. Iverson. Rationalized APL. 1983 [2022-06-19]. （原始内容存档于2022-07-22）. The proposed replacement for ⎕fx is a modification of the direct definition operator ∇ defined in [A Function Definition Operator], ……
A function produced by the operator ∇ may be assigned a name (as in f←m∇d or in a(f←m∇d)b), but it may also be used without assigning a name, as in y←''∇'⍺+÷⍵'/x.
70. ^ . Direct Functions in Dyalog APL (PDF). October 1996 [2022-06-30]. （原始内容存档 (PDF)于2021-10-05）. A Direct Function (dfn) is a new function definition style, which bridges the gap between named function expressions such as rank←⍴∘⍴ and APL’s traditional ‘header’ style definition.
System/ReleaseNotes/J902. 14 May 2020 [2022-06-30]. （原始内容存档于2022-07-03）. Explicit entities can be defined using direct definition. The digraphs {{ and }} are reserved for delimiters, and text found between {{ }} is taken to define a verb/adverb/conjunction. The text may be multiple lines long and may contain other embedded definitions. The part of speech of the defined entity is inferred from the words in it.
71. ^ DGEMM - matrix matrix multiply. [2022-10-13]. （原始内容存档于2022-10-10）.
72. ^ 控制结构
73. ^ , K. E. Iverson. APL\360 User's Manual (PDF). IBM. August 1968 [2022-07-09]. （原始内容存档 (PDF)于2021-10-27）.
Table 3.9 shows the detailed definitions of transposition for a variety of cases. ……
Case ⍴R Definition
R←1⍉V ⍴V R←V
R←1 2⍉M ⍴M R←M
R←2 1⍉M (⍴M)[2 1] R[I;J]←M[J;I]
R←1 1⍉M ⌊/⍴M R[I]←M[I;I]
R←1 2 3⍉T ⍴T R←T
R←1 3 2⍉T (⍴T)[1 3 2] R[I;J;K]←T[I;K,J]
R←2 3 1⍉T (⍴T)[3 1 2] R[I;J;K]←T[J;K;I]
R←3 1 2⍉T (⍴T)[2 3 1] R[I;J;K]←T[K;I;J]
R←1 1 2⍉T (⌊/(⍴T)[1 2]),(⍴T)[3] R[I;J]←T[I;I;J]
R←1 2 1⍉T (⌊/(⍴T)[1 3]),(⍴T)[2] R[I;J]←T[I;J;I]
R←2 1 1⍉T (⌊/(⍴T)[2 3]),(⍴T)[1] R[I;J]←T[J;I;I]
R←1 1 1⍉T ⌊/⍴T R[I]←T[I;I;I]
Table 3.9: TRANSPOSITION
74. ^ Roger Hui. dyadic transpose, a personal history. 22 May 2020 [2022-08-08]. （原始内容存档于2022-08-08）. Dyadic transpose, x⍉y, is probably one of the last primitives to be mastered for an APLer, but is actually straightforward to describe.
75. ^ IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. If P is any permutation of the indices of the axes of an array A, then P⍉A is an array similar to A except that the axes are permuted: the Ith axis becomes the P[I]th axis of the result. Hence, if R←P⍉A, then (⍴R)[P] is equal to ⍴A. For example:
A←2 3 5 7⍴⍳210
⍴A
2 3 5 7
P←2 3 4 1
⍴P⍉A
7 2 3 5
……
The monadic transpose ⍉A reverses the order of the axes of its argument. Formally, ⍉A is equivalent to (⌽⍳⍴⍴A)⍉A.

上面的APL转置⍉运算规定中，不将多个轴映射到结果中的一个轴的简单示例，所对应的J语言代码：
   transpose=: {{(/: x) |: y}}
a=: >:i. 2 3 5 7
$a 2 3 5 7 p=: 2 3 4 1$ p transpose a
7 2 3 5

76. ^ Kenneth E. Iverson. Operators and Functions. 1978 [2022-06-21]. （原始内容存档于2022-06-24）. The use of the indexing function will be illustrated in a proof of the useful identity i⍉j⍉a ↔ i[j]⍉a. We first state the definition of the transpose as follows: if k is any vector index of j⍉a then
k⌷j⍉a ↔ k[j]⌷a
Then:
k⌷i⍉j⍉a
k[i]⌷j⍉a
(k[i])[j]⌷a
k[i[j]]⌷a
k⌷i[j]⍉a

Kenneth E. Iverson的上述二元转置定义，用J语言写为(<k){j|:a(<(/:j){k){a，而恒等式i|:j|:a(i{j)|:a的推导过程相应如下：
   (<k){i|:j|:a
(<(/:i){k){j|:a
(<(/:j){(/:i){k){a
(<k){(/:(/:j){(/:i))|:a
(<k){(i{j)|:a

77. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. Well, we don’t know what Ken Iverson’s favorite APL expression was or if he even had a favorite APL expression. But we can guess. From A History of APL in 50 Functions [Hui 2016a, §8]:
⊢ x←,1
1
⊢ x←(0,x)+(x,0)
1 1
⊢ x←(0,x)+(x,0)
1 2 1
⊢ x←(0,x)+(x,0)
1 3 3 1
The expression (0,x)+(x,0) or its commute, which generates the next set of binomial coefficients, …….
78. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. What is being indexed is an array (of course) but the indices themselves (the “subscripts”) can also be arrays. For example [Hui 2016a, §4]:
x← 3 1 4 1 5 9
'.⎕'[x∘.>⍳⌈⌿x]
……
In the example, the 2-element character vector '.⎕' is indexed by a 6-by-9 Boolean matrix.
79. ^ IBM. APL Language (PDF). June 1976 [2022-07-02]. （原始内容存档 (PDF)于2019-09-26）. More generally, Q⍉A is a valid expression if Q is any vector equal in length to the rank of A which is "complete" in the sense that if its items include any integer N they also include all positive integers less then N. For example, if ⍴⍴A is 3, then 1 1 2 and 2 1 1 and 1 1 1 are suitable values for Q but 1 3 1 is not. Just as for the case P⍉A where P is a permutation, the Ith axis becomes the Q[I]th axis of Q⍉A. However, in this case two or more of the axes of A may map into a single axis of the result, thus producing a diagonal section of A as illustrated below:
……
B←3 5⍴⍳15
B
1  2  3  4  5
6  7  8  9 10
11 12 13 14 15
1 1⍉B
1 7 13
80. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. Quicksort works by choosing a “pivot” at random among the major cells, then catenating the sorted major cells which strictly precede the pivot, the major cells equal to the pivot, and the sorted major cells which strictly follow the pivot, as determined by a comparison function ⍺⍺. Defined as an operator Q:
Q←{1≥≢⍵:⍵ ⋄ s←⍵ ⍺⍺ ⍵⌷⍨?≢⍵ ⋄ (∇ ⍵⌿⍨0>s)⍪(⍵⌿⍨0=s)⍪(∇ ⍵⌿⍨0<s)}
……
The above formulation is not new; see for example Figure 3.7 of the classic The Design and Analysis of Computer Algorithms [Aho et al. 1974]. However, unlike the pidgin ALGOL program in Figure 3.7, Q is executable, and the partial order used in the sorting is an operand, the (×-) and cmp¨ and cmp⍤1 in the examples above.
81. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. Monadic ⍋ was originally defined only on numeric vectors, and was extended [Wooster 1980] to work on numeric arrays with higher rank. With that extension it has the distinction of being the first APL primitive function defined to work on major cells, before the term was invented or the importance of the concept realized. It was later extended to work on character arrays in Dyalog APL in 1982. More recently, ⍋ was extended in J to work with a TAO (total array ordering) [Hui 1996] on a suggestion by Whitney. TAO was taken up by Dyalog APL in 2018 [Brudzewsky et al. 2018]. The TAO also extends the left domain of ⍸. (The expression above for getting grade from sort requires TAO.)
82. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. Generate the sorted matrix of all permutations of ⍳⍵[Hui 2016a, §19; McDonnell 2003; Hui 2015b]. …… perm ⍵ obtains by indexing each row of the matrix ⍒⍤1 ∘.=⍨ ⍳⍵ by 0,1+perm ⍵-1. …… Putting it all together:
perm ← {0=⍵:1 0⍴0 ⋄ ((!⍵),⍵)⍴(⊂0,1+∇ ¯1+⍵)⌷⍤1 ⍒⍤1 ∘.=⍨ ⍳⍵}
83. ^ A History of APL in 50 Functions － 19. Permutations. [2022-09-27]. （原始内容存档于2022-09-27）.
84. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. An example of John Conway’s Game of Life [Gardner 1970] is obligatory with this operator. life below is due to Jay Foad, translated from an algorithm in k by Whitney [Hui 2017c]. It applies the rules of the Game of Life to the universe to create the next generation.
life ← {3=s-⍵∧4=s←{+⌿,⍵}⌺3 3⊢⍵}
⊢ glider←5 5⍴0 0 1 0 0 1 0 1 0 0 0 1 1,12⍴0
……
{'.⍟'[⍵]}¨ (⍳8) {life⍣⍺⊢⍵}¨ ⊂glider
……
In life, the derived function {+⌿,⍵}⌺3 3 computes the sum of each 3-by-3 square, moving by 1 in each dimension. The function {'.⍟'[⍵]} produces a compact display for a Boolean array.
85. ^ Stencil Lives. Jay Foad offers another stencil life, translating an algorithm in k by Arthur Whitney:
life3 ← {3=s-⍵∧4=s←{+/,⍵}⌺3 3⊢⍵} ⍝ Jay Foad
……
The algorithm combines the life rules into a single expression, wherein s←{+/,⍵}⌺3 3 ⊢⍵
(0) for 0-cells s is the number of neighbors; and
(1) for 1-cells s is the number of neighbors plus 1, and the plus 1 only matters if s is 4.
86. ^ J implementation of Fold primitives. [2022-11-01]. （原始内容存档于2022-11-01）.
87. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020 [2022-06-20]. （原始内容存档于2022-07-10）. Key is a monadic operator. In the dyadic case of the derived function ⍺ f⌸ ⍵, major cells of ⍺ specify keys for the corresponding major cells of ⍵, and f is applied to each unique key in ⍺ and the selection of cells in ⍵ having that key. In the monadic case of the derived function, f⌸⍵ ↔ ⍵ f⌸ ⍳≢⍵: f is applied to each unique key in ⍵ and the indices in ⍵ of that key.
Key was defined and implemented in J in 1989 or 1990 [Hui 2007] and in Dyalog APL in 2015 [Dyalog 2015; Hui 2020b]. It is motivated by the “generalized beta” operation in The Connection Machine [Hillis 1985, §2.6], but generalizes the generalized beta by accepting arrays of any rank, not just vectors, and by permitting any function, not just reductions (folds). Key is also cognate with the GROUP BY statement in SQL. ……
The following snippet solves a “Programming Pearls” puzzle [Bentley 1983]: given a dictionary of English words, here represented as the character matrix a, find all sets of anagrams. ……he algorithm works by sorting the rows individually (note the use of the rank operator ⍤(§3.1)), and these sorted rows are used as keys (“signatures” in the Programming Pearls description) to group the rows of the matrix. As the anagram example illustrates, other APL functions can be used to create the requisite keys.
88. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. Generate ⍵ random numbers selected from ⍳≢⍺ according to the weights ⍺, a vector of positive real numbers [Hui 2017d]. For example, if a←7 5 6 4 7 2 0.4 are the weights, then in a ran 1e6 the number 0 should occur roughly as often as 4(both with a weight of 7) and 3.5 times as often as 5(with a weight of 2).
ran ← {(0⍪+⍀⍺÷+⌿⍺)⍸?⍵⍴0}
……
The technique can be used to generate random numbers according to a probability distribution [Abramowitz and Stegun 1964, §26.8]. If a discrete distribution with values v and probabilities p, then v[p ran ⍵]. If a continuous distribution, convert it into a discrete one by dividing (¯∞,∞) into an appropriate number of intervals. The interval midpoints are the values; the probabilities are the differences of the cumulative distribution function at the interval end points.
The problem was solved in 1975 [IPSA 1975]; the current solution uses to advantage the extension of ?0 to generate a random number drawn uniformly from the open interval (0, 1) (suggested by Whitney) and the interval index function ⍸(§2.3).
89. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. The following is an example of interval index ⍸ (§2.3) and ⌸ working together to illustrate the central limit theorem, that the sum of independent random variables converges to the normal distribution [Hui and Iverson 2004; Hui 2016b, §F].
t←¯1+{≢⍵}⌸(⍳51),(4×⍳50)⍸+⌿?10 1e6⍴21
……
t counts the number of occurrences for interval endpoints 4×⍳50, of 1e6 samples from the sum of ten repetitions of uniform random selection of the integers from 0 to 20. A barchart of t:
.⎕'[(6e3×⊖⍳⌈(⌈/t)÷6e3)∘.≤t]
……
The derived function {≢⍵}⌸x counts the number of occurrences of each unique cell of x. The Dyalog APL and J implementations recognize particular useful operands for key, for example {≢⍵} and {f⌿⍵}, and implement those cases with special code (§9.3) for better performance.
90. ^ Sqlite enhanced API for J. [2022-10-20]. （原始内容存档于2022-10-22）.