Obsah
2. Náhrada programových smyček pomocí operátorů
5. Tvorba uživatelských funkcí
6. Monadické uživatelské funkce
7. Dyadické uživatelské funkce
1. Operátor / (reduce)
V předchozích dvou částech seriálu o programovacím jazyku J jsme se seznámili se základními (primitivními) funkcemi tohoto jazyka, které představují základní stavební kameny všech vytvářených aplikací. Programovací jazyk J však kromě poměrně rozsáhlé řady primitivních funkcí obsahuje, podobně jako již popsaný jazyk APL, několik operátorů, pomocí nichž jsou funkce aplikovány nikoli na jeden či dva parametry, ale postupně na celé vektory nebo matice. Díky operátorům (význam tohoto slova je odlišný od významu, který toto slovo má v jiných jazycích) je možné eliminovat velké množství programových smyček a mnohdy tak například několikařádkovou proceduru zapsat pomocí jediného výrazu (viz druhou kapitolu). Jedním z nejdůležitějších operátorů jazyka J je operátor /, který jsme si již v jednodušší podobě představili při popisu jazyka APL. Tento operátor, který se zapisuje za identifikátor primitivní či uživatelské funkce, postupně danou funkci aplikuje na první dva prvky argumentu, dále ji aplikuje na průběžný výsledek a třetí prvek atd., do doby, než jsou všechny prvky argumentu zpracovány (jinými slovy – daná dyadická funkce je jakoby zapsána mezi všechny prvky předané datové struktury, počet operací je roven n-1 v případě, že předaný vektor má počet prvků n):
NB. Součet všech čísel v řadě od 1 do 10. + / 1 2 3 4 5 6 7 8 9 10 55 NB. Vektor hodnot můžeme vytvořit NB. taktéž s využitím generátoru NB. indexů (viz předchozí části NB. seriálu). Ovšem pozor - indexy NB. se generují od 0, nikoli od 1. + / i. 10 45 NB. Zde se již vektor skutečně vygeneruje NB. tak, že jeho první prvek má NB. jedničkovou hodnotu. + / 1 + i. 10 55
Operátor / je však samozřejmě možné použít i v kombinaci s libovolnou dyadickou funkcí – může se jednat jak o aritmetické funkce, tak i o funkce logické (booleovské), porovnávací (relační), maticové aj. Následují příklady použití některých těchto funkcí; nejprve funkcí booleovských aplikovaných na vektory binárních hodnot:
NB. Použití booleovské funkce "or" NB. (logický součet) +./ 0 0 0 0 +./ 0 0 0 1 1 +./ 1 1 1 1 1 NB. Použití booleovské funkce "and" NB. (logický součin) *./ 0 0 0 0 *./ 0 0 0 1 *./ 1 1 1 1 1 NB. Použití booleovské funkce ekvivalence =/ 0 0 0 0 1 =/ 0 0 0 1 =/ 1 1 1 1 1 NB. Použití booleovské funkce "xor" NB. (nonekvivalence) ~:/ 0 0 0 0 ~:/ 0 0 0 1 1 ~:/ 1 1 1 1
Mezi další dyadické funkce, které lze zkombinovat s operátorem /, patří například funkce pro výpočet (zjištění) minima, maxima, součinu (zde korespondujících prvků vektorů) a mocniny o zvoleném základu:
NB. Výběr nejmenšího prvku z vektoru. <. / 5 4 67 2 1 42 3 7 6 1 NB. Výběr největšího prvku z vektoru. >. / 5 4 67 2 1 42 3 7 6 67 NB. Jeden ze způsobů výpočtu skalárního NB. součinu dvou vektorů. +/ (1 2 3) * (1 2 3) 14 NB. Skalární součin dvou na sebe kolmých NB. vektorů je vždy nulový. +/ (1 0 0) * (0 1 0) NB. Výpočet prvních deseti mocnin NB. základu 2 (včetně 2^0). 2 ^ i. 10 1 2 4 8 16 32 64 128 256 512 NB. Suma prvních deseti mocnin NB. základu 2. Výsledek by měl NB. být roven: (2^(n+1))-1 + / 2 ^ i. 10 1023 NB. Výpočet známé úlohy se šachovnicí a semínky NB. kladenými na jednotlivá políčka šachovnice. 2 ^ i. 64 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1.04858e6 2.09715e6 4.1943e6 8.38861e6 1.67772e7 3.35544e7 6.71089e7 1.34218e8 2.68435e8 5.36871e8 1.07374e9 2.14748e9 4.29497e9 8.58993e9 1.71799e10 3.43597e10 6.87195... NB. Celkový počet všech semínek na šachovnici. + / 2 ^ i. 64 1.84467e19
2. Náhrada programových smyček pomocí operátorů
Ve druhé kapitole si pro ilustraci použití operátoru / v praxi ukážeme příklad převzatý z elektronické knihy „J for C Programmers“, ve kterém je předvedeno, jakým způsobem je možné pomocí operátoru / nalézt největší prvek v matici (zmíněná elektronická kniha je obsažena přímo v instalaci vývojového prostředí programovacího jazyka J). Nejprve si uveďme odpovídající céčkový program, který nalezne prvek s maximální hodnotou v (dvourozměrné) matici x, jejíž rozměry jsou uloženy v konstantách xsize0 a xsize1:
int i, j; float maxval = x[0][0]; for (i = 0; i&jt;=xsize0; ++i) { for (j = 0; j<=xsize1; ++j) { if (x[i][j] > maxval) { maxval = x[i][j]; } } }
V programovacím jazyku J lze maximální prvek v matici nalézt dvojí aplikací operátoru / zkombinovaného s funkcí >. (ta provádí výběr větší hodnoty z dvojice předaných parametrů, tj. jak skalárních hodnot, tak i vektorů popř. matic). První aplikace operátoru / slouží k výběru těch prvků na jednotlivých řádcích matice, které mají největší hodnotu, druhá aplikace pak již z tohoto mezivýsledku (tj. vektoru) vybere přímo maximální hodnotu, takže se celá sekvence zanořených smyček a podmíněného příkazu v programovacím jazyku J zmenší na jediný výraz. Ve skutečnosti je však možné podmíněný příkaz eliminovat i v céčkovém programu, stačí ho nahradit například voláním makra MAX, což však již není možné v příkladu uvedeném níže. Navíc si nikde nemusíme pamatovat rozměry pole (matice), neboť ty lze kdykoli za běhu programu zjistit:
NB. Nejprve si vytvoříme matici NB. s testovacími daty. matice =: 3 3 $ _4 + i.9 matice _4 _3 _2 _1 0 1 2 3 4 NB. Nalezneme největší prvek v matici NB. dvojím použitím operátoru / (<./) <./ matice 4
Druhý příklad je již poněkud složitější – nalezení sloupce, ve kterém se nachází prvek s maximální hodnotou –, ale při použití programovacího jazyka J se opět obejdeme bez nutnosti použití programových smyček a podmínek. Sloupec, ve kterém se prvek s největší hodnotou v matici nachází, lze zjistit s využitím dyadické funkce i. (index of), která vrací index prvního prvku obsahujícího danou hodnotu (prvním parametrem této funkce je většinou vektor, druhým parametrem hledaná hodnota). Povšimněte si především použití závorek, které eliminují nutnost dvojího použití mezivýsledku >./ matice v zapisovaném výrazu (viz též osmá kapitola, v níž se tímto tématem budeme zabývat podrobněji):
(i. >./) >./ matice
Céčkovský ekvivalent je stále mnohonásobně delší kvůli nutnosti použití programových smyček a podmínek:
int i, j, maxcol = 0; float maxval = x[0][0]; for (i = 0; i&jt;=xsize0; ++i) { for (j = 0; j<=xsize1; ++j) { if (x[i][j] > maxval) { maxval = x[i][j]; maxcol = j } } }
3. Dyadická forma operátoru /
Při popisu programovacího jazyka APL jsme se mj. zmínili i o operátoru „outer product“ zapisovaného dvojicí symbolů ◦. (kolečko+tečka) za nimiž následovalo jméno či symbol nějaké primitivní funkce popř. identifikátor uživatelské dyadické funkce. Tento operátor je založen na principu aplikace zvolené dyadické funkce na dvojici vektorů x a y, přičemž vybraná funkce je aplikována na všechny možné kombinace složek prvního a druhého vektoru. Výsledkem je matice Z obsahující v prvku zij návratovou hodnotu funkce aplikované na prvky xi a yj. Význam tohoto operátoru jsme si vysvětlili na příkladu, ve kterém se vytvořila a následně vypsala část tabulky malé násobilky (pozor – následující úryvek kódu je zapsaný v syntaxi odpovídající programovacímu jazyku APL, nikoli J):
1 2 3 4 5 ◦.× 1 2 3 4 5 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25
Programovací jazyk J sice neobsahuje specializovaný operátor typu ◦., ale ani to vlastně není zapotřebí, protože rozšiřuje možnosti operátoru / popsaného v první a druhé kapitole. Zatímco v APL byl operátor / (reduce) pouze monadický (bylo ho možné použít s parametrem zapisovaným napravo od identifikátoru funkce), je možné v programovacím jazyce J využít i jeho dyadickou formu, při níž se první parametr (vektor) zapisuje nalevo od operátoru+funkce a druhý parametr (většinou taktéž vektor) napravo. Výsledek aplikace „dyadického“ operátoru / (nazývaného poněkud neobvykle table) je v tomto případě stejný, jako při použití operátoru ◦. v programovacím jazyce APL (u některých funkcí použitých spolu s tímto operátorem dochází k několika malým změnám chování, které však nejsou v naprosté většině případů podstatné).
Výše uvedený příklad by se tedy dal přepsat do programovacího jazyka J dvěma způsoby: přímým zápisem dvojic vektorů, na něž by se aplikoval operátor „/“ v kombinaci s funkcí násobení, nebo využitím generátoru indexů pro zkonstruování obou vektorů. Ve druhém případě opět nesmíme zapomenout na to, že se indexy generují od nuly a nikoli od jedničky:
NB. Tabulka malé násobilky vzniklá NB. aplikací operátoru "outer product" NB. na dvojici explicitně zapsaných vektorů 1 2 3 4 5 */ 1 2 3 4 5 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25 NB. Použití generátoru indexů pro výpočet NB. tabulky malé násobilky. (1+i.5) */ (1+i.5) 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25
S využitím operátoru outer product je možné zkonstruovat velké množství matic se speciálními vlastnostmi; tyto matice mohou mít samozřejmě téměř libovolnou velikost. Jedná se například o jednotkové matice (obsahují jedničky v diagonále, ostatní prvky jsou nulové), trojúhelníkové matice různého typu (jedničky se nachází pod či nad diagonálou, ostatní prvky jsou nulové) atd. Tvorba těchto matic je ilustrována na následujících příkladech, ve kterých se často používají porovnávací (relační) funkce:
NB. Pomocný vektor obsahující číselnou NB. řadu 0 1 2 3 4 5 vect =. i. 5 NB. Matice obsahující prvky se shodnými NB. hodnotami na vedlejších diagonálách. vect +/ vect 0 1 2 3 4 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 NB. Jednotková matice. vect =/ vect 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 NB. Inverze všech prvků jednotkové NB. matice. vect ~:/ vect 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 NB. Rotace jednotkové matice |. vect =/ vect 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 NB. Matice obsahující NAD hlavní NB. diagonálou jednotkové prvky. vect </ vect 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 NB. Matice obsahující NAD hlavní NB. diagonálou (včetně diagonály) NB. jednotkové prvky. vect </ vect 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 NB. Matice obsahující POD hlavní NB. diagonálou (včetně diagonály) NB. jednotkové prvky. vect >:/ vect 1 0 0 0 0 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 NB. Na hlavní diagonále je NB. číselná posloupnost začínající NB. nulou, ostatní prvky jsou nulové vect * vect =/ vect 0 0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 0 4 NB. Na hlavní diagonále je NB. číselná posloupnost začínající NB. jedničkou, ostatní prvky jsou nulové (vect+1) * vect =/ vect 1 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 5 NB. Rotace předchozí matice |. (vect+1) * vect =/ vect 0 0 0 0 5 0 0 0 4 0 0 0 3 0 0 0 2 0 0 0 1 0 0 0 0
Příklad použití operátoru / s nekomutativní funkcí:
(i.5) ^/ (i.5) 1 0 0 0 0 1 1 1 1 1 1 2 4 8 16 1 3 9 27 81 1 4 16 64 256
Kdo dává přednost transponované tabulce (mocniny rostou po jednotlivých řádcích, základ po sloupcích), může použít funkci |: aplikovanou na vypočtenou matici. I v tomto případě totiž platí, že jsou funkce vyčíslovány zprava doleva, nejdříve je tedy vypočtena matice 5×5 hodnot, která je až následně transponována:
|: (i.5) ^/ (i.5) 1 1 1 1 1 0 1 2 3 4 0 1 4 9 16 0 1 8 27 64 0 1 16 81 256 NB. Kratší zápis pro ty, co šetří NB. každý stisk klávesy :-) |:(i.5)^/i.5 1 1 1 1 1 0 1 2 3 4 0 1 4 9 16 0 1 8 27 64 0 1 16 81 256
4. Operátor \
Druhým operátorem, který si v dnešním článku popíšeme, je operátor \. Tento operátor zpracovává data podobným způsobem, jako výše popsaný operátor /, ovšem s tím rozdílem, že vrací posloupnost obsahující všechny mezivýsledky postupné aplikace dané funkce na vstupní parametr, například vektor (chování tohoto operátoru je tedy odlišné od stejně označeného operátoru známého z programovacího jazyka APL). Na následujícím příkladu si povšimněte, že interpret programovacího jazyka J automaticky zarovnal všechny výsledky tak, aby vytvořily pravidelnou matici. V tomto příkladu je funkce + použita jako identita, která vrací přímo svůj (jediný) argument – jedná se tedy o monadickou podobu této funkce, nikoli o (už ze své podstaty dyadický) součet:
NB. Základní použití operátoru \. +\ 1 2 3 4 1 0 0 0 1 2 0 0 1 2 3 0 1 2 3 4
V předchozí kapitole jsme si ukázali, jakým způsobem lze vytvořit trojúhelníkové matice. Ty je však možné zkonstruovat i alternativním postupem demonstrovaným na následující dvojici příkladů:
NB. Jeden ze způsobů konstrukce trojúhelníkové matice. *\ 1 2 3 4 1 0 0 0 1 1 0 0 1 1 1 0 1 1 1 1 NB. Využití funkce |: provádějící transpozici matice. NB. (pozor - funkce |: je odlišná od funkce |.) |: *\ 1 2 3 4 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1
Předchozí příklady využívající operátor \ byly poněkud netypické. Mnohem častěji se tento operátor využívá spolu s výše popsaným operátorem / pro vytvoření vektoru obsahujícího postupnou aplikaci nějaké dyadické funkce na předaný parametr, kterým je většinou vektor nebo matice (zde se již přibližujeme původnímu operátoru \ z jazyka APL, v jazyku J je zvoleno obecnější a tím pádem i universálnější řešení). Pokud je například zavolán příkaz:
+/\ 1 2 3 4
Vygeneruje se vektor obsahující tyto hodnoty:
1 3 6 10
které vznikly následující sekvencí výpočtů:
1 1+2 1+2+3 1+2+3+4
Tento způsob použití operátoru \ je v aplikacích psaných v programovacím jazyku J poměrně často použitý, protože se s ním dají i bez použití programových smyček generovat například některé důležité číselné řady:
NB. Prvních deset prvků posloupnosti řady faktoriálů. */\ 1 2 3 4 5 6 7 8 9 10 1 2 6 24 120 720 5040 40320 362880 3628800 NB. Při náhradě vektoru (1 2 3 4 5 6 7 8 9 10) sekvencí NB. indexů musíme dát pozor na to, že se indexuje od 0, NB. tj. všechny součiny i jejich postupné součty budou NB. nulové. */\ i. 10 0 0 0 0 0 0 0 0 0 0 NB. Korektní zápis výpočtu prvních deseti prvků NB. posloupnosti řady faktoriálů. */\ 1 + i. 10 1 2 6 24 120 720 5040 40320 362880 3628800
5. Tvorba uživatelských funkcí
V předchozích kapitolách jsme si ukázali, jakým způsobem je možné v interaktivním režimu interpretru programovacího jazyka J volat jednotlivé základní (primitivní) funkce, popř. funkce zkombinované s některým operátorem. Ovšem při tvorbě větších aplikací se nevyhneme nutnosti vytváření uživatelských funkcí, v nichž je možné definovat lokální i globální proměnné, používat řídicí struktury (podmíněné příkazy a programové smyčky) atd. Uživatelsky definované funkce mohou být monadické (s jedním parametrem), dyadické (s dvojicí parametrů) nebo lze jednomu identifikátoru (jménu) přiřadit jak monadickou, tak i dyadickou funkci. Speciálním případem funkcí jsou funkce, v nichž se na předané parametry pouze volají další uživatelské i primitivní funkce, popř. operátory, bez vytváření pomocných proměnných. Tyto speciální funkce, které jsou v mnoha ohledech velmi užitečné, si popíšeme v osmé kapitole. Nyní se ovšem budeme zabývat běžnými uživatelskými funkcemi s parametry (jedním či dvěma) a návratovou hodnotou. Obecný formát zápisu nové funkce jak v monadické, tak i dyadické formě, má tvar:
jméno_funkce =: verb define tělo_monadické_funkce : tělo_dyadické_funkce )
V tuto chvíli můžeme pro jednoduchost považovat identifikátory verb a define za klíčová slova, i když se ve skutečnosti jedná o náhradu numerických konstant s pevným významem (například konstanta 3 říká interpretru, že má vytvořit funkci, konstanta 0, že se jedná o funkci, jejíž tělo se nachází na dalších programových řádcích atd.). Mezi tělem monadické a dyadické funkce se nachází znak dvojtečky, celá funkce (resp. definice těl obou funkcí) je ukončena znakem pravé kulaté závorky (závorky tedy nejsou vyvážené, na rozdíl od použití závorek v aritmetických a logických výrazech). V případě, že uživatel potřebuje vytvořit pouze monadickou nebo jen dyadickou funkci, jejíž tělo je možné zapsat na jeden řádek, může použít zkrácenou formu zápisu funkce ukázanou pod tímto odstavcem. Povšimněte si, že tělo funkce (seznam příkazů) je při použití tohoto způsobu zápisu umístěno v apostrofech:
name =: monad : 'text of verb' name =: dyad : 'text of verb'
6. Monadické uživatelské funkce
Monadické (jednoparametrické) funkce mohou ve svém těle přistupovat ke svému jedinému parametru, který má v tomto případě jméno y. Dyadické (dvouparametrické) funkce mají dvojici parametrů: levý je pojmenovaný x, pravý y (jedná se o stejné pojmenování, jako u monadických funkcí, což dává smysl, protože i u těchto funkcí jde o parametr, který se nachází napravo od jména funkce). Nyní si ukažme, jakým způsobem je možné vytvořit jednoduchou monadickou funkci nazvanou minus, která vrátí hodnotu svého jediného parametru, ale s opačným znaménkem (návratovou hodnotou funkce je výsledek posledního výrazu ve funkci, podobně jako například v LISPu). Jako parametr je možné předat skalární hodnotu, vektor, matici či pole o libovolné dimenzi. Tuto funkci lze vytvořit jedním ze tří způsobů:
NB. První ze způsobů definice funkce NB. "minus". V tomto případě se jakoby NB. současně vytváří monadická i dyadická NB. funkce, ovšem uvede se pouze tělo NB. monadické funkce. minus =: verb define -y ) NB. Druhý ze způsobů definice funkce NB. "minus". Zde se již explicitně uvádí, NB. že se jedná o funkci monadickou. minus =: monad define -y ) NB. Třetí způsob definice funkce "minus", NB. při němž je tělo funkce napsáno na NB. jednom řádku (v apostrofech). minus =: monad : '-y'
Vytvořenou funkci minus si můžeme ihned otestovat, a to jak na parametrech typu skalár, tak i na vektorech a maticích:
NB. Použití skalární hodnoty NB. jako parametru monadické NB. funkce "minus". minus 10 _10 minus 42 _42 minus _42 42 NB. Funkce se v programovacím jazyku NB. "J" vyhodnocují vždy zprava doleva. minus 1 + 2 + 3 _6 1 + minus 2 _1 NB. Použití vektoru NB. jako parametru monadické NB. funkce "minus". minus 1 2 3 4 5 _1 _2 _3 _4 _5 minus 1+i.5 _1 _2 _3 _4 _5 NB. Použití matice NB. jako parametru monadické NB. funkce "minus". matice =: 3 3 $ i.9 matice 0 1 2 3 4 5 6 7 8 minus matice 0 _1 _2 _3 _4 _5 _6 _7 _8
Snadno se taktéž můžeme přesvědčit, že interpret programovacího jazyka J hlídá, zda je uživatelská funkce minus zavolána s korektním počtem parametrů:
NB. Pokus o zavolání dyadické funkce "minus" 1 minus 2 |domain error: minus | 1 minus 2
7. Dyadické uživatelské funkce
Dyadické funkce se vytváří prakticky stejným způsobem jako funkce monadické, ovšem s použitím slova dyad namísto monad. Jak již víme z předchozího textu, jsou parametry uživatelských dyadických funkcí pojmenovány x (levý) a y (pravý). Uživatelskou funkci součtu dvou hodnot (skalárů, vektorů či matic) lze tedy zapsat velmi snadno, například s použitím „jednořádkové“ formy:
NB. Jednořádková uživatelská funkce NB. "soucet" zapsaná na jednom radku soucet =: dyad : 'x + y' NB. Test, zda funkce pracuje korektne 10 soucet 20 30 1 2 3 soucet 4 5 6 5 7 9
Při definici monadické i dyadické funkce se stejným jménem je zapotřebí použít formu definice začínající slovy verb define. Důvod je prostý – pokud by se nejdříve definovala například monadická funkce a poté (samostatným příkazem) funkce dyadická, došlo by k přepisu definice funkce přiřazené ke zvolenému identifikátoru, stejně jako dojde při přiřazení hodnoty do proměnné k přepisu hodnoty předchozí (i =: 1, i =: 2). Monadickou i dyadickou funkci minus je tedy možné vytvořit následovně:
NB. Definice monadické i dyadické NB. funkce "minus". minus =: verb define - y : x - y ) NB. Test funkčnosti obou variant NB. funkce "minus". minus 10 _10 10 minus 20 _10 100 minus 10 90 minus 1 2 3 4 5 _1 _2 _3 _4 _5 minus 1+i.5 _1 _2 _3 _4 _5 1 2 3 minus 4 5 6 _3 _3 _3
8. Tacit programming
Poslední zajímavou vlastností programovacího jazyka J, se kterou se v tomto seriálu seznámíme, je takzvaný tacit programming (přesný český ekvivalent tohoto označení mě nenapadá, proto raději zůstanu u termínu anglického, který se ostatně snadněji vyhledává). Jedná se o styl zápisu bloků programů (typicky uživatelských funkcí nebo výrazů), ve kterých se nachází volání jiných funkcí, ovšem bez explicitního udání jmen jejich argumentů (parametrů). S tímto stylem programování jsme se již mohli seznámit v seriálech o programovacím jazyku Forth a Joy, v nichž se využívalo toho, že všechny argumenty funkcí (operátorů) se nacházely na nejvyšších místech zásobníku operandů. Ve Forthu tedy bylo možné napsat například následující funkci:
:foo + * ;
která na zásobníku očekávala alespoň tři číselné hodnoty, které ovšem uvnitř funkce nebyly nikde explicitně pojmenovány ani použity. Použití této funkce bylo stejně snadné jako její zápis:
3 2 1 foo . 9
Podobným způsobem je možné vytvářet funkce i v programovacím jazyku J. Typickým příkladem je funkce pro výpočet průměru číselných hodnot uložených v nějakém vektoru. Průměr se vypočítá snadno: nejprve zjistíme součet (sumu) všech prvků (funkce + zkombinovaná s operátorem /) a následně tento součet vydělíme jejich počtem (funkce # zjistí délku vektoru). Při těchto výpočtech není nutné nikde explicitně pojmenovávat parametry – ty se použijí až při aplikaci (použití) vytvořené kombinace funkcí v další části programu:
NB. mean=suma(a1..an)/n mean =: +/ % #
9. Literatura
- Linda Alvord and Norman Thomson, „Easy-J: An Introduction to the World's most Remarkable Programming Language“
October 2002 - Ulf Grenander, „Mathematical Experiments on the Computer,“
Academic Press, 1982, ISBN 0–12–301750–5. - K. E. Iverson, „A Programming Language“,
Wiley, 1962. - K. E. Iverson, „Algebra : an algorithmic treatment“,
APL Press 1977, Copyright 1972 by Addison Wesley,
Preliminary Edition entitled „Elementary Algebra“
Copyright 1971 by IBM Corporation.
- K. E. Iverson, „Elementary analysis“,
APL press 1976, Preliminary Edition „Elementary Functions“
Copyright 1974 by IBM Corporation ISBN 0–917326–01–6
- K. E. Iverson, „A personal view of APL,“
IBM Systems Journal, - C. Reiter, „Fractuals Visualization and J“,
Iverson Software, Inc, 1995 ISBN 1–895721–11–3. - „J Phrases,“
Iverson Software, 1996, ISBN 1–895721–12–1 - „Exploring Math“, Iverson Software, 1996, ISBN 1–895721–13-X
- „J Primer,“
Iverson Software, 1996, ISBN 1–895721–14–8
10. Odkazy na Internetu
- Tacit programming
http://en.wikipedia.org/wiki/Tacit_programming - Pure functions in APL and J
http://portal.acm.org/citation.cfm?id=114065&dl=GUIDE&coll=GUIDE - Learning J (Roger Stokes)
http://www.jsoftware.com/help/learning/contents.htm - J: a modern, high-level, general-purpose, high-performance programming language
http://www.jsoftware.com/ - K, Kdb: an APL derivative for Solaris, Linux, Windows
http://www.kx.com - Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
http://www.vector.org.uk/ - APL – A Glimpse of Heaven
http://www.vector.org.uk/archive/v231/legrand.htm - APL Interpreters
http://www.vector.org.uk/?area=interpreters - APL_(programming_language
http://en.wikipedia.org/wiki/APL_(programming_language - APL FAQ
http://www.faqs.org/faqs/apl-faq/ - APL FAQ (nejnovější verze)
http://home.earthlink.net/~swsirlin/apl.faq.html - A+
http://www.aplusdev.org/ - Rosetta Code
http://rosettacode.org/wiki/Main_Page