Wolfram Language
Author
Albert FloresWolfram Language či jen Wolfram (dále jen WL; dříve též Mathematica, pro podrobnosti viz oddíl #Pojmenování|"Pojmenování") je univerzální vyšší programovací jazyk vyvíjený společností Wolfram Research. Ústředním konceptem jazyka jsou výrazy - výrazem jsou reprezentovány i takové části jazyka jako podmíněný příkaz či cykly, jež jsou obvykle v jiných jazycích jako C či Python vyjadřovány pomocí příkazů. Kód tak má přirozenou stromovou strukturu složenou z vnořených výrazů, jež lze přitom upravovat podobně jako data. Dalším ústředním konceptem jazyka jsou vzory (angl. patterns), které umožňují pružné vyhledávání a nahrazování částí kódu či dat pomocí nahrazovacích pravidel. WL je interpretovaný deklarativní jazyk, jenž umožňuje symbolické, funkcionální i procedurální programování s velkou mírou abstrakce.
WL obsahuje množství funkcí z různých oblastí matematiky, statistiky, zpracování dat či strojového učení. Jazyk umožňuje tvorbu 2D i 3D grafiky, manipulaci se zvukem či videem, tvorbu interaktivních uživatelských rozhraní, tvorbu webových rozhraní apod. +more Integrální součástí jazyka jsou funkce pro přímý přístup k datům různého druhu uloženým na vzdálených serverech. Podporovány jsou symbolické i numerické výpočty, paralelní výpočty i napojení na jiné jazyky jako Java, Python či Julia. Kód ve WL lze pro zvýšení efektivity zkompilovat do jazyka C či do nízkoúrovňové reprezentace LLVM.
V současnosti jedinou plnohodnotnou implementací jazyka WL je systém Mathematica. WL samotný je vyvíjený v jazycích C a Java jako multiplatformní jazyk běžící na systémech Windows, macOS a Linux. +more Rozšíření jazyka WL mezi uživateli je spíše omezené. Podle žebříčku TIOBE se jazyk WL nedostává do první stovky nejpoužívanějších jazyků. Žebříček IEEE Spectrum k roku 2022 vypisuje 57 nejoblíbenějších jazyků, přičemž WL mezi nimi nefiguruje. Podobně není WL v seznamu nejoblíbenějších jazyků na projektu RedMonk a v žebříčku PYPL index není WL ani zahrnut do seznamu sledovaných jazyků.
Pojmenování
Firma Wolfram Research od roku 1988 vyvíjí program Mathematica, který zpočátku uživateli umožňoval provádět různé matematické operace v závislosti na zadaných příkazech. Samotné jméno "Mathematica" bylo navrženo Stevem Jobsem a tento produkt byl inzerován sloganem "A System for Doing Mathematics by Computer", to jest "systém pro dělání matematiky počítačem". +more S postupem času se sada příkazů rozšiřovala, čímž vzniknul programovací jazyk s funkčností přesahující rámec matematiky, přičemž se pro tento jazyk též ustálilo pojmenování "Mathematica". Tento název tak označoval jak konkrétní softwarový produkt, tak programovací jazyk, který tento produkt implementuje.
S verzí 10. +more0 došlo k oddělení těchto dvou konceptů spolu s přejmenováním některých produktů společnosti a změnou jejich inzerování. Jméno "Mathematica" tak označuje vývojové prostředí určené pro tvorbu kódu v jazyce, jež nese jméno "Wolfram language", to jest "jazyk Wolfram". Zavedené změny nicméně nejsou zcela dobře vymezeny, což vedlo k rozporuplnému přijetí mezi stávajícími uživateli a zmatení v užívaném názvosloví. Na oficiálních stránkách je rozdíl mezi Wolfram language a Mathematicou popsán slovy: "V prvním přiblížení, Wolfram Language = Mathematica + Wolfram|Alpha + Cloud + víc. Je kompatibilní s Mathematicou, ale je jejím podstatným rozvinutím, včetně znalostí, použití a mnoha nových myšlenek," kde Wolfram|Alpha je služba poskytovaná firmou Wolfram Research založená zčásti na zpracování přirozeného jazyka a slovem Cloud jsou myšleny cloudové služby a s tím související funkce nabízené téže firmou.
Design
WL je symbolický jazyk, kde je s kódem nakládáno stejným způsobem jako s daty - přístup známý jako homoikonicita, který se uplatňuje i v jiných jazycích jako třeba Lisp. Kniha "Mathematica programming - an advanced introduction" uvádí tři základní principy, na nichž je WL vybudován. +more Prvním z nich jsou symbolické výrazy jako stavební blok jazyka. Druhým jsou vzory a jejich použití pro úpravu výrazů s pomocí nahrazovacích pravidel. Třetím principem je pak způsob, jakým jsou výrazy a jejich úpravy vyhodnocovány. Každý princip je podrobněji představen v samostatné podsekci níže. WL je interpretovaný jazyk využívající JIT kompilace. Ze symbolického charakteru jazyka plyne jeho dynamické typování a funkcionální přístup k úpravě kódu. Ačkoli objektově orientované programování není ve WL přímo podporováno, existují různé způsoby jak ho emulovat.
Výpočetní systém, na kterém běží WL, se skládá ze dvou hlavních částí - výpočetního jádra (angl. kernel) a front endu (angl. +more front end). Výpočetní jádro se stará o samotné výpočty, zatímco front end slouží k interakci s uživatelem. Vkládání vstupů uživatelem a jejich formátování stejně jako pokročilé funkce vykreslování výstupů včetně matematické sazby, grafiky či přehrávání zvuku má na starosti front end. S tím je svázán i fakt, že mnoho funkcí WL bez front endu nefunguje. Jádro komunikuje s front endem pomocí protokolu WSTP (Wolfram Symbolic Transfer Protocol, dříve známý pod jménem MathLink). Tento protokol lze použít i pro komunikaci mezi jádrem a externí aplikací vyvinutou v jiném jazyce, přičemž oficiálně jsou takto podporována mimo jiné propojení s jazyky Java (knihovna J/Link), R (knihovna RLink) či s . NET frameworkem (knihovna . NET/Link).
Při vývoji WL se klade důraz na jeho zpětnou kompatibilitu. V minulosti byly hlavní verze WL vydávány zhruba jednou za tři roky, viz přehled vpravo.
Vše je výraz
[[Soubor:Mathematica Treeform example. svg|vlevo|náhled|Výše je vyobrazena hierarchická struktura výrazu a + Sin[b*c] ve formě syntaktického stromu. +more Tuto reprezentaci výrazu lze získat funkcí TreeForm. ]].
Každý objekt ve WL, to jest kód, data, obrázky, dokumenty, rozhraní, programy atd. , je představován symbolickým výrazem (angl. +more expression). Výrazy mohou být dvojího druhu, a to buď atomární anebo normální. Atomárních výrazů je omezené množství, jedná se (především) o čísla, řetězce a symboly. Všechno ostatní jsou normální výrazy, které mají obecnou strukturu následujícího tvaru:.
hlava[arg1, arg2, ...]
kde hlava je hlavička výrazu, jež samotná je buď symbol anebo normální výraz, a kde dále objekty arg1, arg2, atd. tvoří tělo výrazu a samy mohou být buď atomárními či normálními výrazy. +more Tímto přirozeně vzniká stromová struktura výrazů a následně i celého kódu, viz obrázek vlevo. S touto strukturou lze nakládat jako s daty - lze například přistupovat k jejím částem pomocí indexů, podobně jako lze přistupovat k prvkům vícerozměrného pole. Příkladem normálního výrazu je i samotné volání funkce. Například Sin[x] je nejen volání funkce sinus na proměnnou x, ale současně i výraz s hlavičkou Sin a tělem obsahujícím argument x. Každý konstrukt má ve WL reprezentaci výše uvedeného tvaru, která se nazývá FullForm, takže například součet dvou čísel 1 + 2 je interně reprezentován jako Plus[1,2], to jest výraz s hlavičkou Plus. Výrazy jsou ve WL imutabilní struktury, kde jen vyhrazené funkce mohou výraz měnit "in place".
Vzory a nahrazovací pravidla
Vzory (angl. patterns) jsou svým způsobem šablony, kterým může vyhovovat současně vícero různých výrazů. +more Tyto šablony lze použít pro vyhledání nějaké části výrazu, či pro zkontrolování, zda je daný výraz správného tvaru. Tak například výraz Sin[x] je sice odlišný od výrazu Sin[y], oba bychom ale mohli popsat slovy "funkce sinus volaná na nějakou proměnnou". Takovýto krátký popis lze formalizovat pomocí vzoru ve tvaru Sin[_], kde podtržítko _ je znak představující "cokoliv". Tyto a podobné vzory lze uplatnit při definicích funkcí. Konstantní funkci konst, která na jakýkoliv vstup vrátí číslo 42, lze definovat způsobem: konst[_] = 42. Pokud je nutno se na vstup odkazovat jako na proměnnou, lze mu dát jméno. Například x_ označuje "cokoliv, čemuž jsme dali jméno x". Funkci, jež má pro jakoukoliv vstupní hodnotu vrátit její druhou mocninu, tak lze definovat následovně:.
f[x_] := x^2
Ve výše uvedeném vzoru přitom není vůbec řečeno, že vstupní hodnotou musí být číslo - lze použít skutečně cokoliv:
{f[2], f["retez"], f[Sin]} (* vrátí: {4, "retez"^2, Sin^2} *)
Ačkoliv to třeba nemusí dávat smysl, funkce f aplikovala druhou mocninu i na řetězec "retez" a identifikátor funkce Sin. Tímto způsobem WL implementuje polymorfizmus.
Vzory mohou mít velmi složitou strukturu. Způsob, jakým WL určí, zda daný výraz vyhovuje zadanému vzoru, se v angličtině nazývá pattern matching. +more Úpravy výrazů pak probíhají pomocí nahrazovacích pravidel (angl. (transformation) rules) tvaru vzor->vyraz, které danou část výrazu vyhovující vzoru vzor nahradí novým (pod)výrazem tvaru vyraz. Výše uvedenou funkci f lze vyjádřit jako nahrazovací pravidlo x_ -> x^2. Aplikace pravidla se zapisuje jako /. a tak výše uvedený kód lze přepsat do tvaru:.
{2 /. x_ -> x^2, "retez" /. x_ -> x^2, Sin /. x_ -> x^2} (* vrátí: {4, "retez"^2, Sin^2} *)
Ve skutečnosti je jakákoliv funkce vyjádřena interně jako sada odpovídajících nahrazovacích pravidel.
Vyhodnocování
Výpočetní jádro WL si udržuje interní databázi globálních nahrazovacích pravidel, v nichž jsou obsaženy jak definice vestavěných i uživatelem definovaných funkcí, tak přiřazení do proměnných. Jakmile je výraz ve WL odeslán do výpočetního jádra, prochází jádro tuto databázi a zjišťuje, zda levé strany některých pravidel vyhovují zadanému výrazu či některé jeho části. +more Je-li takové pravidlo nalezeno, je na výraz aplikováno, čímž dojde k jeho změně. Tato změna odstartuje další prohledávání téže databáze, kde jsou nyní hledána pravidla vyhovující novému tvaru výrazu. Tento proces probíhá tak dlouho, dokud už nelze výraz žádným z existujících pravidel upravit. Tento výsledný výraz je následně vrácen uživateli.
Pořadí, ve kterém jsou výrazy takto vyhodnocovány, lze nicméně upravovat, a to buď pomocí funkcí Evaluate, Unevaluated, Hold apod. , anebo pomocí atributů funkcí HoldAll, HoldFirst, atd. +more Máme-li například funkci, jež má vrátit hlavičku výrazu, na který je volána, můžeme obdržet neočekávané výsledky:.
f[h_[x_]] := h; (* definice *) f[hlava[telo]] (* vrátí: hlava *) f[Sin[x]] (* vrátí: Sin *) f[Sin[Pi/2]] (* vrátí: f[1] *)
Ačkoli bychom chtěli, aby i v posledním řádku vrátila funkce symbol Sin, obdržíme výsledek f[1]. Důvod je ten, že se nejprve vyhodnotil výraz Sin[Pi/2] na hodnotu 1 a teprve tato hodnota byla vložena do funkce f. +more Protože funkce f ale nemá přiřazenu definici pro případ argumentů, které nemají tvar normálního výrazu, zůstává funkce nevyhodnocena, čímž obdržíme f[1]. Toto chování lze napravit tak, že argument zabalíme do výrazu Unevaluated, který zabrání tomu, aby se daný výraz vyhodnotil:.
f[Unevaluated[Sin[Pi/2]]] (* vrátí: Sin *)
Téhož chování lze dosáhnout i tak, že funkci f nastavíme atribut HoldAll, který zamezí tomu, aby k vyhodnocování argumentů docházelo obecně a Unevaluated tak není potřeba:
SetAttributes[f, HoldAll] f[Sin[Pi/2]] (* vrátí: Sin *)
Přehled jazyka
Níže je podán krátký výběr nejzákladnějších prvků jazyka WL. Důraz je ve WL obecně kladen na funkcionální přístup, kdy například místo for cyklů pro úpravu polí prvek po prvku lze použít funkci Map, která má jako první parametr funkci, jež se má na prvky uplatnit, a jejímž druhým parametrem je upravované pole. +more Dalším specifikem je používání vzorů, což jsou obdoby regulárních výrazů, které lze použít například pro vyhledávání prvků v poli se zadanými vlastnostmi či v definicích funkcí.
Syntaxe se v mnohém podobá známým jazykům jako je jazyk C. Až na speciální znaky a znaky, jež mají ve WL předdefinovanou funkci, lze pro identifikátory použít ve WL celou sadu Unicode včetně písmen české abecedy, přičemž identifikátory nemohou začínat číslicí. +more V praxi se přesto většinou používají jen písmena anglické abecedy. Některé předdefinované interní konstanty a proměnné navíc začínají znakem dolaru $. Na rozdíl od mnoha jiných jazyků nelze však v identifikátoru použít podtržítko, které v WL hraje funkci zástupného symbolu ve vzorech. WL je case sensitive.
V sekci #Ukázky|"Ukázky" níže je vypsána řada příkladů ilustrující různou funkcionalitu jazyka WL. V článku "Syntaxe a sémantika programovacího jazyka Wolfram Language" lze pak nalézt další podrobnosti.
Základy
Nápověda se programově vyvolá zapsáním otazníku na začátek řádky, po němž následuje dotazovaný symbol, např. . +moreSin. Komentáře jsou vloženy mezi závorky s hvězdičkami způsobem (* toto je komentář *). Znak procenta % je používán pro vyvolání posledního výsledku:.
a = 1; (* do proměnné a ulož hodnotu 1 *) b = a + 2; (* proměnná b obsahuje hodnotu 3 *) % (* vrátí: 3 *)
Čísla mohou být jednoho z následujících typů: Integer (celá čísla, nekonečná přesnost), Rational (racionální čísla, nekonečná přesnost), Real (reálná čísla s plovoucí řádovou čárkou, libovolně zvolitelná přesnost), Complex (komplexní čísla, jejichž reálná a imaginární část může být celá, racionální či reálná). Navíc je podporována řada konstant jako číslo pí Pi či Eulerovo číslo E. +more S čísly lze provádět obvyklé aritmetické operace:.
3 + 4 (* sčítání; vrátí: 7 *) 3 - 4 (* odčítání; vrátí: -1 *) 3 * 4 (* násobení; vrátí: 12 *) 3 / 4 (* podíl dvou celých čísel; vrátí: 3/4 *) 3. 0 / 4. +more0 (* podíl dvou reálných čísel; vrátí: 0. 75 *) Quotient[3, 4] (* celočíselné dělení; vrátí: 0 *) Mod[3, 4] (* modulo operace; vrátí: 3 *) 3^4 (* mocnina; vrátí: 81 *) 2. 3 + 4 I (* komplexní číslo; I označuje imaginární jednotku *).
Řetězce se zapisují pomocí dvojitých uvozovek a speciální znaky lze escapovat lomítkem. Dva a více řetězců lze spojit operátorem :
"toto je řetězec" "řekla: \"tak či onak\" \\ následuje\nnový řádek a\ttabulátor" (* vypíše: řekla: "tak či onak" \ následuje nový řádek a tabulátor *) "první"" a ""druhý" (* vrátí: "první a druhý" *)
Proměnné, konstanty či pojmenované funkce jsou reprezentovány symboly. Obecně jsou konstrukty ve WL reprezentovány jako výrazy (angl. +more expressions), které mají hlavičku, za níž v hranatých závorkách následuje tělo výrazu. Například volání funkce sinus Sin[0. 2] lze chápat jako výraz s hlavičkou Sin, v jehož těle je reálné číslo 0,2. Podobně například komplexní číslo 1 + 2 i lze reprezentovat jako výraz Complex[1,2], jehož hlavičkou je Complex a tělo tvoří dvě čísla 1 a 2.
Operátory
Ve WL existují dva základní druhy přiřazení: přímé = a odložené :=. Odložené přiřazení vyhodnocuje pravou stranu až ve chvíli, kdy je symbol na levé straně volán. +more Rozdíl mezi oběma přiřazeními lze nejsnáze nahlédnout, je-li na pravé straně generováno náhodné číslo. Zatímco do proměnné a níže je uloženo jedno dané číslo, které je při volání této proměnné vráceno, v případě proměnné b je funkce RandomReal vždy znova zavolána při každém volání této proměnné:.
a = RandomReal[]; (* přímé přiřazení *) b := RandomReal[]; (* odložené přiřazení *) {a,b} (* vrátí: {0.86258,0.480284} *) {a,b} (* vrátí: {0.86258,0.705826} *)
Podporovány jsou standardní porovnávací operátory, přičemž nerovnost se zapisuje jako vykřičník následovaný rovnítkem !=:
1 = 2 (* neostrá nerovnost; vrátí: False *) 1 == 1. (* rovnost; vrátí: True *) 1 != 2 (* nerovnost; vrátí: True *)
Logické operátory implementují zkrácené vyhodnocení, a tak je-li např. v operátoru AND z prvního argumentu zřejmé, že je výsledek False, další argumenty se již nevyhodnocují. +more Negace se zapisuje vykřičníkem:.
10
Řídicí struktury
Podmíněný příkaz je představován funkcí If, jejímž prvním parametrem je podmínka, druhým parametrem je výraz, který se vyhodnotí, je-li podmínka pravdivá, a třetím parametrem je výraz vyhodnocený, je-li podmínka nepravdivá. Funkce If má ještě nepovinný čtvrtý parametr, který je vyhodnocen, nelze-li určit pravdivostní hodnotu podmínky:
If[1 Protože proměnné x a y nemají v kódu výše přiřazenu žádnou hodnotu, nelze vyhodnotit nerovnost a funkce If tak vrátí čtvrtý argument.
Ačkoli WL podporuje tradiční cykly jako for cyklus For, while cyklus While a repeat-until cyklus Until, není používání for cyklu kvůli jeho pomalé implementaci doporučeno. Místo toho se doporučuje používání funkcí jako Do pro opakované provádění kódu, Table pro tvorbu polí či Nest pro tvorbu vnořených struktur. +more Další alternativou je používání funkce Map, jež aplikuje danou funkci na každý prvek pole:.
pole = {0, 0, 0, 0, 0}; For[i = 1, i
Standardní vyhodnocování kódu lze programově přerušit funkcemi Throw či Confirm, jejichž volání musí být po řadě zachyceno funkcemi Catch či Enclose. Chybové hlášky a varování lze vypsat voláním funkce Message. +more Například:.
Catch[ a = 1; Throw[chyba]; a = 3; ] (* vrátí: chyba; proměnná a má hodnotu 1 *)
Datové struktury
Základními dvěma datovými strukturami ve WL jsou pole neboli seznamy (List) a asociativní pole (Association). Pole jsou imutabilní datové struktury, které lze indexovat a lze do nich ukládat jako prvky libovolné další výrazy, které nemusejí být stejného typu. +more Do jednoho pole tak lze uložit čísla, řetězce, obrázky, zvukové nahrávky apod. Indexování se provádí pomocí dvojitých hranatých závorek, přičemž počáteční index je roven jedné a pro indexování od konce lze použít záporných čísel. Pole jsou zapisována do složených závorek:.
pole = {5, -14, 42., "řetězec", Sin}; (* v poli lze ukládat i funkce *) pole2 (* vrátí: -14 *) pole-2 (* vrátí: "řetězec" *) pole3 = 1; (* do třetího prvku uloží číslo 1; výjimka z imutability *) pole (* vrátí: {5, -14, 1, "řetězec", Sin} *)
Asociativní pole se zapisují do speciálních závorek skládajících se ze svislic a úhlových závorek, kde je každý pár (klíč, hodnota) propojen pomocí šipky ->. Asociativní pole podporují jednak vyhledání hodnoty pomocí klíče, který se vkládá do jednoduchých hranatých závorek, jednak i indexování známé z normálních polí, a to pomocí dvojitých hranatých závorek. +more Klíčem může být libovolný výraz:.
asoc = 5, var -> -14, 345 -> 42., "klic" -> Sin|>; asoc["a"] (* vrátí: 5 *) asoc2 (* vrátí: -14 *) asoc3 = 1; (* do třetí hodnoty uloží číslo 1 *) asoc (* vrátí: 5, var -> -14, 345 -> 1, "klic" -> Sin|> *)
Funkce
Funkce lze definovat dvěma způsoby a to buď jako symboly, anebo jako anonymní funkce, které se ve WL označují jako ryzí funkce (angl. pure functions). +more První způsob přiřazuje k danému symbolu definici, jejíž standardní syntaxe zní následovně:.
umocni[x_] := x^2
kde umocni je identifikátor funkce, x_ je vzor odpovídající vstupnímu parametru a znak := vyjadřuje odložené vyhodnocení, na jehož pravé straně je tělo funkce. Volání takové funkce probíhá pomocí hranatých závorek:
umocni[3] (* vrátí: 9 *) umocni[y] (* vrátí: y^2 *)
Jak vidno, pracovat lze i se symboly, které nemají přiřazenu hodnotu, jako v případě symbolu y výše.
Tělo funkce může být značně složitější a vynucovat si tak lokální proměnné. V takovém případě lze použít například blokové struktury Block či Module:
složitějšíFunkce[x_, y_] := Module[{z = 0}, (* z je lokální proměnná *) If[x
Funkce jsou ve WL first-class objekty a tak lze s nimi manipulovat jako s běžnými proměnnými:
mojeFunkce = umocni; mojeFunkce[3] (* vrátí: 9 *)
Ryzí funkce lze zapisovat speciální syntaxí používající křížek # k označení nepojmenovaných vstupů, přičemž ke konci těla funkce se připojuje ampersand &. Výše definovanou funkci umocni tak lze přepsat jako ryzí funkci do tvaru:
umocni = (#^2) &; umocni[3] (* vrátí: 9 *)
Vzory a nahrazovací pravidla
Velkou kapitolu tvoří ve WL vzory (angl. patterns) a nahrazovací pravidla (angl. +more rules), jež umožňují flexibilní manipulaci s daty či kódem a poskytují tak jistou alternativu ke standardním funkcím. Máme-li například pole čísel, kde chceme každý výskyt čísla 3 nahradit řetězcem "tři", lze toto učinit následujícím zápisem:.
{1, 2, 3, 4, 3, 2, 1} /. 3->"tři" (* vrátí: {1, 2, "tři", 4, "tři", 2, 1} *)
Tento zápis se skládá z výrazu, v němž chceme provést substituci, v příkladu výše tedy číselné pole {1, 2, 3, 4, 3, 2, 1}, a zápisu /. 3->"tři", kde 3->"tři" je samotné nahrazovací pravidlo, jež udává, jaká substituce se má provést. +more Konečně znaky /. jsou syntaktický cukr pro funkci ReplaceAll, která provádí samotné nahrazení. Je-li nahrazovacích pravidel udáno více, je nutno je zabalit do složených závorek, v případě jediného pravidla toto nutné není:.
{1, 2, 3, 4, 3, 2, 1} /. {2->"dva", 3->"tři"} (* vrátí: {1, "dva", "tři", 4, "tři", "dva", 1} *)
Stejně tak lze upravovat další výrazy, například algebraické výrazy či části kódu:
x^3 + 3 x^2 + 5 x + 1 /. x->y (* vrátí: y^3 + 3 y^2 + 5 y + 1 *) x^2 /. x->2 (* vrátí: 4 *)
Podobně jako u přiřazení, i u nahrazovacích pravidel existuje odložená varianta, která se zapisuje symboly :>, kde se pravá strana pravidla vyhodnotí až ve chvíli volání. Chceme-li každý výskyt celého čísla v poli nahradit jeho druhou mocninou, lze toto provést následovně:
{2, 3, x, y} /. x_Integer:>x^2 (* vrátí: {4, 9, x, y} *)
Způsob, jakým jsou vzory používány pro nalezení odpovídající části kódu, se anglicky nazývá pattern matching, což lze přeložit jako porovnávání se vzorem.
Repozitáře a databáze
Součástí WL je kromě funkcí a interních proměnných i přístup k datům uchovávaným na serverech společnosti Wolfram Research. Tato firma označuje WL jako knowledge based, to jest založený na znalostech. +more Jedná se například o astronomická, klimatická či finanční data, jež lze získat funkcemi jako WeatherData, FinancialData atd. Alternativním přístupem je vyjádření znalostí pomocí ontologie, v níž je každý objekt představován výrazem Entity. Například počet obyvatel České republiky lze získat voláním.
Entity["Country", "CzechRepublic"]["Population"]
Obsah stránek na Wikipedii lze obdržet funkcí WikipediaData, položky z projektu Wikidata lze získat voláním funkce WikidataData. Podklady funkcí jako GeoGraphics, jež slouží pro práci s geografickými daty, jsou založeny na mapách tvořených v rámci projektu OpenStreetMap. +more Přímo z editoru WL lze vyvolat i funkcionalitu projektu Wolfram|Alpha a to buď funkcí WolframAlpha, anebo speciální syntaxí, kdy je kurzor přesunut na začátek prázdného řádku a poté je dvakrát zmáčknuta klávesa pro rovnítko. Vyvolá se tak speciální řádka, do níž lze vložit dotaz v přirozené angličtině, pod níž se vykreslí zpracovaný výstup.
Vývojář WL udržuje kromě toho několik online repozitářů poskytujících dodatečná data a funkce: * Wolfram Data Repository - Databáze textových a jiných zdrojů, přičemž lze každý zdroj vyvolat přímo z editoru WL výrazem s hlavičkou ResourceObject, jenž obsahuje název zdroje. * Wolfram Neural Net Repository - Databáze modelů neuronových sítí přístupných skrz funkci NetModel. +more * Wolfram Function Repository - Databáze funkcí, které nejsou předdefinované ve WL a které jsou buď nahrávány na server vývojáři WL či samotnými uživateli. Danou funkci lze vyvolat přímo z editoru WL funkcí ResourceFunction. * Paclet Repository - Databáze pacletů, přístupných skrz funkci PacletInstall. * Data Drop - Služba, jež umožňuje uživatelům zasílat na vzdálený server jimi získaná data. Například data z fyzikálních experimentů lze funkcí Databin zasílat kontinuálně na server a pak je kdykoliv ze serveru stáhnout a zpracovat.
Pro ilustraci používání výše uvedených zdrojů přímo z editoru WL uveďme použití funkcí z repozitáře Wolfram Function Repository. Řekněme například, že máme dvě křivky a chceme spočíst plochu sevřenou mezi těmito křivkami. +more Nevíme ale, jakou funkci k tomu použít, přičemž podobná funkce se v základní sadě funkcí WL nenachází. Můžeme proto zkusit vyhledat tuto funkci v online repozitáři na základě klíčových slov, která v aktuálním případě zvolíme jako "area" (to jest "plocha") a "curve" (to jest "křivka"). Pokud taková funkce existuje, můžeme jí poté rovnou použít:.
ResourceSearch["area curve"] (* vyhledej funkci v repozitáři na základě klíčových slov "area" a "curve" *) (* volání funkce ResourceSearch vrátí interaktivní databázi relevantních dostupných funkcí *) (* na základě popisků v databázi usoudíme, že námi hledaná funkce se jmenuje "AreaBetweenCurves" *) (* v databázi lze nalézt i odkaz na dokumentaci této funkce *)
ResourceFunction["AreaBetweenCurves"][{x, x^2}, {x, 0, 1}] (* voláme funkci ResourceFunction["AreaBetweenCurves"] *)
Výpočetní systém automaticky stáhne definici dané funkce z online repozitáře do lokálního výpočetního jádra a tuto funkci tak lze rovnou použít.
Notebook a buňky
Výchozím pracovním prostředím pro psaní kódu ve WL je tak zvaný notebook, kde je kód strukturován do hierarchie elementárních částí zvaných buňky (angl. cells). +more Příkazy jsou psány do vstupních buněk a po vyhodnocení vstupní buňky je výsledek výpočtu vrácen do výstupní buňky, která se automaticky pod tou vstupní vytvoří. Buňky lze dále seskupovat do větších celků a utvářet tak strukturu kódu podobnou kapitolám a podkapitolám známým z psaných knih. Buňky plní různé role, lze vkládat i čistě textové buňky či nadpisy. Tyto buňky nejsou při běhu kódu vyhodnoceny a mohou tak zastupovat funkci komentářů.
Každá vstupní buňka je uvedena řetězcem "In[n]:=", kde n je její pořadové číslo. Výstup kódu obsaženého v takové buňce je vypsán pod tuto buňku do nové výstupní buňky, jež je uvozena řetězcem "Out[n]=". +more Konkrétní kód v editoru, jakým je tradičně Mathematica, pak může vypadat následovně:.
In[1]:= 1 + 2*3 Out[1]= 7
Spočti obsah kruhu
In[2]:= polomer = 0.2; obsahKruhu = Pi*polomer^2;
In[3]:= obsahKruhu Out[3]= 0.125664
Druhá buňka byla nastavena jako textová buňka a tak není její obsah vyhodnocen. Ve třetí vstupní buňce je specifikováno více příkazů. +more Jejich výstup je středníky potlačen a výstup tak není vypsán.
Interně je každá buňka představována výrazem Cell[obsah, styl, volby], kde obsah může být buď čistý text, anebo strukturovanější data zabalená do výrazu s hlavičkou BoxData; styl označuje styl buňky, jako například vstupní ("Input"), výstupní ("Output"), textová ("Text"), titul ("Title") apod. ; a volby jsou dodatečná nastavení buňky, jakým může být například barva pozadí, čas poslední změny dané buňky či identifikační číslo buňky. +more Buňka tedy obsahuje více informací, než které jsou uživateli v editoru přímo přístupné a z tohoto pohledu nelze kód notebooku označit jako WYSIWYG.
Ukázky
Hello World
Vypiš text "Ahoj světe!":
Print["Ahoj světe!"];
Fibonacciho posloupnost
Definuj Fibonacciho posloupnost:
f[0] = 0; f[1] = 1; f[n_] := f[n - 1] + f[n - 2]
Tato implementace je neefektivní, protože při výpočtu daného prvku posloupnosti jsou rekurzivně počítány všechny prvky předchozí. Tomu lze předejít využitím memoizace, kde je každý prvek spočten jen jednou a poté držen v paměti:
f[0] = 0; f[1] = 1; f[n_] := f[n] = f[n - 1] + f[n - 2]
Faktoriál
Spočti faktoriál:
f[0] = 1; f[n_] := n f[n-1]
Podobně jako výše u Fibonacciho posloupnosti lze i zde využít memoizace.
Práce s poli
Provádět operace s poli lze několika způsoby, které si ilustrujeme na příkladu, kde je cílem spočíst druhou mocninu každého prvku zadaného jednorozměrného pole.
* Hrubá síla s použitím For cyklu:
pole = {1, 2, 3, 4}; For[i = 1, i
* Využití funkce Map:
#^2& /@ {1, 2, 3, 4} (* vrátí: {1, 4, 9, 16} *)
Zde je ryzí funkce #^2& aplikována na každý prvek pole zápisem /@, jenž odpovídá volání funkce Map.
* Využití atributu Listable:
{1, 2, 3, 4}^2 (* vrátí: {1, 4, 9, 16} *)
Funkce Power, kterou jsme vyvolali stříškou ^, má atribut Listable. Je-li funkce s tímto atributem zavolána na seznam, to jest výraz s hlavičkou List, je tato funkce automaticky aplikována na každý prvek seznamu. +more Tento atribut mají například i funkce Sin, Plus či Divide.
Použití syntaktického cukru
Ve WL má mnoho funkcí ekvivalentní zkrácený zápis poskytující syntaktický cukr pro kompaktnější vyjádření. Pro příklad uvažme pole a = {12, p, {b, c}, {}}, kde je naším cílem nahradit každý jeho prvek, jenž je sám seznamem o alespoň jednom prvku, jeho posledním prvkem. +more To lze provést následujícím kódem:.
anovy = {}; For[i = 1, i = 1, elem = ai, -1, elem = ai]; AppendTo[anovy, elem] ]; anovy (* vrátí: {12, p, c, {}} *)
S použitím vzorů a funkcionálního přístupu lze téhož dosáhnout i následovně:
Map[Function[y, ReplaceAll[y, RuleDelayed[Pattern[x, List[BlankSequence[]]], Last[x]] ] ], a] (* vrátí: {12, p, c, {}} *)
Tento druhý přístup lze přepsat do velmi kompaktního tvaru s použitím syntaktického cukru:
(# /. {x : {__} :> x-1}) & /@ a (* vrátí: {12, p, c, {}} *)
Na každý prvek pole a je pomocí funkce Map, představované zápisem /@, aplikována ryzí funkce
, jež vezme vstupní parametr, představovaný slotem #, a pomocí funkce ReplaceAll, představované zápisem /., provede substituci zadanou předpisem
. Toto substituční pravidlo nahradí každý výskyt seznamu o alespoň jednom prvku, představovaného výrazem {__} a pojmenovaného x, jeho posledním prvkem, to jest výrazem
.
Homoikonicita
WL umožňuje symbolické programování, kde s kódem samotným lze nakládat jako s daty. Pro ilustraci uveďme následující příklad, kde je cílem vytvořit vícerozměrné pole, kde dimenzi pole dopředu nevíme a je nechaná jako nezávislá proměnná. +more Pro konkrétnost mějme funkci f, kterou chceme aplikovat na vícerozměrné pole o dané dimenzi D. Toho lze dosáhnout funkcí Table, jejíž syntaxe zní.
Table[f[i1, i2, ..., iD], {i1, pocatek, konec}, {i2, pocatek, konec}, ..., {iD, pocatek, konec}];
kde i1, i2 atd. jsou indexovací proměnné a kde tři tečky . +more nejsou součástí kódu, ale pouze naznačují, že je potřeba dodat tolik indexovacích proměnných, kolik má být dimenze výsledného pole. Důležité v tomto ohledu je to, že výše uvedený zápis není jen syntaxí pro funkci Table, ale skutečně výraz tvaru hlavicka[telo], jehož hlavičkou je identifikátor Table a jehož tělo je tvořeno několika prvky, z nichž první má tvar f[i1, i2, . , iD] a zbylé prvky jsou seznamy. Přitom první prvek každého seznamu je symbol tvaru i1, i2, atd. , druhý prvek pocatek je celé číslo a třetí prvek každého seznamu je celé číslo konec.
Tato reprezentace kódu umožňuje napsat program, který vytvoří výše zadaný výraz pro libovolnou vstupní dimenzi a rozsah hodnot indexovací proměnné. Pro začátek uvažme dvourozměrné pole, jehož prvky jsou celá čísla v rozsahu -1 až 1. +more Následující kód bere jako vstupní proměnné proměnnou dimenze určující dimenzi pole a proměnné pocatek a konec určující rozsah hodnot v každé dimenzi. Výsledek je uložen do proměnné pole:.
dimenze = 2; pocatek = -1; konec = 1;
(* vygeneruj indexovací proměnné *) indexy = Symbol["i"ToString@#]& /@ Range[dimenze] (* vrátí: {i1, i2} *)
(* pro každou proměnnou specifikuj rozsah hodnot *) rozsahy = {#, pocatek, konec}& /@ indexy (* vrátí: {{i1, -1, 1}, {i2, -1, 1}} *)
(* vlož rozsahy do funkce Table, která vytvoří pole indexací přes dané rozsahy *) pole = Table[f@@indexy, Evaluate[Sequence@@rozsahy]] (* vrátí: {{f[-1,-1], f[-1,0], f[-1,1]}, {f[0,-1], f[0,0], f[0,1]}, {f[1,-1], f[1,0], f[1,1]}} *)
Tento kód lze snadno přizpůsobit pro libovolnou jinou dimenzi změnou hodnoty proměnné dimenze (samozřejmě za předpokladu, že funkce f bere více proměnných). Výše uvedený kód tak v podstatě odpovídá posloupnosti vnořených for cyklů, kde počet těchto cyklů není dopředu znám a je určen hodnotou proměnné zadané uživatelem.
Pokročilá definice funkce
Při definici funkce lze kromě samotného těla funkce specifikovat i značné množství dalších prvků, které ovlivňují chování funkce a její zobrazení v editoru. Uvažme funkci f[a,b], jejíž hlavní funkcí je dělit parametr a parametrem b. +more Spolu s tím chceme mít možnost nastavit, zda dělení má probíhat standardně či celočíselně. Pro ilustraci rozšířených možností definice ve WL jsou do následujícího kódu dodány i vzory, které by v reálném případě patrně nebyly potřeba.
(* smaž předchozí definice *) ClearAll[f]
(* dokumentační a chybová hlášení *) f::usage = "Dělení kladného celého čísla"; f::invpars = "Neplatné vstupy ``, ``."; f::divzero = "Dělení nuly nulou.";
(* první blok *) SyntaxInformation[f] = {"ArgumentsPattern" -> {__}}; SetAttributes[f, Listable]; Options[f] = {"Celociselne"->False}; Default[f] = 2;
(* druhý blok *) f[0, 0, ___] := Message[f::divzero];Indeterminate; f[x_Integer. NonNegative, y_. +more, OptionsPattern[]] /; y > 0 := Module[{meth = OptionValue["Celociselne"]}, If[meth, Quotient[x, y], x / y]] f[x_, y_, ___] := Message[f::invpars, x, y].
Nejprve příkazem ClearAll smažeme všechny předchozí definice symbolu f, pokud nějaké existovaly. Poté uvedeme dokumentační řetězec a chybová hlášení. +more Dále specifikujeme, viz sekci kódu "první blok", že se má uživateli v editoru barevně zvýraznit, nenapíše-li žádný vstupní parametr. Nastavením Listable jako atribut způsobíme, že při aplikaci funkce f na seznam se tato automaticky aplikuje na jednotlivé prvky. Funkce f má jednu volbu s názvem "Celociselne", udávající, má-li se provést dělení celočíselné či standardní. První blok kódu je zakončen příkazem Default[f] = 2, který udává, že pokud není dodán vstupní parametr, je automaticky použita hodnota 2.
Druhý blok kódu obsahuje definici samotnou. Nejprve je ošetřen hraniční případ, kdy by mělo dojít k dělení nuly nulou. +more V takovém případě je vypsána chybová hláška a vrácen předdefinovaný symbol Indeterminate, to jest, neurčité. Poté je dodána hlavní definice, která implementuje dělení vstupních parametrů. Tato definice je zavolána ale pouze tehdy, je-li první parametr nezáporné (NonNegative) celé číslo (Integer) a současně je druhý parametr kladný (y > 0). Pokud jsou tyto podmínky splněny, je nejprve vyvolána hodnota volby "Celociselne" a uložena do lokální proměnné meth. Je-li meth rovno True, je návratová hodnota výrazu If rovna výrazu Quotient[x,y]. Tento výraz je vyhodnocen a protože není If konstrukt ukončen středníkem, tak je výsledek výpočtu Quotient[x,y] vrácen funkcí f jako její návratová hodnota. Pokud je meth rovno False, probíhá vyhodnocení stejně, akorát je místo funkce Quotient použito reálného dělení.
Konečně, pokud nejsou splněny výše uvedené podmínky na vstupní parametry, je použita poslední část definice na posledním řádku začínající konstruktem f[x_, y_, ___]. Tento konstrukt neobsahuje žádné podmínky a vrací chybové hlášení. +more Nevyhodnotí se však vždy. Výše uvedená definice nezachycuje např. případy tvaru f[-10]. Takový výraz zůstává nevyhodnocen.
Vývojová prostředí
Existuje několik programů sloužících k psaní či alespoň prohlížení kódu a výstupů WL jazyka, přičemž až na jednu výjimku v podobě pluginu pro IntelliJ IDEA jsou všechny tyto programy vyvíjené společností Wolfram Research. Níže je jejich výběr.
Desktopová prostředí
Wolfram Mathematica - výchozí vývojářské prostředí pro práci s jazykem WL. Ze všech zde zmíněných programů představuje tento program jedinou plnohodnotnou implementaci WL jazyka. +more Mathematica umožňuje interaktivní práci s daty a kódem, její součástí jsou například pokročilá nastavení vzhledu zdrojového kódu a forma zpracovávaných dat. * Wolfram Workbench - nízkoúrovňovější alternativa k Mathematice, jež slouží spíše pro vývojáře. Jedná se o rozšíření pro vývojové prostředí Eclipse, jež primárně slouží pro vývoj aplikací v jazyce Java. Až do verze WL 13 byl Workbench jedinou možností pro koncové uživatele, jak vytvořit interaktivní dokumentaci pro svůj kód. * Wolfram Language plugin pro IntelliJ IDEA - Jedná se o plugin vývojového prostředí IntelliJ IDEA vyvíjeného společností JetBrains, které je též primárně určeno pro psaní kódu v jazyce Java.
Ostatní prostředí
Wolfram Cloud - cloudová obdoba Mathematicy, kdy je kód upravován z webového prohlížeče. Prostředí má oproti Mathematice omezenější funkcionalitu. +more * Wolfram Player - program pro prohlížení kódu bez možnosti jeho vyhodnocení. Umožňuje ale např. interaktivní prohlížení 3D grafiky. Tento program je k dispozici zdarma. * Wolfram Cloud App a Wolfram Player App - obdoby výše uvedených aplikací určené pro chytré telefony.
Příkazová řádka
Wolfram Kernel - přímý přístup k jádru WL bez funkcionality vyžadující frontend, jako třeba vykreslování grafiky. Lze vyvolat v příkazové řádce příkazem WolframKernel či wolfram v závislosti na operačním systému. +more * wolframscript - modernizovanější varianta umožňující provádění kódu z příkazové řádky či ze skriptů, provádění kódu lokálně či přes cloud apod. Skripty pro wolframscript mohou obsahovat shebang, díky nimž z nich lze v UNIXových systémech udělat spustitelný program.
Odkazy
Poznámky
Reference
Literatura
Související články
Externí odkazy
Zdroje v češtině
[url=https://www. pslib. +morecz/jaromir. oscadal/PRG%20-V1/Mathematica%20-%20p%C5%99%C3%ADru%C4%8Dka3. pdf]MATHEMATICA - příručka s příklady pro učitele a studenty[/url] (PDF) * [url=http://mathscience. upol. cz/materialy/software_mathematica_pro_geografy. pdf]Software Mathematica pro geografy[/url] (PDF), * [url=http://utf. mff. cuni. cz/~kusak/math. php. zalozka=1]Mathematica 7 - Základy používání programu[/url].
Zdroje v angličtině
[url=http://www. mathprogramming-intro. +moreorg/download/MathProgrammingIntro. pdf]Mathematica Programming: An Advanced Introduction[/url] (PDF) - Volně dostupná kniha se zevrubným úvodem do jazyka WL * [url=https://mathematica. stackexchange. com/questions/18393/what-are-the-most-common-pitfalls-awaiting-new-users]What are the most common pitfalls awaiting new users. [/url] - Neoficiální seznam začátečnických chyb * [url=https://mathematica. stackexchange. com/questions/18/where-can-i-find-examples-of-good-mathematica-programming-practice]Where can I find examples of good Mathematica programming practice. [/url] - Neoficiální rozcestník pro další zdroje o jazyku WL * [url=https://wolframlanguage. org/]WolframLanguage. org[/url] - Oficiální rozcestník pro další zdroje o jazyku WL * [url=https://reference. wolfram. com/language/]Wolfram Language & System Documentation Center[/url] - Dokumentace jazyka WL * [url=https://github. com/WolframResearch]GitHub WolframResearch[/url] - GitHub repozitář firmy Wolfram Research pro balíky s pokročilou funkčností.
Q & A portály v angličtině
[url=https://mathematica. stackexchange. +morecom/]Mathematica Stack Exchange[/url] - Stack Exchange portál pro otázky týkající se WL * [url=https://stackoverflow. com/questions/tagged/wolfram-mathematica]Wolfram Mathematica Stack Overflow[/url] - Stack Overflow portál pro otázky týkající se WL * [url=https://community. wolfram. com/]Wolfram Community[/url] - Portál na stránkách firmy Wolfram Research pro otázky týkající se WL.
Kategorie:Matematický software Kategorie:Počítačová algebra Kategorie:Funkcionální jazyky