Közvetlen funkció - Direct function
A közvetlen függvény ( dfn , ejtsd: "dee fun") alternatív módja annak, hogy egy funkciót és operátort ( magasabb rendű függvény ) definiáljunk az APL programozási nyelvben . A közvetlen operátor nevezhető dopnak (ejtsd: "dee op"). Ezeket John Scholes találta fel 1996-ban. A tömb programozás , a magasabb rendű funkció és a funkcionális programozás egyedülálló kombinációja , és a 21. század eleji APL jelentős megkülönböztető előnye a korábbi verziókhoz képest.
A dfn az esetlegesen védett kifejezések sorozata (vagy csak egy őr) a {és között }, ⋄új sorokkal elválasztva , ahol ⍺a bal és ⍵a jobb oldali argumentum , valamint ∇a rekurzió (függvény önhivatkozás). Például, a függvény PTellenőrzi, hogy minden egyes sorában ⍵egy pithagoraszi triplett (annak tesztelésével, hogy a négyzetösszeg kétszer akkora a tér a legnagyobb).
PT← {(+/⍵*2)=2×(⌈/⍵)*2}
PT 3 4 5
1
x
4 5 3
3 11 6
5 13 12
17 16 8
11 12 4
17 15 8
PT x
1 0 1 0 0 1
A faktoriális függvény dfn -ként:
fact← {0=⍵:1 ⋄ ⍵×∇ ⍵-1}
fact 5
120
fact¨ ⍳10 ⍝ fact applied to each element of 0 to 9
1 1 2 6 24 120 720 5040 40320 362880
Leírás
A dfns szabályait a következő "referenciakártya" foglalja össze:
{⍺ function ⍵}
|
{⍺⍺ operator ⍵⍵}
|
: őr
|
⍺ bal érv
|
⍺⍺ bal operandus
|
:: hiba-őr
|
⍵ helyes érv
|
⍵⍵ jobb operandus
|
⍺← alapértelmezett bal érv
|
∇ önhivatkozás
|
∇∇ önhivatkozás
|
s← félénk eredmény
|
A dfn az esetlegesen védett kifejezések sorozata (vagy csak egy őr) között {és között }, elválasztva ⋄vagy új sorokkal.
expression
guard: expression
guard:
A kifejezéseket és/vagy védőelemeket sorrendben értékelik. Az őrnek 0 -ra vagy 1 -re kell értékelnie; a hozzá tartozó kifejezést akkor értékeli, ha az értéke 1. A dfn az első nem védett kifejezés után fejeződik be, amely nem végződik hozzárendeléssel , vagy az első őrzött kifejezés után, amelynek őre 1 -re értékel, vagy ha nincs több kifejezés. A dfn eredménye az utoljára értékelt kifejezés eredménye. Ha az utolsó értékelt kifejezés hozzárendeléssel végződik, az eredmény "félénk" - nem jelenik meg automatikusan a munkamenetben.
A dfn -ben hozzárendelt nevek alapértelmezés szerint lokálisak , lexikális hatókörrel .
⍺a bal függvény argumentumot és ⍵a jobb oldalt jelöli ; ⍺⍺a bal és ⍵⍵a jobb operandust jelöli . Ha ⍵⍵előfordul a definícióban, akkor a dfn egy diadikus operátor ; ha csak ⍺⍺előfordul, de nem ⍵⍵, akkor monád operátor; ha egyik sem ⍺⍺vagy ⍵⍵előfordul, akkor a dfn függvény.
A speciális szintaxist arra használjuk, hogy alapértelmezett értéket adjunk a bal argumentumnak, ha egy dfn -t monadikailag hívunk, azaz bal argumentum nélkül hívjuk meg. A másként nem értékelhető.
⍺←expression⍺←expression
∇rekurziót vagy önreferenciát jelöl a függvény által, és ∇∇jelzi az operátor önreferenciáját. Az ilyen jelölés lehetővé teszi a névtelen rekurziót .
Hiba csapdázás keresztül biztosított hiba őrök, . Amikor hiba keletkezik, a rendszer dinamikusan keresi a hívási funkciók között a hibához illő hibaelhárítót. Ha ilyet talál, a végrehajtási környezet lecsévélődik közvetlenül a hibavédelmi végrehajtást megelőző állapotára, és a hibavédő kapcsolódó kifejezése a dfn eredményeként kerül kiértékelésre.
errnums::expression
A dfns -ről további leírások, magyarázatok és oktatóanyagok találhatók az idézett cikkekben.
Példák
Az itt látható példák a dfns különböző aspektusait illusztrálják. További példákat talál az idézett cikkekben.
Alapértelmezett bal érv
A funkció hozzáadja a ( i vagy √ -1 ) alkalommal .
{⍺+0j1×⍵}⍺0j1⍵
3 {⍺+0j1×⍵} 4
3J4
∘.{⍺+0j1×⍵}⍨ ¯2+⍳5
¯2J¯2 ¯2J¯1 ¯2 ¯2J1 ¯2J2
¯1J¯2 ¯1J¯1 ¯1 ¯1J1 ¯1J2
0J¯2 0J¯1 0 0J1 0J2
1J¯2 1J¯1 1 1J1 1J2
2J¯2 2J¯1 2 2J1 2J2
Ennek a funkciónak a jelentősége a következőképpen tekinthető meg:
A komplex számokat valós számok rendezett párjaiként lehet felépíteni, hasonlóan ahhoz, ahogy az egész számokat természetes számok rendezett párjaként, a racionális számokat pedig rendezett egészpárokként lehet felépíteni. Összetett számok esetében ugyanaz a szerep, mint egész számoknál és racionális számoknál.
{⍺+0j1×⍵}-÷
Ezenkívül a monád ⇔ ( tagadás ) és a monadikus ⇔ ( kölcsönös ) analógjaihoz hasonlóan hasznos a függvény monadikus meghatározása, amely a 0 alapértelmezett értékének megadásával érhető el : ha , akkor ⇔ ⇔ .
-⍵0-⍵÷⍵1÷⍵⍺j←{⍺←0 ⋄ ⍺+0j1×⍵}j ⍵0 j ⍵0+0j1×⍵
j←{⍺←0 ⋄ ⍺+0j1×⍵}
3 j 4 ¯5.6 7.89
3J4 3J¯5.6 3J7.89
j 4 ¯5.6 7.89
0J4 0J¯5.6 0J7.89
sin← 1∘○
cos← 2∘○
Euler← {(*j ⍵) = (cos ⍵) j (sin ⍵)}
Euler (¯0.5+?10⍴0) j (¯0.5+?10⍴0)
1 1 1 1 1 1 1 1 1 1
Az utolsó kifejezés Euler képletét szemlélteti tíz véletlen számon, valós és képzelt részekkel az intervallumban .
Egyszeri rekurzió
A Cantor halmaz terner konstrukciója a [0,1] intervallummal kezdődik, és minden szakaszban eltávolítja a középső harmadot minden fennmaradó részintervallumból:
A Cantor sorrend ⍵dfn -ként definiálva:
Cantor← {0=⍵:,1 ⋄ ,1 0 1 ∘.∧ ∇ ⍵-1}
Cantor 0
1
Cantor 1
1 0 1
Cantor 2
1 0 1 0 0 0 1 0 1
Cantor 3
1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1
Cantor 0 - Cantor 6 fekete sávként ábrázolva:
A függvény kiszámít egy bites hosszúságú vektort, hogy a bit (for és ) esetén 1 és csak akkor legyen prím .
sieve ⍵⍵i0≤ii<⍵i
sieve←{
4≥⍵:⍵⍴0 0 1 1
r←⌊0.5*⍨n←⍵
p←2 3 5 7 11 13 17 19 23 29 31 37 41 43
p←(1+(n≤×⍀p)⍳1)↑p
b← 0@1 ⊃ {(m⍴⍵)>m⍴⍺↑1 ⊣ m←n⌊⍺×≢⍵}⌿ ⊖1,p
{r<q←b⍳1:b⊣b[⍵]←1 ⋄ b[q,q×⍸b↑⍨⌈n÷q]←0 ⋄ ∇ ⍵,q}p
}
10 10 ⍴ sieve 100
0 0 1 1 0 1 0 1 0 0
0 1 0 1 0 0 0 1 0 1
0 0 0 1 0 0 0 0 0 1
0 1 0 0 0 0 0 1 0 0
0 1 0 1 0 0 0 1 0 0
0 0 0 1 0 0 0 0 0 1
0 1 0 0 0 0 0 1 0 0
0 1 0 1 0 0 0 0 0 1
0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 1 0 0
b←sieve 1e9
≢b
1000000000
(10*⍳10) (+⌿↑)⍤0 1 ⊢b
0 4 25 168 1229 9592 78498 664579 5761455 50847534
Az utolsó szekvencia, a prímek száma kevesebb, mint 10, az OEIS kezdeti szegmense : A006880 . Az utolsó szám, 50847534, a prímek száma kevesebb, mint . Ezt Bertelsen számának hívják, amelyet a MathWorld emlékezetesen úgy ír le, hogy "téves név, tévesen, tekintettel a" hibás értékére ".
sievekét különböző módszert használ a kompozitok 0 -val történő megjelölésére, mindkettő helyi anonim dfns használatával: Az első az Eratosthenes szitáját használja az 1 -es kezdőmaszkra és a prímszámok előtagjára 2 3 ... 43, az insert operátor használatával ⌿( jobb oldali hajtás ). (Az előtag hossza az elsődleges függvénnyel összehasonlítva kapható meg .) A második megtalálja a legkisebb új prímet, amely a ( ) függvényben marad , és maga 0 bitre állítja, és a biteket időnként a (1 ) kezdeti szegmensben maradó 1 bit számaira állítja . Ez a második dfn farokrekurziót használ.
×⍀pqbq←b⍳1qqb⍸b↑⍨⌈n÷q
Farok rekurzió
Jellemzően a faktoriális függvény rekurzívan definiálható (a fentiek szerint ), de kódolható a farok rekurzió kihasználására egy akkumulátor bal oldali argumentum használatával:
fac←{⍺←1 ⋄ ⍵=0:⍺ ⋄ (⍺×⍵) ∇ ⍵-1}
Hasonlóképpen, a négyzet alakú komplex mátrix determinánsa a Gauss -eliminációt alkalmazva kiszámítható farokrekurzióval:
det←{ ⍝ determinant of a square complex matrix
⍺←1 ⍝ product of co-factor coefficients so far
0=≢⍵:⍺ ⍝ result for 0-by-0
(i j)←(⍴⍵)⊤⊃⍒|,⍵ ⍝ row and column index of the maximal element
k←⍳≢⍵
(⍺×⍵[i;j]ׯ1*i+j) ∇ ⍵[k~i;k~j] - ⍵[k~i;j] ∘.× ⍵[i;k~j]÷⍵[i;j]
}
Többszörös rekurzió
A nem negatív egészek partíciója pozitív egész számok vektora , így ahol a sorrend nem jelentős. Például, és a partíciók 4, és és és ugyanazt a partíciót tekintik.
n = +⌿v2 22 1 12 1 11 2 11 1 2
A partíciófüggvény megszámolja a partíciók számát. A funkció a számelméletben érdekes , amelyet Euler , Hardy , Ramanujan , Erdős és mások tanulmányoztak. Az ismétlődési reláció
Euler ötszögű számtételéből származtatott . Dfn -ként írva:
pn ← {1≥⍵:0≤⍵ ⋄ -⌿+⌿∇¨rec ⍵}
rec ← {⍵ - (÷∘2 (×⍤1) ¯1 1 ∘.+ 3∘×) 1+⍳⌈0.5*⍨⍵×2÷3}
pn 10
42
pn¨ ⍳13 ⍝ OEIS A000041
1 1 2 3 5 7 11 15 22 30 42 56 77
Az alapja lépésben megállapítja, hogy az , az eredmény a funkció , 1, ha ⍵ jelentése 0 vagy 1, és 0 egyébként. A rekurzív lépés erősen többszörösen rekurzív. Például azt eredményezi, hogy a függvényt a következő elemekre kell alkalmazni :
1≥⍵:0≤⍵1≥⍵0≤⍵pn 200rec 200
rec 200
199 195 188 178 165 149 130 108 83 55 24 ¯10
198 193 185 174 160 143 123 100 74 45 13 ¯22
és az univerzum koránál hosszabb ideig tart kiszámítani (a függvény önmagához hív). A számítási idő csökkenthető memoizálással , itt közvetlen operátorként valósul meg (magasabb rendű funkció) :
pn 200M
M←{
f←⍺⍺
i←2+'⋄'⍳⍨t←2↓,⎕cr 'f'
⍎'{T←(1+⍵)⍴¯1 ⋄ ',(i↑t),'¯1≢T[⍵]:⊃T[⍵] ⋄ ⊃T[⍵]←⊂',(i↓t),'⍵}⍵'
}
pn M 200
3.973E12
0 ⍕ pn M 200 ⍝ format to 0 decimal places
3972999029388
Ez az érték megegyezik Hardy és Ramanujan 1918 -as számításával.
pn M 200
A memo operátor Mdefiniálja operandus funkciójának egy változatát ⍺⍺a gyorsítótár használatára T, majd értékeli azt. Az operandussal pna változat a következő:
{T←(1+⍵)⍴¯1 ⋄ {1≥⍵:0≤⍵ ⋄ ¯1≢T[⍵]:⊃T[⍵] ⋄ ⊃T[⍵]←⊂-⌿+⌿∇¨rec ⍵}⍵}
Közvetlen kezelő (dop)
Quicksort egy tömbben ⍵működik választásával egy „pivot” véletlenszerűen körében nagyobb sejteket, majd catenating a válogatott nagy sejtek, amelyek szigorúan megelőzik a pivot, a nagy sejtek egyenlő a pivot, és a válogatott nagy sejtek, amelyek szigorúan követik a pivot, mint összehasonlító függvény határozza meg ⍺⍺. Definíció szerint a közvetlen operátor (DOP) Q:
Q←{1≥≢⍵:⍵ ⋄ (∇ ⍵⌿⍨0>s)⍪(⍵⌿⍨0=s)⍪∇ ⍵⌿⍨0<s←⍵ ⍺⍺ ⍵⌷⍨?≢⍵}
⍝ precedes ⍝ follows ⍝ equals
2 (×-) 8 8 (×-) 2 8 (×-) 8
¯1 1 0
x← 2 19 3 8 3 6 9 4 19 7 0 10 15 14
(×-) Q x
0 2 3 3 4 6 7 8 9 10 14 15 19 19
Q3egy változata, hogy catenates a három rész által bezárt funkció ⊂helyett a részek önmagukban . Az egyes rekurzív lépésekben létrehozott három rész nyilvánvaló a végeredmény szerkezetében. Ha a függvényt Q3többször alkalmazza ugyanahhoz az argumentumhoz, akkor eltérő eredményeket kap, mivel a pivotokat véletlenszerűen választják ki. Az eredmények sorrendi bejárása ugyanazt a rendezett tömböt eredményezi.
Q3←{1≥≢⍵:⍵ ⋄ (⊂∇ ⍵⌿⍨0>s)⍪(⊂⍵⌿⍨0=s)⍪⊂∇ ⍵⌿⍨0<s←⍵ ⍺⍺ ⍵⌷⍨?≢⍵}
(×-) Q3 x
┌────────────────────────────────────────────┬─────┬┐
│┌──────────────┬─┬─────────────────────────┐│19 19││
││┌──────┬───┬─┐│6│┌──────┬─┬──────────────┐││ ││
│││┌┬─┬─┐│3 3│4││ ││┌┬─┬─┐│9│┌┬──┬────────┐│││ ││
│││││0│2││ │ ││ ││││7│8││ │││10│┌──┬──┬┐││││ ││
│││└┴─┴─┘│ │ ││ ││└┴─┴─┘│ │││ ││14│15││││││ ││
││└──────┴───┴─┘│ ││ │ │││ │└──┴──┴┘││││ ││
││ │ ││ │ │└┴──┴────────┘│││ ││
││ │ │└──────┴─┴──────────────┘││ ││
│└──────────────┴─┴─────────────────────────┘│ ││
└────────────────────────────────────────────┴─────┴┘
(×-) Q3 x
┌───────────────────────────┬─┬─────────────────────────────┐
│┌┬─┬──────────────────────┐│7│┌────────────────────┬─────┬┐│
│││0│┌┬─┬─────────────────┐││ ││┌──────┬──┬────────┐│19 19│││
│││ │││2│┌────────────┬─┬┐│││ │││┌┬─┬─┐│10│┌──┬──┬┐││ │││
│││ │││ ││┌───────┬─┬┐│6│││││ │││││8│9││ ││14│15││││ │││
│││ │││ │││┌┬───┬┐│4│││ │││││ │││└┴─┴─┘│ │└──┴──┴┘││ │││
│││ │││ │││││3 3│││ │││ │││││ ││└──────┴──┴────────┘│ │││
│││ │││ │││└┴───┴┘│ │││ │││││ │└────────────────────┴─────┴┘│
│││ │││ ││└───────┴─┴┘│ │││││ │ │
│││ │││ │└────────────┴─┴┘│││ │ │
│││ │└┴─┴─────────────────┘││ │ │
│└┴─┴──────────────────────┘│ │ │
└───────────────────────────┴─┴─────────────────────────────┘
A fenti megfogalmazás nem új; lásd például A klasszikus A számítógépes algoritmusok tervezése és elemzése 3.7 . A 3.7. Ábrán látható pidgin ALGOL programtól eltérően azonban Qvégrehajtható, és a rendezésben használt részleges sorrend operandus, a fenti példák.
(×-)
Dfns kezelőkkel és vonatokkal
A Dfns, különösen a névtelen dfns, jól működik az üzemeltetőkkel és a vonatokkal. A következő részlet megoldja a "Programozó gyöngyök" rejtvényt: az angol szavak szótárában, amelyet itt karaktermátrixként ábrázolunk a, keresse meg az összes anagrammakészletet.
a {⍵[⍋⍵]}⍤1 ⊢a ({⍵[⍋⍵]}⍤1 {⊂⍵}⌸ ⊢) a
pats apst ┌────┬────┬────┐
spat apst │pats│teas│star│
teas aest │spat│sate│ │
sate aest │taps│etas│ │
taps apst │past│seat│ │
etas aest │ │eats│ │
past apst │ │tase│ │
seat aest │ │east│ │
eats aest │ │seta│ │
tase aest └────┴────┴────┘
star arst
east aest
seta aest
Az algoritmus úgy működik, válogatás a sorok egyenként ( ), és ezek a Rendezett sorok használják kulcsok ( „aláírás” a programozás Pearls leírás) a kulcsfontosságú szereplő a csoport a sorok a mátrixban. A jobb oldali kifejezés vonat , egy szintaktikai forma, amelyet az APL használ a hallgatólagos programozás eléréséhez . Itt három függvény elszigetelt sorozata, így ⇔ , ahonnan a jobb oldali kifejezés egyenértékű .
{⍵[⍋⍵]}⍤1 ⊢a⌸(f g h) ⍵(f ⍵) g (h ⍵)({⍵[⍋⍵]}⍤1 ⊢a) {⊂⍵}⌸ a
Lexikai hatókör
Amikor egy belső (nested) dfn utal egy nevet, azt kérik a kifelé nézett át körülfogó dfns helyett le a hívási verem . Ez a rendszer lexikális hatókört alkalmaz az APL szokásos dinamikus hatóköre helyett . A megkülönböztetés csak akkor válik nyilvánvalóvá, ha egy külső szinten meghatározott függvényt hívnak meg. A szokásosabb bejövő hívások esetében a két rendszer nem különböztethető meg.
Például, a következő függvény which, a változó tyhatározza mind whichönmagában, és a belső funkció f1. Amikor f1kifelé hív f2és f2arra hivatkozik ty, a külsőt találja (értékkel 'lexical'), nem pedig az f1(értékkel 'dynamic') -ben meghatározottat :
which←{
ty←'lexical'
f1←{ty←'dynamic' ⋄ f2 ⍵}
f2←{ty,⍵}
f1 ⍵
}
which ' scope'
lexical scope
Hiba-őr
A következő funkció a hibavédők használatát szemlélteti:
plus←{
tx←'catch all' ⋄ 0::tx
tx←'domain' ⋄ 11::tx
tx←'length' ⋄ 5::tx
⍺+⍵
}
2 plus 3 ⍝ no errors
5
2 3 4 5 plus 'three' ⍝ argument lengths don't match
length
2 3 4 5 plus 'four' ⍝ can't add characters
domain
2 3 plus 3 4⍴5 ⍝ can't add vector to matrix
catch all
Az APL -ben az 5. számú hiba "hosszúsághiba"; a 11. számú hiba "domain hiba"; és a 0 -ás hibaszám az "1 -es és 999 -es hibaszámok" összes fogása.
A példa a helyi környezet felcsévélését mutatja be, mielőtt kiértékeli a hibavédő kifejezését. A helyi név úgy txvan beállítva, hogy leírja a következő hibavédelmi körét. Hiba esetén a környezetet letekerjük, hogy txstatikusan helyes értékét tegyük közzé .
Dfns versus tradfns
Mivel a közvetlen függvények dfns -ek, a hagyományos módon definiált APL -függvényeket tradfns -nek, azaz „trad funs” -nak nevezzük. Itt a dfns -t és a tradfns -t a függvény figyelembevételével hasonlítják össze sieve: A bal oldalon egy dfn (a fentiek szerint ); a közepén egy tradfn használó vezérlési szerkezetek ; a jobb oldalon van egy tradfn segítségével GOTOS ( →), és sorban címkéket .
sieve←{
4≥⍵:⍵⍴0 0 1 1
r←⌊0.5*⍨n←⍵
p←2 3 5 7 11 13 17 19 23 29 31 37 41 43
p←(1+(n≤×⍀p)⍳1)↑p
b← 0@1 ⊃ {(m⍴⍵)>m⍴⍺↑1 ⊣ m←n⌊⍺×≢⍵}⌿ ⊖1,p
{r<q←b⍳1:b⊣b[⍵]←1 ⋄ b[q,q×⍸b↑⍨⌈n÷q]←0 ⋄ ∇ ⍵,q}p
}
|
∇ b←sieve1 n;i;m;p;q;r :If 4≥n ⋄ b←n⍴0 0 1 1 ⋄ :Return ⋄ :EndIf r←⌊0.5*⍨n p←2 3 5 7 11 13 17 19 23 29 31 37 41 43 p←(1+(n≤×⍀p)⍳1)↑p b←1 :For q :In p ⋄ b←(m⍴b)>m⍴q↑1 ⊣ m←n⌊q×≢b ⋄ :EndFor b[1]←0 :While r≥q←b⍳1 ⋄ b[q,q×⍸b↑⍨⌈n÷q]←0 ⋄ p⍪←q ⋄ :EndWhile b[p]←1 ∇ |
∇ b←sieve2 n;i;m;p;q;r →L10 ⍴⍨ 4<n ⋄ b←n⍴0 0 1 1 ⋄ →0 L10: r←⌊0.5*⍨n p←2 3 5 7 11 13 17 19 23 29 31 37 41 43 p←(1+(n≤×\p)⍳1)↑p i←0 ⋄ b←1 L20: b←(m⍴b)>m⍴p[i]↑1 ⊣ m←n⌊p[i]×≢b →L20 ⍴⍨ (≢p)>i←1+i b[1]←0 L30: →L40 ⍴⍨ r<q←b⍳1 ⋄ b[q,q×⍸b↑⍨⌈n÷q]←0 ⋄ p⍪←q ⋄ →L30 L40: b[p]←1 ∇ |
- A dfn lehet névtelen ; egy tradfn -t meg kell nevezni.
- Egy dfn -t a assignment (
←) nevez ; egy tradfn -t úgy neveznek el, hogy beágyazzák a nevet a függvény ábrázolásába, és alkalmaznak⎕fx(rendszerfüggvényt) erre az ábrázolásra. - A dfn operánsabb, mint a tradfn (lásd az előző tételeket: a tradfn -t meg kell nevezni; a tradfn -t beágyazással nevezik el ...).
- A dfn -ben hozzárendelt nevek alapértelmezés szerint helyiek ; a tradfn -ben hozzárendelt nevek globálisak, hacsak nincs megadva a helyi listában.
- A dfn -ben lévő helyiek lexikális hatókörrel rendelkeznek ; A tradfn -ben élő helyiek dinamikus hatókörrel rendelkeznek , amelyek a hívott függvényekben láthatók, hacsak nem árnyékolja őket a helyiek listája.
- A dfn argumentumai meg vannak nevezve
⍺,⍵és a dop operandusai meg vannak nevezve⍺⍺és⍵⍵; a tradfn argumentumai és operandusai bármilyen nevet tartalmazhatnak, az első sorban megadva. - A dfn eredménye (ha van) névtelen; a tradfn eredménye (ha van) meg van nevezve a fejlécében.
- A ⍺ alapértelmezett értéke tisztábban van megadva, mint a tradfn bal argumentuma.
-
A rekurzió egy dfn hajtjuk hivatkozva
∇, vagy∇∇vagy a hajó nevét; a rekurzió a tradfn -ben a nevének meghívásával valósul meg. -
Az áramlásszabályozást a dfn -ben védők és funkcióhívások végzik; hogy egy tradfn -ben a vezérlőstruktúrák és a
→(goto) és vonalcímkék . - Egy olyan kifejezés értékelése a dfn -ben, amely nem végződik hozzárendeléssel, visszatérést eredményez a dfn -ből; egy sor értékelése a tradfn -ben, amely nem végződik hozzárendeléssel vagy goto -val, megjeleníti a sor eredményét.
- A dfn visszatér a hozzárendeléssel nem végződő kifejezés kiértékelésénél, a védett kifejezés értékelésénél vagy az utolsó kifejezés után; egy tradfn visszatér a
→(goto) 0. sorra vagy egy nem létező sorra, vagy a vezérlőstruktúra kiértékelésekor , vagy az utolsó sor után.:Return - Az egyszerűbb áramlásszabályozás a dfn -ben megkönnyíti a farok rekurzió észlelését és megvalósítását, mint a tradfn -ben.
- A dfn hívhat tradfn -t és fordítva ; a dfn definiálható egy tradfn -ben, és fordítva .
Történelem
Kenneth E. Iverson , az APL feltalálója elégedetlen volt a felhasználói funkciók (tradfns) meghatározásának módjával. 1974 -ben kitalálta a "formális függvénydefiníciót" vagy a "közvetlen meghatározást". A közvetlen meghatározás két vagy négy részből áll, kettősponttal elválasztva:
name : expression
name : expression0 : proposition : expression1
Közvetlen meghatározáson belül ⍺a bal és ⍵a jobb érvet jelöli . Az első esetben expressionaz eredmény a függvény eredménye; második esetben a függvény eredménye az, hogy expression0ha propositionaz érték 0 -ra, vagy expression1ha 1 -re értékel. A közvetlen definíción belüli hozzárendelések dinamikusan lokálisak . A közvetlen meghatározás használatára példák találhatók az 1979 -es Turing -díj előadásában, valamint könyvekben és pályázati dokumentumokban.
A közvetlen meghatározás túlságosan korlátozott volt a nagyobb rendszerekben való használatra. Az ötleteket több szerző továbbfejlesztette több munkában, de az eredmények nehézkesek voltak. Ezek közül a Bunda 1987 -es "alternatív APL -függvénydefiníciója" került a legközelebb a jelenlegi létesítményekhez, de hibás a meglévő szimbólumokkal való konfliktusokban és a hibakezelésben, amelyek gyakorlati nehézségeket okoztak volna, és soha nem valósult meg. A különböző javaslatok fő párlatai az alábbiak voltak: a) a definiált funkció névtelen, a későbbi elnevezést (ha szükséges) hozzárendeléssel hajtják végre; b) a funkciót szimbólum jelöli, és ezáltal lehetővé teszi a névtelen rekurziót .
1996 -ban John Scholes, a Dyalog Limited cég kitalálta a közvetlen funkciókat (dfns). Az ötletek 1989 -ben keletkeztek, amikor a The Computer Journal funkcionális programozásról szóló különszámát olvasta . Ezt követően tanulmányozta a funkcionális programozást, és erősen motivált ("beteg a vágytól", mint Yeats ), hogy ezeket az ötleteket az APL -hez juttassa. Kezdetben lopakodva tevékenykedett, mert attól tartott, hogy a változtatásokat túl radikálisnak és a nyelv szükségtelen bonyolításának ítélhetik; más megfigyelők azt mondják, hogy lopakodva tevékenykedett, mert Dyalog kollégái nem voltak annyira elragadtatva, és azt hitték, hogy csak vesztegeti az idejét, és bajt okoz az embereknek. A Dfns -t először az APL '96 konferencián a Dyalog Vendor Forum -ban mutatták be, és 1997 elején adták ki a Dyalog APL -ben. Az elfogadás és az elismerés lassan érkezett. Még 2008 -ban, a Dyalog 25 éves kiadványában, amely a Dyalog Limited 25. évfordulóját ünnepli, a dfns -ek alig kerültek említésre (kétszer „dinamikus funkciók” -ként és részletes kidolgozás nélkül). 2019 -től a dfns -ek a Dyalog APL, a NARS2000 és az ngn/apl alkalmazásban kerülnek bevezetésre. Kulcsszerepet játszanak a grafikus feldolgozó egység (GPU) számítási képességeinek kiaknázásában is .
Hivatkozások
Külső linkek
- Hivatalos honlap , Dyalog