Obsah
1. Programovací jazyk APL, kombinátory a point-free style
2. Od výrazů s explicitně zapsanými proměnnými k point-free stylu
3. Refaktoring uživatelem definovaných funkcí tak, aby se využil point-free styl
4. Zobrazení stromové struktury volání funkcí ve vláčku
5. S-kombinátor a „vláčky“ v APL
6. Výpočet matice s malou násobilkou
7. Symboly ⊢ a ⊣ v APL a S-kombinátor
8. Výpočet průměrné hodnoty prvků vektoru
9. Vláček se dvěma vagony – atop
12. Příklad použití – nalezení nejdelšího řetězce
13. Nalezení všech výskytů podřetězce v řetězci
15. Předchozí články o rozsáhlém světu „array programmingu“
1. Programovací jazyk APL, kombinátory a point-free style
„Simplicity and elegance are unpopular because they require hard work and discipline to achieve and education to be appreciated.“
Edsger Dijkstra
V pořadí již jedenáctém článku věnovaném programovacím jazykům z oblasti „array programmingu“ (viz též odkazy uvedené v devatenácté kapitole) se ještě jednou vrátíme ke slavnému programovacímu jazyku APL, za jehož vývojem stál Kenneth E. Iverson. Ukážeme si totiž, jak se v nových verzích APL (mezi které je zapotřebí započítat především Dyalog APL atd.) používá programovací technika nazývaná point-free style nebo též tacit programming, s jejímiž základy jsme se již seznámili v článku Programovací technika nazvaná tacit programming. Ukázky sice budou založeny na jazyku APL, ovšem většinu myšlenek je možné přenést například do Haskellu, který se (možná kupodivu) v tomto ohledu programovacímu jazyku APL do značné míry podobá a i proto je možné v Haskellu mnoho algoritmů zapisovat velmi elegantním způsobem.
Přesný a přitom dostatečně jednoznačný český ekvivalent označení tacit programming mě nenapadá a proto i v dnešním článku raději zůstanu u termínu anglického, který se ostatně snadněji vyhledává. Co se ovšem pod názvy tacit programming nebo point-free style skrývá? Jedná se o styl zápisu bloků programů (typicky jednotlivých výrazů, ale i uživatelských funkcí popř. sekvencí funkcí, někdy o zápis dekorátorů), ve kterých se nachází volání jiných funkcí, ovšem bez explicitního udání jmen jejich argumentů (parametrů). A nejenom to – většinou není naznačen ani počet argumentů. Proč by se však tacit programming měl používat, resp. jaká je jeho přednost? Základní idea spočívá v tom, že se seskupením funkcí popř. operátorů vytvoří abstraktnější funkce nebo operátor, takže je možné v programovacím jazyce vybaveném relativně základními operacemi vytvářet vyšší úrovně abstrakce podle potřeb programátora, a to za použití snadno pochopitelných a testovatelných prostředků a idiomů – bez nutnosti zápisu „zbytečností“, mezi něž patří názvy formálních i skutečných parametrů atd.
2. Od výrazů s explicitně zapsanými proměnnými k point-free stylu
Před ukázkou složitějších programových konstrukcí si ukažme, jak se v programovacím jazyce APL vyhodnocují takzvané monadické funkce. Jedná se o funkce, které mají jediný operand, jenž je zapisovaný za jméno funkce (tedy napravo od jména funkce či od jejího symbolu). Podívejme se na trojici standardních monadických funkcí, konkrétně na funkce pro otočení znaménka operandu, výpočet převrácené hodnoty a výpočet absolutní hodnoty:
-10 ¯10 ÷10 0.1 |10 10 |¯10 10
Samozřejmě nám nic nebrání v předání výsledné hodnoty funkce do funkce jiné. Můžeme tedy například zapsat výpočet: otočení znaménka následované výpočtem převrácené hodnoty a výpočtem absolutní hodnoty z výsledku:
|(÷(-3)) 0.3333333333
Funkce se v programovacím jazyce APL vyhodnocují zprava doleva, což znamená, že se mnohdy (prakticky vždy) obejdeme bez nutnosti použití závorek. Výpočet převrácené hodnoty následovaný otočením znaménka výsledku lze zapsat takto (ve druhém výrazu je ¯10 konstantou se zápornou hodnotou):
-÷10 ¯0.1 -÷¯10 0.1
Nejsme ovšem omezeni pouze na dvě monadické funkce, ale můžeme použít funkce tři či více funkcí:
-÷-3 0.3333333333
Jazyk APL je polním jazykem, proto prakticky všechny výpočty můžeme provádět s prvky polí (zde s prvky vektoru). Týká se to i monadických funkcí zmíněných výše:
-÷ 1 2 3 4 5 ¯1 ¯0.5 ¯0.3333333333 ¯0.25 ¯0.2
A nakonec si ukažme modifikaci předchozího příkladu, nyní s využitím funkce nazvané indices, která se zapisuje symbolem ⍳ (jedná se vlastně o obdobu generátoru range). Vypočteme opačné hodnoty z převrácených hodnot 1 až 10:
-÷⍳10 ¯1 ¯0.5 ¯0.3333333333 ¯0.25 ¯0.2 ¯0.1666666667 ¯0.1428571429 ¯0.125 ¯0.1111111111 ¯0.1
3. Refaktoring uživatelem definovaných funkcí tak, aby se využil point-free styl
V této kapitole si ukážeme, jakým způsobem je možné modifikovat uživatelské funkce tak, aby se namísto klasických funkcí s parametry využil point-free styl, tedy zápis „větší funkce“ bez parametrů – pouhým uvedením jiných (jednodušších) funkcí. Připomeňme si opět, jak vypadá zápis monadické funkce (tedy funkce s jediným parametrem) v programovacím jazyku APL. Tělo funkce je uzavřeno do složených závorek a pravý (jediný) parametr takové funkce se jmenuje ⍵ (u dyadických funkcí je první parametr pojmenován ⍺ a druhý opět ⍵, což je elegantní).
Funkce, která vypočte absolutní hodnotu parametru, z výsledku vypočte převrácenou hodnotu a nakonec otočí znaménko, bude vypadat následovně (původně anonymní funkce je přiřazena symbolu foo):
foo ← {-(÷(|⍵))}
Funkci si snadno otestujeme:
foo 3 ¯0.3333333333
Vzhledem k tomu, že uvnitř uživatelské funkce se používají pouze monadické funkce, můžeme všechny vnitřní (kulaté) závorky odstranit:
bar ← {-÷|⍵} bar 3 ¯0.3333333333
Z klasické funkce můžeme vytvořit i „vláček“ (train), a to konkrétně odstraněním složených závorek i odstraněním jména parametru ⍵ (ten nelze odstranit vždy, ovšem nyní ano):
baz ← -(÷(|)) baz 3 ¯0.3333333333
Vnitřní závorky okolo funkce | (absolutní hodnota) nejsou nezbytné:
baz ← -(÷|) baz 3 ¯0.3333333333
4. Zobrazení stromové struktury volání funkcí ve vláčku
Pokud ovšem z výše uvedeného vláčku odstraníme i druhý pár kulatých závorek, bude výpočet nekorektní, resp. přesněji řečeno bude provádět něco jiného, než jsme měli na mysli:
baz ← -÷| baz 3 ¯1
Proč tomu tak je? Jednou z vlastností programovacího jazyka APL je fakt, že jeden symbol, například ÷, většinou představuje jak monadickou funkci (zde výpočet převrácené hodnoty), tak i funkci dyadickou (zde konkrétně podíl obou parametrů). To představuje problém ve výše uvedeném zápisu -÷|, neboť všechny tři symboly představují jak monadické, tak i dyadické funkce a parser jazyka APL dá v tomto případě přednost funkcím dyadickým (což má svůj hlubší význam vysvětlený dále).
Způsob chápání zápisu interpretrem jazyka APL zjistíme snadno – na vstup zadáme přímo daný výraz bez parametrů. V tomto případě Dyalog APL vykreslí stromovou strukturu, z níž by mělo být zřejmé, jak parser zapsaný výraz pochopil. Můžeme si to snadno otestovat:
-÷ ┌┴┐ - ÷ -(÷|) ┌┴─┐ - ┌┴┐ ÷ | -÷| ┌─┼─┐ - ÷ |
5. S-kombinátor a „vláčky“ v APL
V moderních dialektech programovacího jazyka APL nalezneme, podobně jako například již ve zmíněném Haskellu, podporu pro takzvaný S-kombinátor. Jedná se o způsob zkrácení zápisů výrazů s trojicí funkcí, z nichž funkce prostřední musí být dyadická a funkce nalevo a napravo mohou být monadické nebo dyadické. Konkrétně se jedná o následující struktury výrazů:
(f ⍵) g (h ⍵)
- ⍵ je parametr předávaný jak funkci f, tak i funkci h
- f je monadická funkce s jediným parametrem ⍵
- h je monadická funkce s jediným parametrem ⍵
- g je dyadická funkce, které se předají výsledky z funkce f i h
Taktéž se může jednat o trojici dyadických funkcí:
(⍺ f ⍵) g (⍺ h ⍵)
:
- ⍺ je parametr předávaný jak funkci f, tak i funkci h
- ⍵ je parametr předávaný jak funkci f, tak i funkci h
- f je dyadická funkce se dvěma parametry ⍺ a ⍵
- h je dyadická funkce se dvěma parametry ⍺ a ⍵
- g je dyadická funkce, které se předají výsledky z funkce f i h
Důležité je, že díky podpoře S-kombinátoru v moderním APL je možné zápis (monadický vláček):
(f ⍵) g (h ⍵)
Nahradit za mnohem kratší zápis:
(f g h) ⍵
Totéž platí pro dyadický vláček:
(⍺ f ⍵) g (⍺ h ⍵)
Ten je možné nahradit zápisem:
⍺ (f g h) ⍵
Struktura výrazu (f g h) je jazykem APL pochopena takto:
┌─┼─┐
Z tohoto důvodu se vláčku se třemi vagony říká fork, i když údernější název by byl trident.
6. Výpočet matice s malou násobilkou
Abychom si blíže vysvětlili, jak lze v S-kombinátoru využít jak dyadické funkce (s levým i pravým operandem/parametrem), tak i funkce monadické (pouze s pravým operandem), zaměříme se na relativně jednoduchý příklad – na výpočet a tisk matice s malou násobilkou. Budeme tedy chtít, aby se v matici objevily všechny možné kombinace vstupních hodnot od 1 do 10. Takový výpočet lze realizovat snadno s využitím operátoru outer product použitého společně s funkcí součinu (funkce v APL mají stejný význam jako operátory v jiných jazycích; naproti tomu operátory v APL většinou odpovídají konstrukcím typu foreach, apply, filter či reduce). Na levé i na pravé straně vnějšího součinu budou vektory s hodnotami od 1 do 10:
(⍳10) ∘.× (⍳10)
Výsledek tohoto výpočtu bude skutečně obsahovat celou malou násobilku:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
Kombinace ∘.× tvoří funkci se dvěma parametry (levým a pravým), tedy funkci dyadickou. Naproti tomu funkce indices zapisovaná znakem ⍳ je funkcí monadickou. Strukturu stromu pro vyhodnocení si pochopitelně můžeme opět snadno zobrazit:
(⍳ ∘.× ⍳) ┌─┼─┐ ⍳ . ⍳ ┌┴┐ ∘ ×
Závorky okolo celého výrazu nejsou nutné, tedy:
⍳ ∘.× ⍳ ┌─┼─┐ ⍳ . ⍳ ┌┴┐ ∘ ×
A ani mezery nemají v APL žádný význam, což znamená, že výraz lze zapsat takto:
⍳∘.×⍳ ┌─┼─┐ ⍳ . ⍳ ┌┴┐ ∘ ×
Tento výraz (jenž je zapsaný „vláčkem“) použijeme pro výpočet tabulky (resp. matice) s malou násobilkou:
(⍳∘.×⍳)10
S výsledkem:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
7. Symboly ⊢ a ⊣ v APL a S-kombinátor
V souvislosti s S-kombinátorem a především pak s forkem se někdy setkáme s použitím symbolů ⊢ a ⊣. Tyto symboly se nazývají same right a same left; v zápisu vláčku nahrazují konkrétní jména parametrů, tedy ⍺ a ⍵. Příkladem může být použití s funkcemi – a -:
(⊢--)
Podívejme se na nějaký příklad. Předpokládejme, že je nadefinována funkce inc:
inc ← {1+⍵}
S tímto chováním:
inc 10 11
Můžeme se pokusit vytvořit tento vláček:
⊢×inc ┌─┼─┐ ⊢ × {1+⍵}
Který ukazuje, že se pravý parametr použije jako funkce h, která vrátí hodnotu tohoto parametru (bez dalších modifikací):
(⊢×inc)1 2 (⊢×inc)2 6 (⊢×inc)10 110
Nic nám samozřejmě nezabraňuje ve vytvoření forku, který obsahuje další fork jako svůj podvýraz:
⊢×inc(⊢×inc) ┌─┴─┐ ⊢ ┌─┼───────┐ × {1+⍵} ┌─┼─┐ ⊢ × {1+⍵}
Test:
(⊢×inc(⊢×inc))2 7
(⊣*⊢) ┌─┼─┐ ⊣ * ⊢ 2(⊣*⊢)3 8 (⊢*⊣) ┌─┼─┐ ⊢ * ⊣ 2(⊢*⊣)3 9
8. Výpočet průměrné hodnoty prvků vektoru
Další demonstrační příklad se při představování možností programovacího jazyka APL používá velmi často. Jedná se o funkci určenou pro výpočet průměrné hodnoty všech prvků uložených ve vstupním vektoru:
Avg←{(+⌿⍵)÷≢⍵}
Výpočet je rozdělen na tři části:
- Součet všech prvků výrazem (+⌿⍵) (funkce + je použita společně s operátorem ⌿ neboli reduce first).
- Zjištění počtu všech prvků ve vstupním vektoru výrazem ≢⍵ (funkce ≢ se nazývá tally a její symbol po rotaci o 90° připomíná čárky na účtu s počtem objednaných piv).
- Podíl výsledků obou výše zmíněných výrazů dyadickou funkcí÷.
Novou funkci si můžeme snadno otestovat:
Avg 1 2 3 4 5 3
Samotné tělo funkce po odstranění jména parametru lze realizovat vláčkem:
+⌿÷≢ ┌─┼─┐ ⌿ ÷ ≢ ┌─┘ +
Což znamená, že funkci lze velmi snadno přepsat do point-free podoby:
Avg←+⌿÷≢ Avg 1 2 3 4 5 3
9. Vláček se dvěma vagony – atop
Vláček se třemi vagony neboli fork byl popsán v rámci předchozích kapitol. Z tohoto vláčku můžeme odvodit vláček se dvěma vagony. Vyjdeme přitom z původní podoby výrazu, který bylo možné přepsat na fork:
(⍺ f ⍵) g (⍺ h ⍵)
V případě, že vynecháme levou část s funkcí f, znamená to, že zůstane pouze výraz s monadickou funkcí g:
g (⍺ h ⍵)
Ten lze převést na vláček se dvěma vagony:
⍺ (g h) ⍵
V tomto případě se namísto názvu fork používá označení atop, protože funkce g je vyhodnocena s hodnotou, která vznikne („on the top of“) vyhodnocením funkce h.
10. Vláček se čtyřmi vagony
Zdaleka nejčastěji se v praxi setkáme s vláčkem, který obsahuje dvě funkce – dva vagony (tedy atop) nebo tři vagony (tedy fork). Co se ovšem stane ve chvíli, kdy se pokusíme zapsat vláček se čtyřmi funkcemi (vagony)? Bude se tedy jednat o zápis:
f g h j ⍵
nebo (pravděpodobně ve většině případů):
⍺ f g h j ⍵
Parser programovacího jazyka APL v tomto případě rozpozná fork g h j a vyhodnotí ho s využitím argumentů ⍺ a ⍵. Výsledkem bude nějaká hodnota X. Z původního výrazu nám tedy zbývá pouze f X, což mimochodem znamená, že funkce f musí být monadická.
To tedy znamená, že ⍺ f g h j ⍵ se vyhodnotí jako:
f ((⍺ g ⍵) h (⍺ j ⍵))
Podívejme se nyní na praktické použití. V předchozích kapitolách jsme si ukázali vláček pro výpočet průměrné hodnoty prvků uložených ve vektoru. Pro větší přehlednost jsou jednotlivé funkce odděleny mezerou, i když to není nutné:
+⌿ ÷ ≢ ┌─┼─┐ ⌿ ÷ ≢ ┌─┘ +
Tento vláček můžeme snadno rozšířit o funkci | tak, aby výsledkem výpočtu byla vždy kladná hodnota:
| +⌿ ÷ ≢ ┌─┴─┐ | ┌─┼─┐ ⌿ ÷ ≢ ┌─┘ +
Převeďme vláček do podoby pojmenované funkce:
AvgAbs ← | +⌿ ÷ ≢
Kterou si můžeme snadno otestovat:
AvgAbs 1 2 3 4 2.5 AvgAbs ¯1 ¯2 ¯3 ¯4 2.5
11. Vláček s pěti vagony
Podívejme se ještě na použití vláčku s pěti vagony (funkcemi), tedy na výraz ve tvaru:
⍺ f g h j k ⍵
Jeho struktura vypadá následovně (pomůžeme se pěti dyadickými funkcemi):
f←+ g←- h←× j←÷ k←* f g h j k ┌─┼───┐ + - ┌─┼─┐ × ÷ *
Ze struktury je jasně patrné, že se nejdříve vyhodnotí poslední tři funkce h j k tvořící klasický fork. A výsledek se stává pravým parametrem funkce g, tedy získáme ⍺ f g X, což je vzor, který již umíme řešit.
12. Příklad použití – nalezení nejdelšího řetězce
Díky podpoře spojování funkcí do vláčků lze některé algoritmy skutečně zapsat idiomatickým způsobem. Podívejme se například na to, jak lze vytvořit funkci, která ve vektoru řetězců nalezne nejdelší řetězec. Prvním krokem bude použití ≢¨ neboli tally each, což je funkce tally modifikovaná operátorem ¨ tak, aby se aplikovala na všechny prvky řetězce:
≢¨ 'foo' 'bar' 'xyzzy' '' 3 3 5 0
Na výsledný vektor s délkami řetězců můžeme aplikovat ⌈/ neboli max reduce (se známým významem):
⌈/ 3 3 5 0 5
Takto vypadá vláček získaný spojením obou výše popsaných funkcí (každá vytvořena s využitím operátoru):
⌈/ ≢¨ ┌─┴─┐ / ¨ ┌─┘ ┌─┘ ⌈ ≢
Výsledný vláček pojmenujeme – vytvoříme z něho funkci:
MaxLen ← ⌈/ ≢¨
Nyní si můžeme funkci snadno otestovat:
MaxLen 'foo' 'bar' 'xyzzy' '' 5
Alternativně je samozřejmě možné si jednotlivé vagony ve vláčku pojmenovat:
Lengths ← ≢¨ FindMax ← ⌈/ MaxLength ← FindMax Lengths
A otestovat:
MaxLength 'foo' 'bar' 'xyzzy' '' 5
FindMax Lengths ┌─┴─┐ / ¨ ┌─┘ ┌─┘ ⌈ ≢
13. Nalezení všech výskytů podřetězce v řetězci
Dalším příkladem bude vláček implementující nalezení všech výskytů podřetězce v řetězci. Vrátit by se měly indexy nalezených slov resp. podřetězců:
input ← 'War Is Peace, Freedom Is Slavery, and Ignorance Is Strength'
Začneme funkcí ⍷ neboli find. Ta vrátí vektor pravdivostních hodnot, každou hodnotu pro každý znak ve vstupním řetězci:
'Is' ⍷ input 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
Výsledek předáme do funkce ⍸ neboli where. Ta v tomto případě vrací indexy nenulových prvků:
'Is' (⍸ ⍷) input 5 23 49
což je očekávaný výsledek.
Můžeme si otestovat i výsek z původního řetězce, abychom zjistili, zda jsou vrácené indexy korektní:
input[5 6, 23 24, 49 50] IsIsIs
nebo spíše:
indices ← 'Is' (⍸ ⍷) input indices 5 23 49 indices+1 6 24 50 ∊ (indices ,¨ indices+1) 5 6 23 24 49 50 input[∊ (indices ,¨ indices+1)] IsIsIs
Vraťme se k funkci pro nalezení všech podřetězců ve vstupním řetězci. Tuto funkci si můžeme pojmenovat a opět otestovat:
FindAll ← ⍸ ⍷ 'Is' FindAll input 5 23 49
Můžeme si zobrazit i její strukturu (jedná se o atop):
FindAll ┌┴┐ ⍸ ⍷
A můžeme si vytvořit i vláček, který bude tuto funkci uvnitř obsahovat, například:
⊢FindAll⊣ ┌──┼──┐ ⊢ ┌┴┐ ⊣ ⍸ ⍷
14. Shrnutí
Přidání podpory pro tacit programming do programovacího jazyka APL znamená poměrně výrazné zlepšení vyjadřovacích schopností tohoto jazyka (které jsou už tak velké). Týká se to zejména vláčku fork, protože kombinací většího množství funkcí aplikovaných na stejný parametr či dva parametry existuje v praxi relativně velké množství. Díky této podpoře lze v APL psát idiomatický kód, který neobsahuje nepodstatné „maličkosti“ typu deklarace těla funkce, explicitního zápisu jmen parametrů atd. Navíc je fork součástí i některých dalších programovacích jazyků, například Haskellu (a samozřejmě programovacího jazyka J), takže se nejedná o nějakou raritu, ale naopak o akceptovaný (i když ne široce) přístup k zápisu algoritmů.
15. Předchozí články o rozsáhlém světu „array programmingu“
Programovacími jazyky, které jsou z větší či menší míry odvozeny od APL, jsme se již na stránkách Roota zabývali v několika článcích (a samozřejmě i v dnešním článku). Odkazy na tyto články naleznete pod odstavcem:
- Jazyky umožňující operace s poli aneb rozsáhlý svět „array programmingu“
https://www.root.cz/clanky/jazyky-umoznujici-operace-s-poli-aneb-rozsahly-svet-bdquo-array-programmingu-ldquo/ - Specializované jazyky pro práci s N-dimenzionálními poli: jazyk J
https://www.root.cz/clanky/specializovane-jazyky-pro-praci-s-n-dimenzionalnimi-poli-jazyk-j/ - Programovací jazyky odvozené od APL: BQN a ivy aneb 1~×`1↓↕10
https://www.root.cz/clanky/programovaci-jazyky-odvozene-od-apl-bqn-a-ivy-aneb-1–1–10/ - Programovací jazyk K: důkaz, že mezi námi žijí mimozemšťané
https://www.root.cz/clanky/programovaci-jazyk-k-dukaz-ze-mezi-nami-ziji-mimozemstane/ - Programovací jazyk K: důkaz, že mezi námi žijí mimozemšťané (dokončení)
https://www.root.cz/clanky/programovaci-jazyk-k-dukaz-ze-mezi-nami-ziji-mimozemstane-dokonceni/ - Nial Array Language: další z jazyků inspirovaných APL
https://www.root.cz/clanky/nial-array-language-dalsi-z-jazyku-inspirovanych-apl/ - Programování mainframů: jazyk APL
https://www.root.cz/clanky/programovani-mainframu-jazyk-apl/ - Programovací jazyk APL: programování bez smyček
https://www.root.cz/clanky/programovaci-jazyk-apl-programovani-bez-smycek/ - Programovací jazyk APL – dokončení
https://www.root.cz/clanky/programovaci-jazyk-apl-dokonceni/ - Oslava 55 let od vzniku první implementace jazyka APL
https://www.root.cz/clanky/oslava-55-let-od-vzniku-prvni-implementace-programovaciho-jazyka-apl/
16. Odkazy na Internetu
- Tacit programming (APL Wiki)
https://aplwiki.com/wiki/Tacit_programming - Function trains
https://mlochbaum.github.io/BQN/doc/train.html - Tacit programming (Wikipedia)
https://en.wikipedia.org/wiki/Tacit_programming - Beyond Functional Programming: Manipulate Functions with the J Language
https://www.adamtornhill.com/articles/jlang/beyondfunctional.html - Real World Uses of Tacit Programming: Part 1 of 2
https://medium.com/@jesterxl/real-world-uses-of-tacit-programming-part-1-of-2-f2a0c3f9e00c - Programovací jazyk Forth a zásobníkové procesory
http://www.root.cz/clanky/programovaci-jazyk-forth-a-zasobnikove-procesory/ - Seriál Programovací jazyk Forth
http://www.root.cz/serialy/programovaci-jazyk-forth/ - Programovací jazyk Factor
http://www.root.cz/clanky/programovaci-jazyk-factor/ - Grafický metaformát PostScript
http://www.root.cz/clanky/graficky-metaformat-postscript/ - Factor: revoluce v programování nebo propadák?
https://www.root.cz/clanky/factor-revoluce-v-programovani-nebo-propadak/ - Integrované vývojové prostředí Factoru
https://www.root.cz/clanky/integrovane-vyvojove-prostredi-factoru/ - Programujeme ve Factoru
https://www.root.cz/clanky/programujeme-ve-factoru/ - Joy: radost z programování
https://www.root.cz/clanky/joy-radost-z-programovani/ - Joy: programovací jazyk od protinožců
https://www.root.cz/clanky/joy-programovaci-jazyk-od-protinozcu/ - Jazyk Joy a rekurzivní kombinátory
https://www.root.cz/clanky/jazyk-joy-a-rekurzivni-kombinatory/ - Point-Free or Die: Tacit Programming in Haskell and Beyond
https://www.thestrangeloop.com/2016/point-free-or-die-tacit-programming-in-haskell-and-beyond.html - Threading macro (dokumentace k jazyku Clojure)
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-> - Understanding the Clojure → macro
http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/ - Transducers
https://clojure.org/reference/transducers - dc (computer program)
https://en.wikipedia.org/wiki/Dc_%28computer_program%29 - dc (na Esolang)
http://esolangs.org/wiki/Dc - Relational pipes
https://relational-pipes.globalcode.info/v0/ - Roura (Unix)
https://cs.wikipedia.org/wiki/Roura_(Unix) - Roura (software)
https://cs.wikipedia.org/wiki/Roura_(software) - APL Wiki
https://aplwiki.com/wiki/ - The Array Cast
https://www.arraycast.com/episodes/episode-03-what-is-an-array - EnthusiastiCon 2019 – An Introduction to APL
https://www.youtube.com/watch?v=UltnvW83_CQ - Dyalog
https://www.dyalog.com/ - Try APL!
https://tryapl.org/ - APL na replit
https://replit.com/languages/apl - Advent of Code 2020 in APL!
https://www.youtube.com/watch?v=0RQFW6P1Tt0 - Python vs APL (1 Problem)
https://www.youtube.com/watch?v=APdKFJkmBbM - APL Wins (vs C++, Java & Python)
https://www.youtube.com/watch?v=59vAjBS3yZM - A Tour de Force of APL in 16 Expressions by Roger Hui
https://www.youtube.com/watch?v=e0rywC7-i0U - Conway's Game Of Life in APL
https://www.youtube.com/watch?v=a9×AKttWgP4 - A List of companies that use Array Languages (J, K, APL, q)
https://github.com/interregna/arraylanguage-companies - APL – one of the greatest programming languages ever
http://www.vaxman.de/publications/apl_slides.pdf - „The J Programming Language“ by Tracy Harms (2013)
https://www.youtube.com/watch?v=RWYkx6-L04Q - Dyalog Modern Programming Language, Morten Kromberg, Talks at Google
https://www.youtube.com/watch?v=PlM9BXfu7UY - The J Language: Consistency, Adjacency, and Solution-Oriented Programming – Tracy Harms
https://www.youtube.com/watch?v=gLULrFY2-fI - Un-directed programming
https://www.sacrideo.us/un-structured-programming/ - Concatenative programming language
https://en.wikipedia.org/wiki/Concatenative_programming_language - Repositáře s jazykem Joy
https://github.com/joy-language - J language: Chapter 8: Composing Verbs
https://www.jsoftware.com/help/learning/08.htm - J language: Chapter 9: Trains of Verbs
https://www.jsoftware.com/help/learning/09.htm - Combinatory logic
https://en.wikipedia.org/wiki/Combinatory_logic - Four Features of Modern APL
https://www.youtube.com/watch?v=cBuqDHA-zEI - How to read trains in Dyalog APL code
https://www.youtube.com/watch?v=kt4lMZbn-so - Tacit programming
https://xpqz.github.io/cultivations/Trains.html - Function trains in APL
https://www.youtube.com/watch?v=A2LqqBosvY0 - Trainspotting (APL)
https://xpqz.github.io/learnapl/tacit.html - Train Spotting in Dyalog APL – Dyalog Webinar with Richard Park
https://www.youtube.com/watch?v=Enlh5qwwDuY