本页使用了标题或全文手工转换

J语言

维基百科,自由的百科全书
跳到导航 跳到搜索
J
编程范型阵列隐式函数级函数式
設計者Kenneth E. Iverson許國華英语Roger Hui
實作者JSoftware
发行时间1990年,​32年前​(1990[1]
穩定版本
J903-release-b
(2022年1月28日,​4個月前​(2022-01-28[2]
型態系統动态类型
作業系統跨平台: Windows, Linux, macOS
許可證GPLv3
網站www.jsoftware.com
主要實作產品
J
啟發語言
APL
影響語言
Dyalog APL, NARS2000, I, BQN, Jelly, SuperCollider[3], Octave[4], NumPy[5]

J语言,是一种阵列编程语言,由肯尼斯·艾佛森許國華英语Roger Hui於1990年代初發明,是APL語言的一种方言[6][7]。J语言非常簡潔和強力,在數學统计学程式設計上十分有效,特別是在需要进行矩陣运算的场合。

简介[编辑]

Ken Iverson(右)和Roger Hui在1996年的照片
Ken Iverson(右)和Roger Hui在1996年的照片

最初起步于Kenneth E. Iverson在1987年发表的《APL字典》[8],J语言提供隐式定义特别是、叉子(fork)和函数复合英语function composition (computer science)[9],和作为头等对象动名词(gerund),并用以建立控制结构[10],它常被作为隱式編程的典范[11]

為了避免APL使用特殊的字符而遇到的問題,J语言只需基本的ASCII字符集,但使用点号.和冒号:作为“屈折[12]。点号和冒号除了前导着空白字符英语Whitespace character的情况之外,都与紧前字符形成类似双字符组的短字。多数“基础”或“原始”的J单字,都充当数学符号,通过点号或冒号来扩展这些可用基本字符的含义。在其他语言中经常是成对的很多字符,比如[] {} "" `` <>,在J语言中被当作单独的字,或者在有屈折的时候,作为多字符字的单字符字根

J语言的算符,没有优先级并且最右先行,2 * 3 + 4的结果是14。历史上,APL使用/来指示fold函数,所以+/1 2 3等价于1 + 2 + 3。在APL中,除法被表示为数学除号÷,它将减号和冒号一起重复打印英语overstrikeEBCDICASCII二者的纸质文本终端上。J语言使用%表示除法,作为一种可见的近似或提示。

J语言承袭最初于1968年推出的IBM APL\360采用了平坦阵列模型,不支持由NARS(嵌套阵列研究系统)于1981年介入的嵌套阵列模型[13],它被IBM APL2采纳[14];J语言增加了Kenneth E. Iverson于1978年在《运算符和函数》中提出的盒装数据类型[15],它由SHARP APL于1981年在其技术说明SATN-41中介入,并于1983年在I.P. Sharp协会研究报告《理性化APL》中,列入与APL2相比较的限定子集(RS)而著重强调[16]

是J语言中至关重要的概念[17]。J语言不再支持APL\360的方括号索引,转而支持Kenneth E. Iverson在《运算符和函数》中提出的“依据”(from)索引[18],它也被称为“班组”(squad)索引。J语言支持AVX2指令集进行SIMD运算[19]

不同于支持面向对象编程的多数语言,J语言灵活的层次名字空间机制,这里所有名字都存在于特定语境(locale)中,可以有效的用作基于类基于原型的面向对象编程二者的框架。它还被用于极限编程[20]网络性能分析[21]

自从2011年3月,J语言成为了自由和开源软件,采用了GNU通用公共许可证版本3(GPLv3)[22][23]。人们还可以在Jsoftware的商业许可证下利用源代码[24]

词类与文档[编辑]

在J语言中的字,被识别为名词[25]动词[26]定语[27]副词连词)、系词标点符号控制字。一个程序或例程,有时接受数据作为输入并产生数据作为输出,被称为“动词”,与之相对,数据参数被称为“名词”。

J语言有一组丰富的预定义的动词,它们都自动的起作用于多种数据类型之上。用户的程序可以命名,并可以用在任何允许使用原语的地方。注意动词有两种形式:参数只在右侧的一元(monad)形式,和参数在左右两侧的二元(dyad)形式。例如,在-1中横杠是一元动词,而在3-2中横杠是二元动词。一元定义很大程度上独立于二元定义,不管这个动词是原语动词还是派生动词。

J语言的文档包括于NuVoc中[28]。主要的字罗列于“J原语”中,其中使用颜色标示出它们分别的词类[29]。早期的文档还有入门[30]和字典[31]

起步示例[编辑]

J语言的程序可以非常精简,以至于一些编程者将它称为难以阅读的只写语言。在计算机的终端上执行ijconsole,即可进入J语言的REPL解释器界面。

Hello, World![编辑]

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

   'Hello, world!'

这个hello world的实现反映了J语言的传统用法,就是把程序录入到J解释器会话中,显示出表达式结果。还可以准备J脚本来作为独立程序来执行。下面是在Linux系统上的样子:

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

平均[编辑]

在J语言中函数一般称为动词,例如定义一个叫做avg的动词,计算一序列数的平均

   avg=: +/ % #
   avg 1 2 3 4
2.5

一元动词#“计数”(tally),总计阵列中项目的总个数。动词+“加”(plus)和副词/“插入”(insert),派生出的动词+/,合计这个阵列的项目的总和。二元动词%“除”(divide)将这个总和除以这个总个数。上述的avg使用一连串的三个动词(+/%#)来定义,术语叫“叉子”(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
   ]b=: ?. 4 5 $50  NB. 产生50以内20个随机整数的一个矩阵
44  6  8  6 35
48 16 46 26  9
33 22 13  1 39
 2 17 20  9 15
   avg b
31.75 15.25 21.75 10.5 24.5
   avg"1 b          NB. 应用avg于m的每个秩为1的子阵列
19.8 29 21.6 12.6

一元动词]“相同”(same),恒等于给它的单一右参数,常像这样用来在赋值之后显示变量的内容。计算移动平均用到的二元副词\“中缀”(infix),将作为数据参数的列表划分成一系列的指定大小的连续项目的子列表,将所修饰动词应用于其上,并将这些结果形成一个列表。

