Jazyk APL, kombinátory, vláčky a point-free style

8. 11. 2022
Doba čtení: 18 minut

Sdílet

 Autor: A.Brudz, podle licence: CC-BY
V dalším článku o jazycích z oblasti „array programmingu“ se ještě jednou vrátíme k jazyku APL. Ukážeme si, jak se v nových verzích APL (Dyalog APL) používá elegantní technika nazývaná point-free style nebo též tacit programming.

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

10. Vláček se čtyřmi vagony

11. Vláček s pěti vagony

12. Příklad použití – nalezení nejdelšího řetězce

13. Nalezení všech výskytů podřetězce v řetězci

14. Shrnutí

15. Předchozí články o rozsáhlém světu „array programmingu“

16. Odkazy na Internetu

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.

Poznámka: poměrně často používám v článcích pojem „idiom“ pro ustálenou strukturu/notaci v daném obvyklou programovacím jazyce. Důsledné používání idiomů vede ke kódu, který je srozumitelný i pro další programátory (ovšem pro programátory v tomto jazyce – idiomy většinou nejsou snadno přenositelné). A nejenom to – v takovém kódu se obecně nachází menší množství logických chyb. Naopak nepoužití idiomu programátory zbytečně zmate.

2. Od výrazů s explicitně zapsanými proměnnými k point-free stylu

Poznámka na úvod: všechny dále uvedené demonstrační příklady si můžete otestovat ve webovém prostředí jazyka Dyalog APL (což je nejmodernější varianta APL). Toto prostředí je dostupné na adrese https://tryapl.org/.

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:

      
┌┴┐
- ÷
 
      -(÷|)
┌┴─┐
- ┌┴┐
  ÷ |
 
      -÷|
┌─┼─┐
- ÷ |
Poznámka: povšimněte si, že poslední dva výrazy mají skutečně odlišnou interní reprezentaci.

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 fh

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
  • h je dyadická funkce se dvěma parametry
  • g je dyadická funkce, které se předají výsledky z funkce fh

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
Poznámka: důležité je, že prostřední funkce je funkcí dyadickou. Pokud by tomu tak nebylo, nejednalo by se o S-kombinátor a musely by se použít závorky.

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
Poznámka: podobně lze využít i druhý symbol u dyadického vláčku. Viz následující (umělé) příklady ukazující použití otočených operandů u funkce pro výpočet n-té mocniny:
      (⊣*⊢)
┌─┼─┐
⊣ * ⊢
 
      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:

  1. Součet všech prvků výrazem (+⌿⍵) (funkce + je použita společně s operátorem neboli reduce first).
  2. 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).
  3. 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.

Poznámka: podobně se řeší i delší vláčky, které vždy v důsledku vedou na kombinace atop+fork nebo fork+fork
.

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
Poznámka: struktura vláčku zůstane zachována i v případě pojmenování vagonů:
      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:

