用户:Lilin3035/APL语法与符号
编程语言APL的独特之处在于它的符号,而不是语法:它的原语由符号而不是单词表示。这些符号最初是作为描述算法的数学符号而设计的。[1]APL程序员在讨论函数和运算符时通常会指定非正式名称(例如,乘积代表 ×/),但该语言提供的核心函数和运算符由非ASCII的符号表示。
一元函数和二元函数
大多数符号表示函数或运算符,一元函数会将他右侧的所有元素的求值结果作为参数。(通过括号调整顺序)二元函数除此之外还将左侧的第一个数据当作参数。许多符号即是一元函数也是二元函数,只通过用途来进行区分。例如 ⌊3.2 得到 3,取小于参数的最大整数,而 3⌊2 得到 2,取两个参数中较小的参数。
函数和运算符
APL像亥维赛的方式一样使用运算符作为函数的调节器,而不像其他编程语言中使用的对数据进行操作的相同运算,参见[关系运算子|[关系运算符]]和算子。 //其他编程语言有时也会交换“术语”与函数的用法。然而,相关的术语在APL中使用的更确切。.[2][3][4][5][6]APL早期定义符号对其分类化分得非常具体。[7]例如,运算符reduce由正斜杠表示,并通过插入其函数操作数来沿一个轴缩减数组。reduce的一个示例:
×/2 3 4 24 |
<< 在APL中等价的结果 >> << Reduce 运算符 / 用在左边 |
2×3×4 24 |
在上述情况下,reduce运算符调节了乘法函数。表达式×/2 3 4通过乘法缩减了一个数组来计算标量(仅1个元素)的结果。上面的情况是简化的,想象一下,相乘(加、减或除)不仅仅是几个数字加在一起(在向量中,×/返回其所有元素的乘积。)
1 0 1\45 67 45 0 67 |
<< APL中相反的结果 >> << Expand二元函数\应用在左侧 Replicate二元函数/应用于右侧>> |
1 0 1/45 0 67 45 67 |
上面的二元函数示例[左右示例](使用相同的/符号,右侧示例)演示了布尔值(0s和1s)如何用作 \ expand 和 /replicate 函数 的左参数以产生完全相反的结果。在左侧,2元素向量{45 67}是expanded,其中出现布尔值0导致3元素 向量{45 0 67}——注意APL如何将0插入向量中。相反,在右侧——发生完全相反的情况,其中3元素的向量变成了2元素的;布尔值0s使用二元函数/ slash删除了向量的项。APL符号还使用数字以外的数据类型对项目的列表(向量)进行操作,例如字符串的2元素向量{"Apples" "Oranges"}可以替换掉上述示例中的数值向量{45 67}。
语法规则
在APL中,函数或运算符没有优先级。APL不遵循其他编程语言通常的运算符优先级;例如,×
并没有比+
更“紧密地”绑定它的操作数。APL定义了作用域的概念,而不是运算符优先级。
函数的作用域决定了它的参数。函数有长的右作用域:也就是说,它们将所有右侧的所有参数都作为右参数。二元函数具有短的左作用域:它将其左侧的第一条数据作为其左参数。例如,(下方左侧的是APL用户会话的源代码,缩进的是用户输入,非缩进的是APL解释器返回结果):
1 ÷ 2 ⌊ 3 × 4 - 5
¯0.3333333333
1 ÷ 2 ⌊ 3 × ¯1
¯0.3333333333
1 ÷ 2 ⌊ ¯3
¯0.3333333333
1 ÷ ¯3
¯0.3333333333
|
<<首先注意到没有括号 |
运算符可能具有函数或数据操作数,并计算为二元或一元函数。运算符有长的左作用域。运算符将其左侧最长的函数作为其左操作数。 例如:
∘.=/⍳¨3 3 1 0 0 0 1 0 0 0 1
|
APL原子或零碎的子分析(完整解释): diaeresis ¨或迷你双点表示重复或在每个或分别执行某个操作所以iota repeats (APL解释器使用iota读取了两次右侧的3 3), 简洁的表示了: iota两次作用于3。 |
¨
运算符的左侧操作数是index ⍳函数。派生函数 ⍳¨
作为一元函数并将向量3 3
作为右参数。each的左作用域被表示为/的reduce运算符终止。reduece的左操作数是它左侧的函数表达式:相等函数的外积。∘.=/的结果是一个一元函数。对于此函数的长右作用域,它将⍳¨3 3的结果作为其右参数。因此
(⍳3)(⍳3)
1 2 3 1 2 3
(⍳3)∘.=⍳3
1 0 0
0 1 0
0 0 1
⍳¨3 3
1 2 3 1 2 3
∘.=/⍳¨3 3
1 0 0
0 1 0
0 0 1
|
由 |
im ← ∘.=⍨∘⍳
im 3
1 0 0
0 1 0
0 0 1
|
某些APL解释器支持compose运算符∘和commute运算符⍨。前者∘ glues将函数结合在一起foo∘bar是一个函数,将自定义函数foo应用于自定义函数bar的结果;foo和bar可以代表任何存在的函数。例子中的二元函数被commute调节然后作为一元函数使用,它的右参数也被当作左参数来使用。因此,一个派生函数或组合函数(在左侧被命名为im)在APL的用户会话中被应用于它的右参数 参数、参数或操作数 = 3返回一个9-元素的单位矩阵。 |
Letters←"ABCDE"
Letters
ABCDE
⍴Letters
5
FindIt←"CABS"
FindIt
CABS
⍴FindIt
4
Letters ⍳ FindIt
3 1 2 6
|
使用APL在字符向量中英语index ⍳或查找元素的示例: 首先,变量Letters被分配了一个5元素的向量,在本例中是字母表中的字母。 Letters的shape ⍴或字符向量长度为5。 变量FindIt分配了指定要在Letters中搜索的内容,其长度为4个字符。 1 2 3 4 5 << Letters中的向量位置或索引 最后,二元函数iota searches通过其左参数(Letters)搜索搜索字符串(iota的右参数FindIt)。 Iota在Letters的第3位找到字母“C”,在第1位找到“A”,在第2位找到“B”。Iota没有找到字母“S” S不在变量Letters中的任何位置,因此它返回数字6,它比Letters的长度大1。Iota找完了字母。 "CAB"(3 1 2)。Iota没有正确找到“S”(6)。 |
一元函数
名称 | 符号 | 含义 | Unicode代码点 |
---|---|---|---|
Roll随机数 | ?B
|
从B整数随机选择一个随机数 | U+003F ? |
上取整函数 | ⌈B
|
大于或等于B的最小整数 | U+2308 ⌈ |
下取整函数 | ⌊B
|
小于或等于B的最大整数 | U+230A ⌊ |
形状, Rho | ⍴B
|
B的每个维度的分量数 | U+2374 ⍴ |
Not, 波浪号 | ∼B
|
逻辑: ∼1 是 0, ∼0 是 1 | U+223C ∼ |
绝对值 | ∣B
|
B的绝对值 | U+2223 ∣ |
索引生成器, Iota | ⍳B
|
生成从1到整数B的向量 | U+2373 ⍳ |
幂 | ⋆B
|
e的B次幂 | U+22C6 ⋆ |
逻辑非 | −B
|
改变B的符号 | U+2212 − |
共轭复数 | +B
|
B的共轭复数 (实数返回值不变) | U+002B + |
符号函数 | ×B
|
如果B<0,则是¯1;如果B=0,则是0;如果B>0,则是1 | U+00D7 × |
倒数 | ÷B
|
1除以B | U+00F7 ÷ |
链状 | ,B
|
重整B为向量 | U+002C , |
矩阵求逆 | ⌹B
|
求矩阵B的逆 | U+2339 ⌹ |
Pi乘以 | ○B
|
乘以π | U+25CB ○ |
对数 | ⍟B
|
B的自然对数 | U+235F ⍟ |
逆转 | ⌽B
|
沿最后一个轴反转B的元素 | U+233D ⌽ |
逆转 | ⊖B
|
沿第一个轴反转B的元素 | U+2296 ⊖ |
升序 | ⍋B
|
按B的指数升序排列B | U+234B ⍋ |
降序 | ⍒B
|
按B的指数降序排列B | U+2352 ⍒ |
执行 | ⍎B
|
执行一个APL表达式 | U+234E ⍎ |
一元格式 | ⍕B
|
B的字符表示 | U+2355 ⍕ |
一元转置矩阵 | ⍉B
|
反转B的轴 | U+2349 ⍉ |
阶乘 | !B
|
从1到B的整数的乘积 | U+0021 ! |
二元函数
名称 | 符号 | 含义 | Unicode代码点 |
---|---|---|---|
加法 | A+B
|
A和B的和 | U+002B + |
减法 | A−B
|
A减去B | U+2212 − |
乘法 | A×B
|
A乘以B | U+00D7 × |
除法 | A÷B
|
A除以B | U+00F7 ÷ |
幂 | A⋆B
|
A的B次幂 | U+22C6 ⋆ |
圆 | A○B
|
依据A的选择为B的三角函数
A=1: sin(B) A=5: sinh(B) A=2: cos(B) A=6: cosh(B) A=3: tan(B) A=7: tanh(B) 负数产生相应函数的倒数 |
U+25CB ○ |
随机数 | A?B
|
A个不同的整数随机从1到B的整数中产生 | U+003F ? |
成员, Epsilon | A∈B
|
如果A是B的成员,返回1,否则返回0 | U+2208 ∈ |
搜索, Epsilon Underbar | A⍷B
|
1表示B中存在多项数组A的起始点;0表示不存在 | U+2377 ⍷ |
最大值, Ceiling | A⌈B
|
返回A或B中最大的值 | U+2308 ⌈ |
最小值, Floor | A⌊B
|
返回A或B中最小的值 | U+230A ⌊ |
重塑, 二元Rho | A⍴B
|
使用B的数据构成的形状为A的数组 | U+2374 ⍴ |
选择 | A↑B
|
依据×A选择B中的第一个(或最后一个)A元素 | U+2191 ↑ |
降低 | A↓B
|
依据×A删除B中的第一个(或最后一个)A元素 | U+2193 ↓ |
解码 | A⊥B
|
系数为B在A处的多项式的值 | U+22A5 ⊥ |
编码 | A⊤B
|
B值的Base-A表示 | U+22A4 ⊤ |
模除 | A∣B
|
B模除A | U+2223 ∣ |
连接 | A,B
|
B中的元素附加A中的元素 | U+002C , |
展开式, 二元反斜杠 | A\B
|
向'B中插入零(或空格)对应于A中的零 | U+005C \ |
压缩, 二元斜杠 | A/B
|
选择B中的元素,对应于A中的一 | U+002F / |
索引, 二元Iota | A⍳B
|
返回B在A中的位置,如果没有找到,则返回1+⍴A
|
U+2373 ⍳ |
矩阵除法 | A⌹B
|
线性方程组, 多元变量统计的解 Ax = B | U+2339 ⌹ |
旋转 | A⌽B
|
B的元素旋转A个位置 | U+233D ⌽ |
旋转 | A⊖B
|
B的元素沿第一条轴旋转A个位置 | U+2296 ⊖ |
对数 | A⍟B
|
B以A为底的对数 | U+235F ⍟ |
二元格式 | A⍕B
|
根据A将B格式化为字符矩阵 | U+2355 ⍕ |
一般转置 | A⍉B
|
B的轴按A排序 | U+2349 ⍉ |
组合 | A!B
|
一次取A的B组合数 | U+0021 ! |
Diaeresis,双点 | A¨B
|
对每个, 或分别执行每一项; B = 被分别应用的项; A = 要执行或使用的操作 (例如iota) | U+00A8 ¨ |
少于 | A < B
|
比较: 如果为真,返回1;如果为假,返回0 | U+003C < |
小于等于 | A≤B
|
比较: 如果为真,返回1;如果为假,返回0 | U+2264 ≤ |
相等 | A=B
|
比较: 如果为真,返回1;如果为假,返回0 | U+003D = |
大于等于 | A≥B
|
比较: 如果为真,返回1;如果为假,返回0 | U+2265 ≥ |
大于 | A>B
|
比较: 如果为真,返回1;如果为假,返回0 | U+003E > |
不等 | A≠B
|
比较: 如果为真,返回1;如果为假,返回0 | U+2260 ≠ |
或 | A∨B
|
布尔逻辑:如果A.B都等于0,为0(False);如果A或B=1 (True),为1(True) | U+2228 ∨ |
与 | A∧B
|
布尔逻辑:如果A.B都等于1,为1(True);否则为0(False) | U+2227 ∧ |
或非 | A⍱B
|
布尔逻辑:如果A.B都是0,为1;除此以外为0. Alt: ~∨ = not Or | U+2371 ⍱ |
Nand | A⍲B
|
布尔逻辑: 如果A.B都是1,为0;除此之外为1. Alt: ~∧ = not And | U+2372 ⍲ |
左 | A⊣B
|
A | U+22A3 ⊣ |
右 | A⊢B
|
B | U+22A2 ⊢ |
运算符与轴指示符
名称 | 符号 | 示例 | 含义(示例) | Unicode代码点序列 |
---|---|---|---|---|
Reduce (最后轴), 斜杠 | / | +/B
|
横向对B求和 | U+002F / |
Reduce (第一轴) | ⌿ | +⌿B
|
纵向对B求和 | U+233F ⌿ |
Scan (最后轴), 反斜杠 | \ | +\B
|
横向对B累加求和 | U+005C \ |
Scan (第一轴) | ⍀ | +⍀B
|
纵向对B累加求和 | U+2340 ⍀ |
内积 | . | A+.×B
|
A和B的矩阵乘法 | U+002E . |
外积 | ∘. | A∘.×B
|
A和B的外积 | U+2218 ∘ , U+002E . |
注释:reduce和scan运算符期望在其左侧有一个二元函数,从而形成一个应用于其右侧向量的一元复合函数。
积运算符"."在左右两侧期望二元函数,形成一个应用于其左右两侧向量的二元复合函数。如果积运算符左侧的函数是"∘" (表示空值) 复合函数代表外积, 否则它代表内积。用于传统矩阵乘法的内积使用+和×函数,用其他二元函数替换这些可以产生有用的替代操作。
某些函数可以跟在括号中的轴指示符之后。即这出现在函数和数组之间,不应与数组后写的数组下标混淆。例如,给定⌽(反转)函数和二维数组,该函数默认沿最后一个轴运行,但这可以使用轴指示器进行更改:
A←4 3⍴⍳12
A
1 2 3
4 5 6
7 8 9
10 11 12
⌽A
3 2 1
6 5 4
9 8 7
12 11 10
⌽[1]A
10 11 12
7 8 9
4 5 6
1 2 3
⊖⌽A
12 11 10
9 8 7
6 5 4
3 2 1
⍉A
1 4 7 10
2 5 8 11
3 6 9 12
|
A is now reflected or flipped along its vertical axis as symbol ⌽ visually indicates. A is now reflected using the [1] axis indicator or first dimension modifier. The result is that variable A has been reflected across the horizontal axis, instead of vertically. A is now reflected both vertically ⊖ and horizontally ⌽. A is ⍉ transposed to a 3 row by 4 col matrix such that rows-cols become exchanged, as symbol ⍉ visually portrays. Compare the result here to the original matrix stored in A, topmost matrix. These types of data transformations are useful in time series analysis and spatial coordinates, just two examples, more exist. |
As a particular case, if the dyadic catenate "," function is followed by an axis indicator (or axis modifier to a symbol/function), it can be used to laminate (interpose) two arrays depending on whether the axis indicator is less than or greater than the index origin[8] (index origin = 1 in illustration below):
B←1 2 3 4
C←5 6 7 8
B,C
1 2 3 4 5 6 7 8
B,[0.5]C
1 2 3 4
5 6 7 8
B,[1.5]C
1 5
2 6
3 7
4 8
|
At left, variable 'B' is first assigned a vector of 4 consecutive integers (e.g., ⍳4). |
嵌套数组
Arrays are structures which have elements grouped linearly as vectors or in table form as matrices - and higher dimensions (3D or cubed, 4D or cubed over time, etc.). Arrays containing both characters and numbers are termed mixed arrays.[9] Array structures containing elements which are also arrays are called nested arrays.[10]
APL解释器的用户会话 | 解释 |
---|---|
X←4 5⍴⍳20
X
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
X[2;2]
7
⎕IO
1
X[1;1]
1
|
Element X[2;2] in row 2 - column 2 currently is an integer = 7. Initial index origin ⎕IO value = 1. Thus, the first element in matrix X or X[1;1] = 1. |
X[2;2]←⊂"Text"
X[3;4]←⊂(2 2⍴⍳4)
X
1 2 3 4 5
6 Text 8 9 10
11 12 13 1 2 15
3 4
16 17 18 19 20
|
Element in X[row 2; col 2] is changed (from 7) to a nested vector "Text" using the enclose ⊂ function. Element in X[row 3; col 4], formerly integer 14, now becomes a mini enclosed or ⊂ nested 2x2 matrix of 4 consecutive integers. Since X contains numbers, text and nested elements, it is both a mixed and a nested array. |
流程控制
A user may define custom functions which, like variables, are identified by name rather than by a non-textual symbol. The function header defines whether a custom function is niladic (no arguments), monadic (one right argument) or dyadic (left and right arguments), the local name of the result (to the left of the ← assign arrow), and whether it has any local variables (each separated by semicolon ';').
Niladic function PI or π(pi) | Monadic function CIRCLEAREA | Dyadic function SEGMENTAREA, with local variables |
---|---|---|
∇ RESULT←PI
RESULT←○1
∇
|
∇ AREA←CIRCLEAREA RADIUS
AREA←PI×RADIUS⋆2
∇
|
∇ AREA←DEGREES SEGMENTAREA RADIUS ; FRACTION ; CA
FRACTION←DEGREES÷360
CA←CIRCLEAREA RADIUS
AREA←FRACTION×CA
∇
|
Whether functions with the same identifier but different adicity are distinct is implementation-defined. If allowed, then a function CURVEAREA could be defined twice to replace both monadic CIRCLEAREA and dyadic SEGMENTAREA above, with the monadic or dyadic function being selected by the context in which it was referenced.
Custom dyadic functions may usually be applied to parameters with the same conventions as built-in functions, i.e., arrays should either have the same number of elements or one of them should have a single element which is extended. There are exceptions to this, for example a function to convert pre-decimal UK currency to dollars would expect to take a parameter with precisely three elements representing pounds, shillings and pence.[11]
Inside a program or a custom function, control may be conditionally transferred to a statement identified by a line number or explicit label; if the target is 0 (zero) this terminates the program or returns to a function's caller. The most common form uses the APL compression function, as in the template (condition)/target which has the effect of evaluating the condition to 0 (false) or 1 (true) and then using that to mask the target (if the condition is false it is ignored, if true it is left alone so control is transferred).
Hence function SEGMENTAREA may be modified to abort (just below), returning zero if the parameters (DEGREES and RADIUS below) are of different sign:
∇ AREA←DEGREES SEGMENTAREA RADIUS ; FRACTION ; CA ; SIGN ⍝ local variables denoted by semicolon(;)
FRACTION←DEGREES÷360
CA←CIRCLEAREA RADIUS ⍝ this APL code statement calls user function CIRCLEAREA, defined up above.
SIGN←(×DEGREES)≠×RADIUS ⍝ << APL logic TEST/determine whether DEGREES and RADIUS do NOT (≠ used) have same SIGN 1-yes different(≠), 0-no(same sign)
AREA←0 ⍝ default value of AREA set = zero
→SIGN/0 ⍝ branching(here, exiting) occurs when SIGN=1 while SIGN=0 does NOT branch to 0. Branching to 0 exits function.
AREA←FRACTION×CA
∇
The above function SEGMENTAREA works as expected if the parameters are scalars or single-element arrays, but not if they are multiple-element arrays since the condition ends up being based on a single element of the SIGN array - on the other hand, the user function could be modified to correctly handle vectorized arguments. Operation can sometimes be unpredictable since APL defines that computers with vector-processing capabilities should parallelise and may reorder array operations as far as possible - thus, test and debug user functions particularly if they will be used with vector or even matrix arguments. This affects not only explicit application of a custom function to arrays, but also its use anywhere that a dyadic function may reasonably be used such as in generation of a table of results:
90 180 270 ¯90 ∘.SEGMENTAREA 1 ¯2 4
0 0 0
0 0 0
0 0 0
0 0 0
A more concise way and sometimes better way - to formulate a function is to avoid explicit transfers of control, instead using expressions which evaluate correctly in all or the expected conditions. Sometimes it is correct to let a function fail when one or both input arguments are incorrect - precisely to let user know that one or both arguments used were incorrect. The following is more concise than the above SEGMENTAREA function. The below importantly correctly handles vectorized arguments:
∇ AREA←DEGREES SEGMENTAREA RADIUS ; FRACTION ; CA ; SIGN
FRACTION←DEGREES÷360
CA←CIRCLEAREA RADIUS
SIGN←(×DEGREES)≠×RADIUS
AREA←FRACTION×CA×~SIGN ⍝ this APL statement is more complex, as a one-liner - but it solves vectorized arguments: a tradeoff - complexity vs. branching
∇
90 180 270 ¯90 ∘.SEGMENTAREA 1 ¯2 4
0.785398163 0 12.5663706
1.57079633 0 25.1327412
2.35619449 0 37.6991118
0 ¯3.14159265 0
Avoiding explicit transfers of control also called branching, if not reviewed or carefully controlled - can promote use of excessively complex one liners, veritably "misunderstood and complex idioms" and a "write-only" style, which has done little to endear APL to influential commentators such as Edsger Dijkstra.[12] Conversely however APL idioms can be fun, educational and useful - if used with helpful comments ⍝, for example including source and intended meaning and function of the idiom(s). Here is an APL idioms list, an IBM APL2 idioms list here[13] and Finnish APL idiom library here.
杂项
名称 | 符号 | 示例 | 含义(示例) | Unicode代码点 |
---|---|---|---|---|
High minus[14] | ¯ | ¯3
|
Denotes a negative number | U+00AF ¯ |
Lamp, Comment | ⍝ | ⍝This is a comment
|
Everything to the right of ⍝ denotes a comment | U+235D ⍝ |
RightArrow, Branch, GoTo | → | →This_Label
|
→This_Label sends APL execution to This_Label: | U+2192 → |
Assign, LeftArrow, Set to | ← | B←A
|
B←A sets values and shape of B to match A | U+2190 ← |
Most APL implementations support a number of system variables and functions, usually preceded by the ⎕ (quad) and or ")" (hook=close parenthesis) character. Particularly important and widely implemented is the ⎕IO (Index Origin) variable, since while the original IBM APL based its arrays on 1 some newer variants base them on zero:
APL解释器的用户会话 | 描述 |
---|---|
X←⍳12
X
1 2 3 4 5 6 7 8 9 10 11 12
⎕IO
1
X[1]
1
|
X set = to vector of 12 consecutive integers. Initial index origin ⎕IO value = 1. Thus, the first position in vector X or X[1] = 1 per vector of iota values {1 2 3 4 5 ...}. |
⎕IO←0
X[1]
2
X[0]
1
|
Index Origin ⎕IO now changed to 0. Thus, the 'first index position' in vector X changes from 1 to 0. Consequently, X[1] then references or points to 2 from {1 2 3 4 5 ...} and X[0] now references 1. |
⎕WA
41226371072
|
Quad WA or ⎕WA, another dynamic system variable, shows how much Work Area remains unused or 41,226 megabytes or about 41 gigabytes of unused additional total free work area available for the APL workspace and program to process using. If this number gets low or approaches zero - the computer may need more random-access memory (RAM), hard disk drive space or some combination of the two to increase virtual memory. |
)VARS
X
|
)VARS a system function in APL,[15] )VARS shows user variable names existing in the current workspace. |
There are also system functions available to users for saving the current workspace e.g., )SAVE and terminating the APL environment, e.g., )OFF - sometimes called hook commands or functions due to the use of a leading right parenthesis or hook.[16] There is some standardization of these quad and hook functions.
字体
The Unicode Basic Multilingual Plane includes the APL symbols in the Miscellaneous Technical block,[17] which are thus usually rendered accurately from the larger Unicode fonts installed with most modern operating systems. These fonts are rarely designed by typographers familiar with APL glyphs. So, while accurate, the glyphs may look unfamiliar to APL programmers or be difficult to distinguish from one another.
Some Unicode fonts have been designed to display APL well: APLX Upright, APL385 Unicode, and SimPL.
Before Unicode, APL interpreters were supplied with fonts in which APL characters were mapped to less commonly used positions in the ASCII character sets, usually in the upper 128 code points. These mappings (and their national variations) were sometimes unique to each APL vendor's interpreter, which made the display of APL programs on the Web, in text files and manuals - frequently problematic.
APL2键盘的函数到符号映射
Note the APL On/Off Key - topmost-rightmost key, just below. Also note the keyboard had some 55 unique (68 listed per tables above, including comparative symbols but several symbols appear in both monadic and dyadic tables) APL symbol keys (55 APL functions (operators) are listed in IBM's 5110 APL Reference Manual), thus with the use of alt, shift and ctrl keys - it would theoretically have allowed a maximum of some 59 (keys) *4 (with 2-key pressing) *3 (with tri-key pressing, e.g., ctrl-alt-del) or some 472 different maximum key combinations, approaching the 512 EBCDIC character max (256 chars times 2 codes for each keys-combination). Again, in theory the keyboard pictured below would have allowed for about 472 different APL symbols/functions to be keyboard-input, actively used. In practice, early versions were only using something roughly equivalent to 55 APL special symbols (excluding letters, numbers, punctuation, etc. keys). Thus, early APL was then only using about 11% (55/472) of a symbolic language's at-that-time utilization potential, based on keyboard # keys limits, again excluding numbers, letters, punctuation, etc. In another sense keyboard symbols utilization was closer to 100%, highly efficient, since EBCDIC only allowed 256 distinct chars, and ASCII only 128.
解题
APL在解决数学难题方面非常有用,下面将介绍其中的几个例子。
帕斯卡三角形
Take Pascal's triangle, which is a triangular array of numbers in which those at the ends of the rows are 1 and each of the other numbers is the sum of the nearest two numbers in the row just above it (the apex, 1, being at the top). The following is an APL one-liner function to visually depict Pascal's triangle:
Pascal←{0~¨⍨a⌽⊃⌽∊¨0,¨¨a∘!¨a←⌽⍳⍵} ⍝ Create one-line user function called Pascal
Pascal 7 ⍝ Run function Pascal for seven rows and show the results below:
1
1 2
1 3 3
1 4 6 4
1 5 10 10 5
1 6 15 20 15 6
1 7 21 35 35 21 7
质数,通过因数反证
Determine the number of prime numbers (prime # is a natural number greater than 1 that has no positive divisors other than 1 and itself) up to some number N. Ken Iverson is credited with the following one-liner APL solution to the problem:
⎕CR 'PrimeNumbers' ⍝ Show APL user-function PrimeNumbers
Primes←PrimeNumbers N ⍝ Function takes one right arg N (e.g., show prime numbers for 1 ... int N)
Primes←(2=+⌿0=(⍳N)∘.|⍳N)/⍳N ⍝ The Ken Iverson one-liner
PrimeNumbers 100 ⍝ Show all prime numbers from 1 to 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
⍴PrimeNumbers 100
25 ⍝ There are twenty-five prime numbers in the range up to 100.
Examining the converse or opposite of a mathematical solution is frequently needed (integer factors of a number): Prove for the subset of integers from 1 through 15 that they are non-prime by listing their decomposition factors. What are their non-one factors (#'s divisible by, except 1)?
⎕CR 'ProveNonPrime'
Z←ProveNonPrime R
⍝Show all factors of an integer R - except 1 and the number itself,
⍝ i.e., prove Non-Prime. String 'prime' is returned for a Prime integer.
Z←(0=(⍳R)|R)/⍳R ⍝ Determine all factors for integer R, store into Z
Z←(~(Z∊1,R))/Z ⍝ Delete 1 and the number as factors for the number from Z.
→(0=⍴Z)/ProveNonPrimeIsPrime ⍝ If result has zero shape, it has no other factors and is therefore prime
Z←R,(⊂" factors(except 1) "),(⊂Z),⎕TCNL ⍝ Show the number R, its factors(except 1,itself), and a new line char
→0 ⍝ Done with function if non-prime
ProveNonPrimeIsPrime: Z←R,(⊂" prime"),⎕TCNL ⍝ function branches here if number was prime
ProveNonPrime ¨⍳15 ⍝ Prove non primes for each(¨) of the integers from 1 through 15 (iota 15)
1 prime
2 prime
3 prime
4 factors(except 1) 2
5 prime
6 factors(except 1) 2 3
7 prime
8 factors(except 1) 2 4
9 factors(except 1) 3
10 factors(except 1) 2 5
11 prime
12 factors(except 1) 2 3 4 6
13 prime
14 factors(except 1) 2 7
15 factors(except 1) 3 5
斐波那契数列
生成一个斐波那契数列,序列中的每个后续数字都是前两个数字的和:
⎕CR 'Fibonacci' ⍝ Display function Fibonacci
FibonacciNum←Fibonacci Nth;IOwas ⍝ Funct header, funct name=Fibonacci, monadic funct with 1 right hand arg Nth;local var IOwas, and a returned num.
⍝Generate a Fibonacci sequenced number where Nth is the position # of the Fibonacci number in the sequence. << function description
IOwas←⎕IO ⋄ ⎕IO←0 ⋄ FibonacciNum←↑0 1↓↑+.×/Nth/⊂2 2⍴1 1 1 0 ⋄ ⎕IO←IOwas ⍝ In order for this function to work correctly ⎕IO must be set to zero.
Fibonacci¨⍳14 ⍝ This APL statement says: Generate the Fibonacci sequence over each(¨) integer number(iota or ⍳) for the integers 1..14.
0 1 1 2 3 5 8 13 21 34 55 89 144 233 ⍝ Generated sequence, i.e., the Fibonacci sequence of numbers generated by APL's interpreter.
进一步阅读
- Polivka, Raymond P.; Pakin, Sandra. APL: The Language and Its Usage. Prentice-Hall. 1975. ISBN 978-0-13-038885-8.
- Reiter, Clifford A.; Jones, William R. APL with a Mathematical Accent 1. Taylor & Francis. 1990. ISBN 978-0534128647.
- Thompson, Norman D.; Polivka, Raymond P. APL2 in Depth (Springer Series in Statistics) (Paperback) Reprint of the original 1st. Springer. 2013. ISBN 978-0387942131.
- Gilman, Leonard; Rose, Allen J. A. P. L.: An Interactive Approach (Paperback) 3rd. 1976. ISBN 978-0471093046.
另见
引用
- ^ Iverson, Kenneth E. A Programming Language. Proceedings of the May 1–3, 1962, Spring Joint Computer Conference. AIEE-IRE '62 (Spring) (New York, NY, USA: ACM). 1962-01-01: 345–351. doi:10.1145/1460833.1460872.
- ^ Baronet, Dan. Sharp APL Operators. archive.vector.org.uk. Vector - Journal of the British APL Association. [13 January 2015].
- ^ MicroAPL. Primitive Operators. www.microapl.co.uk. MicroAPL. [13 January 2015].
- ^ MicroAPL. Operators. www.microapl.co.uk. MicroAPL. [13 January 2015].
- ^ Progopedia. APL. progopedia.com. Progopedia. [13 January 2015].
- ^ Dyalog. D-functions and operators loosely grouped into categories. dfns.dyalog.com. Dyalog. [13 January 2015].
- ^ IBM. IBM 5100 APL Reference Manual (PDF). bitsavers.trailing-edge.com. IBM. [14 January 2015]. (原始内容 (PDF)存档于14 January 2015).
- ^ Brown, Jim. In defense of index origin 0. ACM SIGAPL APL Quote Quad. 1978, 9 (2): 7. doi:10.1145/586050.586053.
- ^ MicroAPL. APLX Language Manual (PDF). www.microapl.co.uk. MicroAPL - Version 5 .0 June 2009: 22. [31 January 2015].
- ^ Benkard, J. Philip. Nested Arrays and Operators: Some Issues in Depth. ACM SIGAPL APL Quote Quad. 1992, 23 (1): 7–21. ISBN 978-0897914772. doi:10.1145/144045.144065.
- ^ Berry, Paul "APL\360 Primer Student Text", IBM Research, Thomas J. Watson Research Center, 1969.
- ^ Treatise (PDF). www.cs.utexas.edu. [2019-09-10].
- ^ Cason, Stan. APL2 Idioms Library. www-01.ibm.com. IBM. [1 February 2015].
- ^ APL's "high minus" applies to the single number that follows, while the monadic minus function changes the sign of the entire array to its right.
- ^ The Workspace - System Functions. Microapl.co.uk: (toward bottom of the web page). [2018-11-05].
- ^ APL language reference (PDF). [2018-11-05].
- ^ Unicode chart Miscellaneous Technical (including APL) (PDF).
外部链接
- APL character reference: Page 1, Page 2, Page 3, Page 4
- British APL Association fonts page
- IBM code page 293 aka the APL code page on mainframes
- General information about APL chars on the APL wiki
- extending APL and its keyboard-symbols-operators.
- Lee, Xah. How to Create an APL or Math Symbols Keyboard Layout. [13 January 2015].
通用在线教程
- A Practical Introduction to APL 1 & APL 2 by Graeme Donald Robertson
- APL for PCs, Servers and Tablets - NARS full-featured, no restrictions, free downloadable APL/2 with nested arrays by Sudley Place Software
- GNU APL free downloadable interpreter for APL by Jürgen Sauermann
- YouTube APL Tutorials uploaded by Jimin Park, 8 intro/beginner instructional videos.
- SIGAPL Compiled Tutorials List
- Learn APL: An APL Tutorial by MicroAPL
语法规则
- Conway's Game Of Life in APL, on YouTube
- Iverson, Kenneth E. APL syntax and semantics. ACM SIGAPL APL Quote Quad. 1983, 13 (3): 223–231. ISBN 978-0897910958. doi:10.1145/800062.801221.
- Gffer, M. A Future APL: Examples and Problems. ACM SIGAPL APL Quote Quad. 1989, 19 (4): 158–163. ISBN 978-0897913270. doi:10.1145/75144.75166.