一元动词?.“掷骰/固定种子”(roll/fixed seed),以固定的种子,生成数据参数项目所指定大小范围内的随机数。这里用到的连词"“秩”(rank),在后面的定语章节单独条目中论述。

查找与排序[编辑]

二元动词i.“出现索引”(index of),和二元动词i:“最后出现索引”(index of last),在任何大小的阵列内查找匹配者,并返回它的位置索引,如果未找到匹配者,则返回这个阵列的大小。例如:

   a=: 3 1 4 1 5 9
   a i. 1 2  NB. 找到1和2的第一次出现的索引
1 6
   a i: 1 2  NB. 找到1和2的最后一次出现的索引
3 6

在J语言中,排序可以按APL传统的两步骤方式,使用一元动词/:“升级”(grade up)或\:“降级”(grade down),二元动词{“依据索引”(from),和一元动词]“相同”(same),三者形成的一个叉子来完成。J语言还提供专用的二元动词/:“上升排序”(sort up)或\:“下降排序”(sort down)。下面是用例:

   a=: 15 2 9 10 4 0 13 13 18 7
   /: a        NB. 产生能将参数阵列升序排序的置换向量
5 1 4 9 2 3 6 7 0 8
   (/: { ]) a  NB. 依据置换向量的索引选择参数阵列的项目
0 2 4 7 9 10 13 13 15 18
   /:~ a
0 2 4 7 9 10 13 13 15 18
   (a - 10) /: a
_10 _8 _6 _3 _1 0 3 3 5 8

这里用到的一元副词~“反身”(reflex),在后面定语章节介绍。

插件[编辑]

除了使用标准库[32],还可以通过包管理器[33],安装各种插件[34],例如在管理员权限下,安装CSV文件插件[35]

   load 'pacman'                NB. 加载包管理器
   'install' jpkg 'tables/csv'  NB. 安装CSV文件插件
   'showinstalled' jpkg ''      NB. 查看已经安装插件

下面是CSV文件简单用例:

   load 'tables/csv'                  NB. 加载CSV插件
   a=: i. 2 3                 
   a writecsv jpath '~/test01.csv'    NB. 将一个阵列写入一个CSV文件
12
   ]b=: readcsv jpath '~/test01.csv'  NB. 从一个CSV文件读入一个盒子阵列
┌─┬─┬─┐
012
├─┼─┼─┤
345
└─┴─┴─┘
   ]c=: makenum b                     NB. 尽可能的将盒子阵列转换成数值阵列
0 1 2
3 4 5

数据类型和结构[编辑]

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

  • 数值
  • 文字(字符)
  • 盒装

其中数值有很多变种。J语言提供的唯一搜集(collection)类型,是任意维度的阵列。多数算法可以使用这些阵列来简洁的表达。

数值[编辑]

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

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

其他数值类型包括整数(比如3, 42)、浮点数(3.14, 8.8e22)、複數(0j1, 2.5j3e88)、扩展精度整数(12345678901234567890x)和(扩展精度)有理分数(1r2, 3r4)。同位一样,它们可以形成列表或任意维度的阵列。同位一样,运算可以在一个阵列的所有数之上。下面例子展示π的前50位,超出了IEEE 754双精度浮点数的53位二进制尾数能精确表示的最大范围,这要用到J语言的扩展精度整数:

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