bitcoin školení listopad 24

      ⊢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:

  1. 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/
  2. Specializované jazyky pro práci s N-dimenzionálními poli: jazyk J
    https://www.root.cz/clanky/spe­cializovane-jazyky-pro-praci-s-n-dimenzionalnimi-poli-jazyk-j/
  3. Programovací jazyky odvozené od APL: BQN a ivy aneb 1~×`1↓↕10
    https://www.root.cz/clanky/pro­gramovaci-jazyky-odvozene-od-apl-bqn-a-ivy-aneb-1–1–10/
  4. Programovací jazyk K: důkaz, že mezi námi žijí mimozemšťané
    https://www.root.cz/clanky/pro­gramovaci-jazyk-k-dukaz-ze-mezi-nami-ziji-mimozemstane/
  5. Programovací jazyk K: důkaz, že mezi námi žijí mimozemšťané (dokončení)
    https://www.root.cz/clanky/pro­gramovaci-jazyk-k-dukaz-ze-mezi-nami-ziji-mimozemstane-dokonceni/
  6. Nial Array Language: další z jazyků inspirovaných APL
    https://www.root.cz/clanky/nial-array-language-dalsi-z-jazyku-inspirovanych-apl/
  7. Programování mainframů: jazyk APL
    https://www.root.cz/clanky/pro­gramovani-mainframu-jazyk-apl/
  8. Programovací jazyk APL: programování bez smyček
    https://www.root.cz/clanky/pro­gramovaci-jazyk-apl-programovani-bez-smycek/
  9. Programovací jazyk APL – dokončení
    https://www.root.cz/clanky/pro­gramovaci-jazyk-apl-dokonceni/
  10. 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

  1. Tacit programming (APL Wiki)
    https://aplwiki.com/wiki/Ta­cit_programming
  2. Function trains
    https://mlochbaum.github.i­o/BQN/doc/train.html
  3. Tacit programming (Wikipedia)
    https://en.wikipedia.org/wi­ki/Tacit_programming
  4. Beyond Functional Programming: Manipulate Functions with the J Language
    https://www.adamtornhill.com/ar­ticles/jlang/beyondfuncti­onal.html
  5. 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
  6. Programovací jazyk Forth a zásobníkové procesory
    http://www.root.cz/clanky/programovaci-jazyk-forth-a-zasobnikove-procesory/
  7. Seriál Programovací jazyk Forth
    http://www.root.cz/serialy/pro­gramovaci-jazyk-forth/
  8. Programovací jazyk Factor
    http://www.root.cz/clanky/programovaci-jazyk-factor/
  9. Grafický metaformát PostScript
    http://www.root.cz/clanky/graficky-metaformat-postscript/
  10. Factor: revoluce v programování nebo propadák?
    https://www.root.cz/clanky/factor-revoluce-v-programovani-nebo-propadak/
  11. Integrované vývojové prostředí Factoru
    https://www.root.cz/clanky/integrovane-vyvojove-prostredi-factoru/
  12. Programujeme ve Factoru
    https://www.root.cz/clanky/pro­gramujeme-ve-factoru/
  13. Joy: radost z programování
    https://www.root.cz/clanky/joy-radost-z-programovani/
  14. Joy: programovací jazyk od protinožců
    https://www.root.cz/clanky/joy-programovaci-jazyk-od-protinozcu/
  15. Jazyk Joy a rekurzivní kombinátory
    https://www.root.cz/clanky/jazyk-joy-a-rekurzivni-kombinatory/
  16. 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
  17. Threading macro (dokumentace k jazyku Clojure)
    https://clojure.github.io/clo­jure/clojure.core-api.html#clojure.core/->
  18. Understanding the Clojure → macro
    http://blog.fogus.me/2009/09/04/un­derstanding-the-clojure-macro/
  19. Transducers
    https://clojure.org/referen­ce/transducers
  20. dc (computer program)
    https://en.wikipedia.org/wi­ki/Dc_%28computer_program%29
  21. dc (na Esolang)
    http://esolangs.org/wiki/Dc
  22. Relational pipes
    https://relational-pipes.globalcode.info/v0/
  23. Roura (Unix)
    https://cs.wikipedia.org/wi­ki/Roura_(Unix)
  24. Roura (software)
    https://cs.wikipedia.org/wi­ki/Roura_(software)
  25. APL Wiki
    https://aplwiki.com/wiki/
  26. The Array Cast
    https://www.arraycast.com/e­pisodes/episode-03-what-is-an-array
  27. EnthusiastiCon 2019 – An Introduction to APL
    https://www.youtube.com/wat­ch?v=UltnvW83_CQ
  28. Dyalog
    https://www.dyalog.com/
  29. Try APL!
    https://tryapl.org/
  30. APL na replit
    https://replit.com/languages/apl
  31. Advent of Code 2020 in APL!
    https://www.youtube.com/wat­ch?v=0RQFW6P1Tt0
  32. Python vs APL (1 Problem)
    https://www.youtube.com/wat­ch?v=APdKFJkmBbM
  33. APL Wins (vs C++, Java & Python)
    https://www.youtube.com/wat­ch?v=59vAjBS3yZM
  34. A Tour de Force of APL in 16 Expressions by Roger Hui
    https://www.youtube.com/wat­ch?v=e0rywC7-i0U
  35. Conway's Game Of Life in APL
    https://www.youtube.com/wat­ch?v=a9×AKttWgP4
  36. A List of companies that use Array Languages (J, K, APL, q)
    https://github.com/interreg­na/arraylanguage-companies
  37. APL – one of the greatest programming languages ever
    http://www.vaxman.de/publi­cations/apl_slides.pdf
  38. „The J Programming Language“ by Tracy Harms (2013)
    https://www.youtube.com/watch?v=RWYkx6-L04Q
  39. Dyalog Modern Programming Language, Morten Kromberg, Talks at Google
    https://www.youtube.com/wat­ch?v=PlM9BXfu7UY
  40. The J Language: Consistency, Adjacency, and Solution-Oriented Programming – Tracy Harms
    https://www.youtube.com/wat­ch?v=gLULrFY2-fI
  41. Un-directed programming
    https://www.sacrideo.us/un-structured-programming/
  42. Concatenative programming language
    https://en.wikipedia.org/wi­ki/Concatenative_programmin­g_language
  43. Repositáře s jazykem Joy
    https://github.com/joy-language
  44. J language: Chapter 8: Composing Verbs
    https://www.jsoftware.com/hel­p/learning/08.htm
  45. J language: Chapter 9: Trains of Verbs
    https://www.jsoftware.com/hel­p/learning/09.htm
  46. Combinatory logic
    https://en.wikipedia.org/wi­ki/Combinatory_logic
  47. Four Features of Modern APL
    https://www.youtube.com/wat­ch?v=cBuqDHA-zEI
  48. How to read trains in Dyalog APL code
    https://www.youtube.com/wat­ch?v=kt4lMZbn-so
  49. Tacit programming
    https://xpqz.github.io/cul­tivations/Trains.html
  50. Function trains in APL
    https://www.youtube.com/wat­ch?v=A2LqqBosvY0
  51. Trainspotting (APL)
    https://xpqz.github.io/le­arnapl/tacit.html
  52. Train Spotting in Dyalog APL – Dyalog Webinar with Richard Park
    https://www.youtube.com/wat­ch?v=Enlh5qwwDuY

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.