使用者: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.