这里采用一元动词o.“π乘以”(pi times),和一元动词<.“下取整”(floor)二者的复合,得到预期的结果[36]。位的列表可以使用一元动词#.“基数2”(base 2)解码成整数。整数可以使用一元动词#:“反基数2”(antibase 2)编码为位的列表。

文字与盒装[编辑]

J语言还支持文字即字符类型。文字包围在引号之间,比如'a''b'。文字的列表,通过将多个字符放入引号之内的常规字符串约定来支持,比如'abcdefg'。典型的,单独的文字是8-位宽(字节)的ASCII字符,但是J语言还支持其他Unicode文字。

不支持在文字上的数值和布尔运算,但支持面向搜集的运算,比如旋转等。使用动词".“执行·数值”(do·numbers),将字节阵列转换成数值;使用动词":“缺省格式·格式”(default format·format),将数值转换成字节阵列。

盒装类型的值是0维标量[15],而不管所包含的是怎样的数据结构。使用一元动词<“盒装”(box),将数据放置入盒子中;使用一元动词>“打开”(open),打开盒子中取出其中数据。还可以通过二元动词;“链接”(link)建立盒子的列表,通过一元动词;“拆除”(raze)移除一层盒子的列表。盒子内可以装入其他盒子,还可以通过二元动词$“重制形状”(reshape)和二元动词#“计件复制”(copy)等操作盒子及其列表。

结构[编辑]

J语言的阵列,具有同质(homogeneous)的项目类型,例如列表1 2 3是整数的列表,尽管1可以是一个位。在极大程度上,这种的类型问题,对于编程者是透明的。只有特定的特殊运算,显露出在类型上的不同。例如,列表1.0 0.0 1.0 0.0,对大多数运算,将被当作是完全同于列表1 0 1 0

J语言支持数值稀疏阵列,这里用它们的下标存储非零数值。这在非零数值相对很少的情况下,是有效率的机制。

J语言还支持对象[37],但是它们是事物命名方式的加工制作,而非数据类型。实际上,使用盒装文字来提及对象和类。J数据有值语义,然而对象和类需要引用语义。

此外还有一个伪类型即内存映射文件[38],它关联于名字而非数值。

基本词汇[编辑]

下表列出了基本词汇,使用@&`及其屈折形式的连词,对于隐式编程有重大意义,在后面的章节中专门论述。如果含义中用了间隔号( · )分隔,通常前者是只有一个右侧参数的一元含义,后者是左右两侧都有参数的二元含义。

J词汇 APL
符号
词类 含义 例子
基本 =. 系词 是(is,局部赋值) loc=. 1 2
=: 系词 是(is,全局赋值) GLO=: 'foo'
NB. 系词 注释(comment) NB. negative vs. negate
'文字' 名词 字符串(character string) 'Hello, World!'
_ ¯ 名词 负号(negative sign)/ 无穷(infinity) _3 = -3
= 动词 等于(equal) 3 = i. 5
< < 动词 (二元)小于(lesser) 8 < 7 8 9
动词 (一元)盒装(box) < 'abc'
> > 动词 (二元)大于(greater) 8 > 7 8 9
  动词 (一元)打开(open) > < 'abc'
[ 动词 相同(same)· 左参数(left) p=: 3 [ q=: 5
] 动词 相同(same)· 右参数(right) (2 { ]) 3 1 4 1 5 9
~ 副词 返身(reflex)· 被动(passive) +~ 1 2 3
" 连词 秩(rank) +/"1 i. 3 4
". 动词 执行(do)· 数值(numbers) 9999 ". '56 NULL'
": 动词 缺省格式(default format)· 格式(format) 10j2 ": 6
^: 连词 动词幂(power of verb) +: ^:(6&<) 12
: 连词 定义(definition) myverb =: 3 : 'Jcode(y)'
$: 动词 自引用(self-reference) fac=: 1: ` (* $:@<:) @. *
阵列 $ 动词 形状(shape of)· 重制形状(reshape) 2 2 4 $ 1 2 11 22
# 动词 (一元)计数(tally) # 1 2 3
 / 动词 (二元)复制(copy) 1 2 3 # 1 2 3
#. 动词 基数2(base 2)· 基数(base) #. 1 0 1 0 1
#: 动词 反基数2(antibase 2)· 反基数(antibase) 24 60 60 #: 86399
L. 动词 最大盒装层数(level of) L. (<,1),(<<,2),(<<<,3)
|.   动词 反转(reverse)· 旋转(rotate) |. 2 |. i. 6 2
|: 动词 转置(transpose)· 重排轴(rearrange axes) |: 'abc' ,: 'def'
; 动词 拆除(raze)· 链接(link) ; (i. 2 3) ; i. 3 2
;.3 副词 极大立方体(max cubes)· 剪切子阵列(subarrays) (2 2 ,: 2 4) <;.3 i. 5 6
, , 动词 (一元)散开(ravel) , i. 2 3 4
动词 (二元)附加(append) (i. 2 3) , i. 4 3
,. 动词 (一元)散开项目(ravel items) ,. i. 2 3 4
, 动词 (二元)缝合(stitch) (i. 2 3) ,. i. 2 4
,: 动词 项目化扩秩(itemize)· 迭片(laminate) (i. 2 3) ,: i. 3 2
/ ∘. 副词 (二元)表格(table) */~ >: i. 6
 / 副词 (一元)插入(insert) +/ 1 10 100
\ 副词 (二元)中缀(infix) 3 <\ 'abcdefg'
 \ 副词 (一元)前缀英语Prefix sum(prefix) ]\ 'banana'
\. 副词 后缀(suffix)· 外缀(outfix) _1 ]\. 1 2 3 4
/. 副词 斜对角(oblique)· 键分组英语Group by (SQL)(key) 1 0 0 1 0 </. AbcDe'
/: 动词 升级(grade up)· 上升排序(sort up) (/: { ]) 10 ? 20
\: 动词 降级(grade down)· 下降排序(sort down) \:~ 10 ? 20
{ 动词 组合盒子目录(catalogue)· 依据索引(from) 2 4 { 'abcde'
} @ 副词 合成项目(composite item)· 修改(amend) 'gw' (0 3)} 'cross'
{. 动词 头部(head)· 选取(take) 3 {. 'foot'
}. 动词 掐头(behead)· 舍弃(drop) 2 }. 1 2 3 4
e. 动词 拆盒值隶属矩阵(raze in)· 成员关系(member/in) 'a' e. 'alpha'
E. 动词 寻找匹配子阵列起点(find match) 'co' E. 'cocoa'
i. 动词 整数生成(integers)· 出现索引(index of) i. 10
I. 动词 存有索引(indices)· 区间索引(interval index) I. 0 0 1 0 1 0
数学 + 动词 共轭复数(conjugate)· (plus) 2 + 3 30
+. 动词 实部/虚部(real/imaginary)· 最大公约/(GCD/or) 0 0 1 1 +. 0 1 0 1
+: 动词 双倍(double)· 或非(not-or) 0 0 1 1 +: 0 1 0 1
* × 动词 符号函数(signum)· (times) 3 30 * 2
*. 动词 模长/幅角(length/angle)· 最小公倍/(LCM/and) 0 0 1 1 *. 0 1 0 1
*: 动词 平方(square)· 与非(not-and) 0 0 1 1 *: 0 1 0 1
- 动词 相反数(negate)· (subtract) 1 10 - 5 6
-. 动词 (not)· (less) -. 0 1
-: 动词 一半(halve)· 匹配(match) 'no' -: 'yes'
% ÷ 动词 倒数(reciprocal)· (divide) 2 3 5 % 3 4 6
%. 动词 逆矩阵(matrix inverse)· 矩阵除(matrix divide) %. ? 3 3 $ 10
| 动词 幅值(magnitude)· 余数(residue) 2 | i. 7
^ 动词 指数(exponential)· (power) 2 ^ i. 17
^. 动词 自然对数(natural log)· 对数(log) 2 10 ^. 4 100
o. 动词 π乘以(pi times)· 圆函数(circle function) sin=: 1&o.
<. 动词 下取整(floor)· 极小(minimum) 2 3 4 <. 99 1 2
>. 动词 上取整(ceiling)· 极大(maximum) >. 1.1 0.5 1.9
<: 动词 增加(decrement)· 小于等于(less or equal) 8 <: 7 8 9
>: 动词 减少(increment)· 大于等于(larger or equal) >: 7 8 9
~: 动词 唯一值筛选(nub sieve)· 不等于(not-equal) 3 ~: i. 5
! 动词 阶乘(factorial)· 抽取(out of) 2 ! 10
? 动词 掷骰(roll)· 发牌英语Random permutation(deal) 3 ? 10
. 连词 行列式(determinant)· 矩阵积(matrix product) (i. 3 2) (+/ . *) i. 2 3

定语[编辑]

J语言的能力,很大程度上来自它的“定语”(modifier:修饰词),这个范畴包括“副词”和“连词”:这些符号接受名词和动词作为运算元(operand),并以指定方式应用这些运算元。定语都可以应用于任何动词,包括用户写的动词,用户可以写自己的定语。

一元副词/“插入”(insert),接受位于它左侧的一个运算元,并产生将这个动词应用于其参数的每个项目之间的一个动词。就是说,+/是一个动词,定义为应用+于给它的参数的各个项目之间。副词\“前缀·中缀”(prefix·infix),副词\.“后缀·外缀”(suffix·outfix),和连词;.“剪切”(cut)[39],指定参数的诸个规则或不规则子集,并在其上执行运算。

采用连词"“秩”(rank)来操纵[40],它有三种形式:u"n“指定秩”(assign),m"n“常量动词”(constant),u"vm"v“复制秩”(copy),这里的u表示定语的动词运算元,而m表示定语的名词运算元。

复合[编辑]

连词@:“在于”(at)、@“顶上”(atop)、&:“并列”(appose)、&“合成”(compose),是四种复合(composition)。J语言支持叫作“钩子”(hook)和“叉子”(fork)的隐形连词[41],二种隐形连词和四种复合连词,规定了如何将参数或将所饰动词应用于参数的结果,提供给所饰动词来进行应用的规则。下表列出它们的含义:

连词 APL
符号
一元 二元
hook (u v) y = y u (v y) x (u v) y = x u (v y) _ _ _
fork (f g h) y = (f y) g (h y) x (f g h) y = (x f y) g (x h y) _ _ _
@: (u @: v) y = u (v y) x (u @: v) y = u (x v y) _ _ _
@ (u @ v) y = (u @: v)"v y x (u @ v) y = x (u @: v)"v y mv lv rv
&: 同于@:故而弃用 x (u &: v) y = (v x) u (v y) _ _ _
& 同于@故而弃用 x (u & v) y = x (u &: v)"mv y mv mv mv

在上表中,mv=: 0{g b.0lv=: 1{g b.0rv=: 2{g b.0,这里的g b.0给出动词g的一个一元秩和两个二元秩[42]。复合连词@:&:对应的APL符号,是Dyalog等现代APL所采用的符号。@&分别对应于《APL字典》中的符号[43],hook对应于《APL字典》中的符号“枝条”(withe)[44]。现代APL将称为“atop”,称为“over”;并增加了“边上”(beside)[45]的一元形式同于,而二元形式同于hook。

四种复合中,@:&:,对第一步运算的中间结果进行收集和填充[46];而@&,在中间结果的诸单元上进行第二步运算。四种复合的运作机制,可详见官方文档的图示[47],下面例子展示四种复合的中间结果的单元差异:

   ] a =: >:i. 2 3
1 2 3
4 5 6
   ] b =: 0.1*>:i. 2
0.1 0.2
   a (< @: +) b
┌───────────┐
1.1 2.1 3.1
4.2 5.2 6.2
└───────────┘
   a (< @ +) b
┌───┬───┬───┐
1.12.13.1
├───┼───┼───┤
4.25.26.2
└───┴───┴───┘
   a (; &: +:) b
┌───────┬───────┐
2  4  60.2 0.4
8 10 12       
└───────┴───────┘
   a (; & +:) b
┌──┬───┐
2 0.2
├──┼───┤
4 0.2
├──┼───┤
6 0.2
└──┴───┘

┌──┬───┐
8 0.4
├──┼───┤
100.4
├──┼───┤
120.4
└──┴───┘

当连词&的一个运算元是名词的时候,表示“粘上”(bond),对应于APL符号“绑上”(bind),即通过向二元动词固定提供其一个参数的值,而产生一个一元动词,如果存在左参数,它表示应用这个派生动词于右参数的次数。副词~“反身·被动”(reflex·passive),将提供给动词的单一右参数重复放置在左参数位置上,或者将提供给动词的左右两个参数对换位置。下面是简单的示例[48]

   norm=: %: @ +/ @: *: "1
   norm >:i. 2 2
2.23607 5
   x=: 3 1 4 1 5 9
   { &('.',u:9109) (>/ i. @ (>./)) x
⎕⎕⎕......
........
⎕⎕⎕⎕.....
........
⎕⎕⎕⎕⎕....
⎕⎕⎕⎕⎕⎕⎕⎕⎕

在J语言中,孤立的动词序列叫做“列车”(train)[11]e f g h意味着(e (f g h))d e f g h意味着(d e (f g h)),而c d e f g h意味着(c (d e (f g h)));以此类推,动词列车的一般模式(a b c ...),依赖于动词的数目,在偶数时形式为(a (b c ...)),最外层是个“钩子”(hook);而在奇数时形式为(a b (c ...)),最外层是个“叉子”(fork);二者的内部都是可能有多层的嵌套的叉子。

在钩子里处在前面的,和在叉子里处在中间的第二步运算,都应是二元动词;在惯用法([: g h)[49],并不实际执行的隐式动词[:“遮帽”(cap),屏蔽了叉子的左分支,形成了特殊化的叉子,这种叉子里处在中间的第二步运算,应是一元动词。

J语言还提供连词&.:“底下”(under)和&.“对偶”(dual)。&.:的秩是_ _ _,对应的APL符号是[50]u &.: v相同于v^:_1 @: (u &: v)&.的秩是mv mv mv,对应于《APL字典》中的符号¨[51]u &. v相同于(u &.: v)"mv,而动词幂^:_1表示逆运算,详见下面章节的介绍。现代APL中另有¨“每个”(each),相当于J语言中的f &. >[52]

控制结构[编辑]

连词^:动词幂”(power of verb)[53],有两种形式:

  • ^:n,是操作元为名词的“固定幂”。
  • ^:v,是操作元为动词的“动态幂”。

对于固定幂x u ^:n y,分别在x存在或缺席的情况下,应用动词x&uuyn次。如果n01,则形成布尔值条件执行;如果n_1,则进行u逆运算;如果n_,则意味着“收敛”,即反复应用u直到结果不再变化。例如:

   flag=: 1
   'Mr. ' , ^:flag 'Jones'
Mr. Jones
   flag=: 0
   'Mr. ' , ^:flag 'Jones'
Jones
   (+: ^:_1) 14 
7

对于动态幂x u ^:v y,如果x存在,(x u ^:v y)应用动词x&uy(x v y)次;如果x缺席,(u ^:v y)应用动词uy(v y)次。动词幂可以形成动态条件执行,这里的动词v必须总是产生布尔值结果,应用动词u当且仅当v返回1。进而(u ^:v ^:_ y)可以形成while-do构造,只要v返回1,就反复的执行u,直到v返回0,或者u将它的参数无变化的返回。例如:

   (+: ^:(6&<) "0) 0 3 6 12      NB. 只对大于6的列表项目乘以2
0 3 6 24
   (3&* ^:(100&>) ^:_ "0) 5 100  NB. 重复的三倍y,只要它小于100
135 100

在J语言中,动名词(gerund)是叫做“原子表示”(atomic representation)的特殊盒子的一个列表,这种盒子可以像任何其他盒子一样使用,并可以最终转变回到要执行的动词。基于动名词的运算有:

  • 连词`“连结成动名词”(tie or gerund),建立动名词。
  • 连词`:“唤起动名词”(evoke gerund),在加以运算元之后成为:
    • `:6,将动名词转变成动词列车;
    • `:0,将转变回来的这些动词分别单独应用,并将它们的结果收集入一个列表。
  • 连词@.“议程”(agenda),m @. n从动名词m中,选择出第n个原子表示,将它转变回到动词并执行它。

下面举例说明:

   grd =: * ` (+&2)  NB. 建立一个动名词
   grd               NB. 显示原子表示,这里的符号'0'标识名词
┌─┬─────────────┐
*│┌─┬─────────┐│
 ││&│┌─┬─────┐││
 ││ ││+│┌─┬─┐│││
 ││ ││ ││02││││
 ││ ││ │└─┴─┘│││
 ││ │└─┴─────┘││
 │└─┴─────────┘│
└─┴─────────────┘
   grd `:6          NB. 将动名词转变回动词
* +&2
   (grd `:6) 2 3    NB. 实际运行这个动词
8 15
   (+: ` *:) `:0 i. 3
0 2 4
0 1 4
   ((%&2) ` (+&3) @. (2&|) "0) 5 6 7 8
8 3 10 4

定义[编辑]

J语言支持用户进行显式定义。以五种复合的定义为例:

   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)'

在显式定义中提供了类似其他过程语言的控制结构[54]。这里列出的是每个范畴内的代表性控制字:

范畴 控制结构
断言触发 assert.
返结果退出 return.
跳转到标号 goto_label. label_lbl.
条件执行 if. T do. B else. B1 end.
情况执行 select. T case. T0 do. B0 end.
条件循环 while. T do. B end.
逐项执行 for. T do. B end.
终止循环 break.
终止本次迭代 continue.
尝试执行捕获异常 try. B catch. B1 end.
抛出异常 throw.

J语言还支持{{……}}形式的直接定义英语Direct function[55]

例子程序[编辑]

斐波那契数列[编辑]

下面的例子演示递归的计算斐波那契数列

   fibonacci=: 1: ` (fibonacci@(-&2) + fibonacci@<:) @. (>&2) "0

注意这里的1:是常量动词。下面的代码,不再通过名字引用动词,转而使用动词$:

   fibonacci=: 1: ` ($:@(-&2) + $:@<:) @. (>&2) "0

用例:

   fibonacci }.i.10
1 1 2 3 5 8 13 21 34

快速排序[编辑]

实现升序快速排序代码样例[56]

   cmp=: * @ -
   quicksort=: {{
     if. 1 >: #y do. y
     else.
       s=. (cmp ({~ ?@#)) y
       (quicksort (0 > s) # y) , ((0 = s) # y) , (quicksort (0 < s) # y) 
     end. }}

这里定义一个复合动词cmp,它通过逐个做两个数的差并取其符号,得到取值为_101平衡三进制值的一个列表。在quicksort动词定义中,首先向局部变量s赋值的表达式,是两层的钩子(hook)。

外层钩子的第一步随机选择支点(pivot)运算是嵌套的钩子,嵌套钩子的第一步运算?@#,生成在数据总个数范围内的随机数,它的第二步运算是对换了左右参数位置的二元动词{,它选择出在随机数指定的位置上的支点值。外层钩子的第二步运算,将二元动词cmp,应用到其左参数的数据列表,和右参数即嵌套钩子给出的支点值之上。在显式定义中可以不采用钩子,而写成更显然的:y cmp y {~?# y

随后是串接分治运算结果,在给递归调用的数据参数中,将平衡三进制值列表,分别与0做逐项的三分法比较,得到三个布尔值列表。然后以这种列表中的01作为件数,复制出数据列表的符合这个条件一个新的子列表。

下面的快速排序实现,展示了隐式编程[11],即将函数复合在一起,而不显式的引用任何变量,这里消隐了前面代码中的变量s

   cmp=: * @ -
   quicksort=: {{((($: @ #~ 0&>) , (#~ 0&=) , ($: @ #~ 0&<)) (u ({~ ?@#))) ^: (1<#)}}}
   cmp quicksort 15 2 9 10 4 0 13 13 18 7 
0 2 4 7 9 10 13 13 15 18

提供给连词^:的左侧运算元,最外层是个钩子,它将提供给它的单一右数据参数,重复放置在它的左数据参数位置上,所以这里的复制运算#,都对换了左右参数的位置。这里定义的quicksort是副词,把cmp的表达式代入定义中,就能得到前面那样的动词。

内存映射文件[编辑]

将J语言中的变量映射到文件系统中的持久文件,需要安装内存映射文件插件'data/jmf',下面是简单用例:

   load 'data/jmf'       NB. 加载插件
   ] V=: 2 2 $ 1 2 3 4   NB. 测试用阵列数值
1 2
3 4
   S=: 64000             NB. 文件大小(字节)
   F=: '~/persis.jmf'    NB. 文件路径及名字
   createjmf_jmf_ F ; S  NB. 建立并打开持久文件
   map_jmf_ 'P' ; F      NB. 映射变量至持久文件
   P=: V                 NB. 将测试内容赋值到P
   unmap_jmf_ 'P'        NB. 解除映射并关闭文件
0
   map_jmf_ 'Q' ; F      NB. 再次建立映射
   ] Q                   NB. 查看持久文件保存内容
1 2
3 4
   unmap_jmf_ 'Q'        NB. 再次解除映射
0

调试[编辑]

J语言拥有常规设施,可以停止在动词内错误或特定位置上。它还有一个唯一的可视调试器,叫做Dissect[57],给出一个单一的J句子执行的2-D交互显示。因为J语言的一个单一句子在低层语言中,是作为一个完整的子例程进行计算的,这个可视显示非常有用。

参见[编辑]

引用[编辑]

  1. ^ Roger K.W. Hui, Kenneth E. Iverson, E. E. McDonnell英语Eugene McDonnell, Arthur T. Whitney英语Arthur Whitney (computer scientist). APL\?. 1990. 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. ^ 903-release-b. [2022-04-28]. (原始内容存档于2022-04-28). 
  3. ^ SuperCollider documentation, Adverbs for Binary Operators. [2020-04-18]. (原始内容存档于2020-12-11). 
  4. ^ GNU Octave Manual, Broadcasting. 
  5. ^ NumPy fundamentals, Broadcasting. 
  6. ^ K. E. Iverson. A Personal View of APL. 1991. 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). 
  7. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. 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.
     
  8. ^ Kenneth E. Iverson. A Dictionary of APL. 1987. 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.
     
  9. ^ Roger K.W. Hui, Kenneth E. Iverson, Eugene E. McDonnell英语Eugene McDonnell. Tacit Definition. 1991. 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.
     
  10. ^ Robert Bernecky英语Robert Bernecky, Roger K. W. Hui. Gerunds and representations. 1991. 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. 
    Changes in Version 4.0, 1991 11 23. 1991.
    `:1 replaced by u^:v
    `:4 replaced by m~
    `:5 replaced by @.
     
  11. ^ 11.0 11.1 11.2 Tacit programming. Most dialects define a 2-train is an atop, equivalent to the function derived using the Atop operator. …… J instead defines the 2-train as a hook, equivalent to the function derived using the Withe operator. 
  12. ^ Vocabulary/Words. [2020-05-18]. (原始内容存档于2016-03-07). 
  13. ^ Bob Smith. Nested arrays, operators, and functions. 1981. 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.
     
  14. ^ James A. Brown英语Jim Brown (computer scientist). The Principles of APL2. TR 03.247. IBM Santa Teresa Laboratory, San Jose, California. 1984. 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. ……
    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.
     
  15. ^ 15.0 15.1 Kenneth E. Iverson. Operators and Functions. 1978. 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.
     
  16. ^ Kenneth E. Iverson. Rationalized APL. 1983. Heterogeneous Arrays. 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.
    Permissive Enclose. 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.
     
  17. ^ Kenneth E. Iverson. Operators and Functions. 1978. 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. 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).
     
  18. ^ Kenneth E. Iverson. Operators and Functions. 1978. 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).
     
    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. ^ Guides/AVX. [2021-12-20]. (原始内容存档于2021-12-20). 
  20. ^ 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 
  21. ^ Holt, Alan, Network Performance Analysis: Using the J Programming Language, Springer, 2007, ISBN 978-1-84628-822-7 
  22. ^ Jsoftware's source download page. [2020-05-18]. (原始内容存档于2021-01-26). 
  23. ^ Eric Iverson. J Source GPL. J programming mailing list. 1 March 2011 [2020-05-18]. (原始内容存档于2016-09-23). 
  24. ^ Jsoftware's sourcing policy. [2020-05-18]. (原始内容存档于2021-01-26). 
  25. ^ 名词页面存档备份,存于互联网档案馆
  26. ^ 动词页面存档备份,存于互联网档案馆
  27. ^ 定语页面存档备份,存于互联网档案馆
  28. ^ NuVoc页面存档备份,存于互联网档案馆
  29. ^ 词类页面存档备份,存于互联网档案馆
  30. ^ 入门页面存档备份,存于互联网档案馆
  31. ^ 字典页面存档备份,存于互联网档案馆
  32. ^ 标准库页面存档备份,存于互联网档案馆
  33. ^ 包管理器. [2020-05-22]. (原始内容存档于2021-04-06). 
  34. ^ 插件页面存档备份,存于互联网档案馆
  35. ^ Addons/tables/csv
    github.com/jsoftware/tables_csv
  36. ^ Roger K.W. Hui. Extended Integers in J. 1996. Some verbs v signal domain error on some extended arguments because the result is not integral; however, <.@v and >.@v are closed on extended arguments. 
  37. ^ Chapter 25: Object-Oriented Programming. [2020-05-18]. (原始内容存档于2020-06-25). 
  38. ^ 内存映射文件页面存档备份,存于互联网档案馆
  39. ^ 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{⍺. 
  40. ^ 页面存档备份,存于互联网档案馆
  41. ^ Iverson, Kenneth E. and Eugene McDonnell英语Eugene McDonnell, Phrasal Forms, APL 89 Conference Proceedings, August 1989, 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. ……
    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.
     
  42. ^ 动词信息
  43. ^ Kenneth E. Iverson. A Dictionary of APL. 1987.
    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 ⍵.
    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 ⍵
     
  44. ^ Kenneth E. Iverson. A Dictionary of APL. 1987. Withe (u⍩v) is similar to (u⍤v), but applies v only to the right argument:
    ⍺ u⍩v ⍵ ←→ ⍺ u v ⍵
      u⍩v ⍵ ←→ ⍵ u v ⍵
     
  45. ^ Function composition
  46. ^ 帧填充
  47. ^ 定语生成的动词的秩
  48. ^ Roger K. W. Hui, Morten J. Kromberg. APL since 1978. Proceedings of the ACM on Programming Languages, Volume 4, Issue HOPL. 2020. 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.
     
  49. ^ Tacit Expressions
  50. ^ Kenneth E. Iverson. Operators and Functions. 1978. 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.
     
  51. ^ Kenneth E. Iverson. A Dictionary of APL. 1987.
    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.
     
  52. ^ Kenneth E. Iverson. Operators and Functions. 1978. 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. 
  53. ^ Kenneth E. Iverson. Operators and Functions. 1978. 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. 
  54. ^ 控制结构
  55. ^ Kenneth E. Iverson. Formal Function Definition. Elementary Functions, IBM Corp. Chapter 10. 1974. This chapter concerns the scheme of formal function definition introduced in Section 1.3. …… It also extends the basic schemes to include recursive definition, a form of definition which makes it easy to handle the formal definitions such as the quotient of polynomials. 
    Kenneth E. Iverson. Rationalized APL. 1983. 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.
     
  56. ^ 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.
     
  57. ^ 剖析页面存档备份,存于互联网档案馆

外部連結[编辑]