Programovací jazyk OCaml

7. 9. 2023
Doba čtení: 18 minut

Sdílet

Autor: OCaml authors, podle licence: Rights Managed
Jazyk F# není jediným jazykem z rodiny ML, který se používá v praxi. Setkat se můžeme i s jazykem OCaml, který se od F# v některých ohledech odlišuje. Jeho výhodou je čistší návrh, nevýhodou pak může být ekosystém tohoto jazyka.

Obsah

1. Programovací jazyk OCaml

2. Instalace balíčku opam

3. Inicializace prostředí přes správce opam

4. Instalace interaktivního prostředí utop

5. Přímá interakce s interpretrem jazyka OCaml

6. Využití interaktivního prostředí utop

7. Základní základy programovacího jazyka OCaml

8. Tisk hodnot na terminál

9. Jak spustit program typu „Hello, world!“?

10. Definice funkce

11. Zavolání funkce

12. Anonymní funkce

13. Explicitní specifikace návratového typu funkcí

14. Nepřetížené operátory

15. Lokální symboly

16. Repositář s demonstračními příklady

17. Odkazy na Internetu

1. Programovací jazyk OCaml

„OCaml: the rehabilitation clinic for OO programmers.“
Erik Meijer

Na úvodní článek o programovacím jazyku F# dnes částečně navážeme, protože se seznámíme se základy jazyka OCaml, jenž je považován za předka jazyka F# (a současně za jazyk, kterého F# v některých ohledech nikdy nepředběhl). Samotný jazyk OCaml se vyvinul z programovacího jazyka nazvaného Caml, přičemž předchůdci OCamlu se jmenovali Caml light a Caml special light. Po přidání podpory pro objektově orientované programování vznikl jazyk se jménem Objective Caml neboli zkráceně OCaml (podrobnější historie byla zmíněna právě v článku o F#).

Poznámka: ve skutečnosti je objektově orientované programování v OCamlu realizováno jen jako „povinný“ přídavný modul jazyka a vůbec ho není zapotřebí využít.

Obrázek 1: Logo jazyka OCaml. Jak jsme si již řekli v článku o F#, pokud zvíře míří doprava, jedná se o jazyk OCaml, pokud doleva, jde o Perl.

V dnešním článku si nejdříve řekneme, jak se OCaml nainstaluje, jak se nastaví jeho interaktivní prostředí utop a taktéž se seznámíme se základy tohoto zajímavého a stále poněkud přehlíženého programovacího jazyka, včetně jedné významné odlišnosti oproti jazyku F# (jedná se o striktní oddělení operátorů pro jednotlivé datové typy).

2. Instalace balíčku opam

V navazujícím textu si řekneme, jakým způsobem je možné si nainstalovat nástroje nutné pro psaní aplikací v programovacím jazyku OCaml (ve skutečnosti si postupně doinstalujeme prakticky celý ekosystém OCamlu). Většinu potřebných základních balíčků pro vývoj v OCamlu většinou nalezneme přímo v repositářích distribuce Linuxu. Vhodné je nainstalovat si přímo balíček nazvaný opam, což je správce prostředí pro OCaml (tedy přibližně obdoba pip+virtualenv). Příkladem může být instalace balíčku opam na Ubuntu či Mintu:

$ sudo apt-get install opam

Povšimněte si, že se skutečně nejedná o minimalistickou instalaci, protože ekosystém OCamlu společně se závislostmi (mj. i C++) vyžaduje přibližně půl gigabajtu diskového prostoru:

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  build-essential cpp-9 darcs g++ g++-9 gcc-9 gcc-9-base ledit libamd2 libasan5 libgcc-9-dev libglpk40 libncurses-dev libncurses5-dev libncurses6
  libncursesw6 libstdc++-9-dev libtinfo6 mercurial mercurial-common ocaml ocaml-base ocaml-base-nox ocaml-compiler-libs ocaml-interp ocaml-man ocaml-nox
  opam-doc opam-installer
Suggested packages:
  gcc-9-locales g++-multilib g++-9-multilib gcc-9-doc gcc-9-multilib libiodbc2-dev default-libmysqlclient-dev ncurses-doc libstdc++-9-doc kdiff3 | kdiff3-qt
  | kompare | meld | tkcvs | mgdiff qct python-mysqldb python-openssl python-pygments wish ocaml-doc tuareg-mode
The following NEW packages will be installed:
  build-essential darcs g++ g++-9 ledit libamd2 libglpk40 libncurses-dev libncurses5-dev libstdc++-9-dev mercurial mercurial-common ocaml ocaml-base
  ocaml-base-nox ocaml-compiler-libs ocaml-interp ocaml-man ocaml-nox opam opam-doc opam-installer
The following packages will be upgraded:
  cpp-9 gcc-9 gcc-9-base libasan5 libgcc-9-dev libncurses6 libncursesw6 libtinfo6
8 upgraded, 22 newly installed, 0 to remove and 362 not upgraded.
Need to get 127 MB of archives.
After this operation, 478 MB of additional disk space will be used.

Po (doufejme, že úspěšném) dokončení instalace si vyzkoušejte, zda je možné spustit příkaz opam:

$ opam

Měla by se vypsat tato nápověda:

usage: opam [--version]
            [--help]
            <command> [<args>]
 
The most commonly used opam commands are:
    init         Initialize opam state, or set init options.
    list         Display the list of available packages.
    show         Display information about specific packages.
    install      Install a list of packages.
    remove       Remove a list of packages.
    update       Update the list of available packages.
    upgrade      Upgrade the installed package to latest version.
    config       Display configuration options for packages.
    repository   Manage opam repositories.
    switch       Manage multiple installation prefixes.
    pin          Pin a given package to a specific version or source.
    admin        Tools for repository administrators
 
See 'opam help <command>' for more information on a specific command.

3. Inicializace prostředí přes správce opam

V dalším kroku provedeme inicializaci prostředí využívaného správcem opam. Jedná se o operaci, kterou je nutné provést pouze jedenkrát, takže i když se jedná o poměrně pomalou operaci (cca jedna až dvě minuty v závislosti na rychlosti připojení), nebude nutné tuto operaci opakovat:

$ opam init

Povšimněte si, že se v rámci inicializace stahují balíčky jazyka OCaml:

[NOTE] Will configure from built-in defaults.
Checking for available remotes: rsync and local, git, mercurial, darcs. Perfect!
 
<><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><>
[default] Initialised
 
A hook can be added to opam's init scripts to ensure that the shell remains in sync with the opam environment when they are loaded. Set that up? [y/N] n
 
<><> Creating initial switch (ocaml-system>=4.02.3) <><><><><><><><><><><><><><>
 
<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
 
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base
∗ installed ocaml-system.4.08.1
∗ installed ocaml-config.1
∗ installed ocaml.4.08.1
Done.
# Run eval $(opam env) to update the current shell environment
Poznámka: poslední řádek, který je vypsán, je důležitý, protože nastaví všechny potřebné proměnné prostředí. Tento příklad (je proveden okamžitě) lze opakovat před každým „sezením“ s jazykem OCaml.

4. Instalace interaktivního prostředí utop

Již v rámci předchozího kroku se nainstalovaly všechny nástroje nutné pro vývoj v jazyku OCaml, tedy jak interpret, tak i překladač do nativního kódu společně s překladačem do bajtkódu. Ovšem v praxi je výhodnější namísto standardního interpretru jazyka OCaml použít interaktivní prostředí nazvané utop. To již můžeme nainstalovat přímo přes správce balíčků opam, a to konkrétně následujícím způsobem:

$ opam install utop

Společně s utop se nainstaluje i celá řada dalších nástrojů a balíčků. S některými z nich (například s dune) se ještě později setkáme:

The following actions will be performed:
  ∗ install dune              3.10.0 [required by utop]
  ∗ install ocamlfind         1.9.6  [required by utop]
  ∗ install ocamlbuild        0.14.2 [required by logs]
  ∗ install trie              1.0.0  [required by mew]
  ∗ install result            1.5    [required by zed]
  ∗ install csexp             1.5.2  [required by dune-configurator]
  ∗ install cppo              1.6.9  [required by utop]
  ∗ install base-bytes        base   [required by ocplib-endian]
  ∗ install uchar             0.0.2  [required by zed]
  ∗ install topkg             1.0.7  [required by logs]
  ∗ install mew               0.1.0  [required by mew_vi]
  ∗ install dune-configurator 3.10.0 [required by lwt]
  ∗ install ocplib-endian     1.2    [required by lwt]
  ∗ install uutf              1.0.3  [required by zed]
  ∗ install react             1.2.2  [required by utop]
  ∗ install lwt               5.7.0  [required by utop]
  ∗ install uucp              15.0.0 [required by zed]
  ∗ install mew_vi            0.5.0  [required by lambda-term]
  ∗ install lwt_react         1.2.0  [required by utop]
  ∗ install logs              0.7.0  [required by utop]
  ∗ install uuseg             15.0.0 [required by zed]
  ∗ install zed               3.2.1  [required by utop]
  ∗ install lambda-term       3.3.2  [required by utop]
  ∗ install utop              2.12.1
===== ∗ 24 =====
 
∗ installed dune.3.10.0
∗ installed csexp.1.5.2
∗ installed cppo.1.6.9
∗ installed result.1.5
∗ installed trie.1.0.0
∗ installed ocplib-endian.1.2
∗ installed uuseg.15.0.0
∗ installed mew.0.1.0
∗ installed zed.3.2.1
∗ installed mew_vi.0.5.0
∗ installed dune-configurator.3.10.0
∗ installed lwt.5.7.0
∗ installed lwt_react.1.2.0
∗ installed logs.0.7.0
∗ installed lambda-term.3.3.2
∗ installed utop.2.12.1
Done.

5. Přímá interakce s interpretrem jazyka OCaml

Po instalaci OCamlu a nastavení jeho prostředí si můžeme spustit interpret tohoto programovacího jazyka. Je to snadné, protože postačuje použít následující příkaz:

$ ocaml

Na terminál by se měla vypsat aktuálně nainstalovaná verze, konkrétně:

        OCaml version 4.08.1

Znak # znamená výzvu (prompt), což znamená, že za tento znak můžeme zadávat jednotlivé příkazy (což jsou prakticky vždy výrazy), interpret je zpracuje, vyhodnotí a vypíše jejich výsledek. Pokusme se například o součet hodnot 1+1:

# 1+1;;
- : int = 2

Povšimněte si zejména toho, že výsledkem není pouze vypsaná hodnota, ale současně i její typ, a to vždy. V tomto ohledu je jazyk OCaml (resp. přesněji řečeno jeho interpret) velmi důsledný.

6. Využití interaktivního prostředí utop

V rámci čtvrté kapitoly jsme si nainstalovali nástroj nazvaný utop, jehož použití je v naprosté většině případů příjemnější, než konverzace se standardním interpretrem jazyka OCaml. utop totiž používá zvýraznění jednotlivých typů zpráv, nabízí plnohodnotnou editaci na příkazovém řádku, zobrazuje seznam modulů atd. Nástroj utop se spustí jednoduše:

$ utop

Podívejme se nyní na to, jak vypadá jeho prostředí:

Obrázek 2: Prostředí utop po svém spuštění. V horní části terminálu jsou zobrazeny uvítací zprávy, v prostřední části vidíme vstupní textové pole (víceřádkové) a na spodním okraji se zobrazuje seznam modulů (a po zápisu jména modulu se zobrazí jména funkcí a dalších symbolů z daného modulu).

Obrázek 3: Definice funkce a zavolání této funkce v prostředí utop.

Poznámka: v utop lze použít většinu známých klávesových zkratek, například Ctrl+A a Ctrl+E pro pohyb kurzoru, vyhledávání v historii přes Ctrl+R atd. atd.

7. Základní základy programovacího jazyka OCaml

Podobně jako F#, patří i OCaml do rodiny funkcionálních programovacích jazyků, konkrétně do skupiny se silným typovým systémem (na rozdíl od LISPu či Clojure) a s podporou typové inference. Při popisu OCamlu se tedy budeme snažit soustředit se právě na tyto dva prvky jazyka – na způsob práce s funkcemi a práce s datovými typy. Dnes se seznámíme s těmi prvky OCamlu, které jsme si (v případě jazyka F#) popsali v již zmíněném úvodním článku. Ukážeme si tedy způsob definice funkce, odvození typu funkce a v neposlední řadě taktéž specifický přístup jazyka OCaml k rozeznání operací podle použitých operátorů.

8. Tisk hodnot na terminál

Pro tisk nějaké hodnoty či hodnot na terminál nabízí programovací jazyk OCaml funkce, v jejichž názvu se již tradičně – ostatně podobně jako v naprosté většině ostatních programovacích jazyků – vyskytuje slovo print. Některé z těchto funkcí jsou umístěny ve výchozím modulu; jedná se například o funkci print_string, print_int atd. Program typu „Hello, world!“ by tedy mohl v OCamlu vypadat následovně:

print_string "Hello, world!"

Další podobně koncipované funkce nalezneme v modulu nazvaném Printf. Jedná se zejména o funkci printf, která nabízí formátovaný výstup (známe z C, Javy atd. atd.). Vzhledem k tomu, že „Hello, world!“ neobsahuje žádný formátovací znak, můžeme psát:

Printf.printf "Hello, world!"

9. Jak spustit program typu „Hello, world!“?

Prográmky ukázané v předchozí kapitole lze spustit několika způsoby. Ukažme si některé základní způsoby, k dalším metodám se vrátíme později:

  1. Spustíme interpret příkazem ocaml a překopírujeme do něj zdrojový kód
  2. Spustíme interaktivní prostředí utop a překopírujeme do něj zdrojový kód
  3. Spustíme interpret, ovšem se zadáním skriptu, který se má použít: ocaml hello_world1.ml
  4. Dtto v případě prostředí utop: utop -init hello_worlld.ml
  5. V interpretru i interaktivním prostředí můžeme použít příkaz #use „hello_world.ml“
  6. A v neposlední řadě je možné program přeložit do nativního kódu příkazem ocamlc hello_world1 (k tomu se ještě vrátíme)

10. Definice funkce

Jazyk OCaml patří do rodiny funkcionálních programovacích jazyků, jak již to ostatně částečně prozrazuje jeho jméno. A ve funkcionálních programovacích jazycích mají funkce stejně plnohodnotný význam, jako jakékoli jiné hodnoty. V jazyku OCaml je neanonymní funkce vytvořena stejně jako jakákoli jiná hodnota s využitím klíčového slova let (zatímco u jazyka ML se používalo klíčové slovo fun). Vyzkoušíme si to na definici funkce pojmenované inc, která bude mít jediný parametr nazvaný x. V těle funkce se vypočte výraz x+1, jehož výsledek je současně i návratovou hodnotou funkce:

let inc x = x + 1;;
Poznámka: dvojice středníků je důležitá v interpretru/utopu, protože ukončuje výraz.

U této funkce je zajímavé především to, že jsme nikde neuvedli typ parametru ani typ návratové hodnoty a přesto jazyk OCaml korektně zjistil, že se jedná o funkci int → int (tedy jediným parametrem je celé číslo a návratovou hodnotou je taktéž celé číslo). Přitom se vychází z těla funkce, tedy z výrazu n+1, což je v jazyku OCaml striktně součet dvou celých čísel (zde navíc mnohem striktnější, než například v F#, kde jsou operátory přetížené).

11. Zavolání funkce

Podívejme se nyní na způsob zavolání již definované funkce. Při samotném volání funkce se parametry nemusí psát do závorek, ani se nemusí oddělovat čárkami:

let inc x = x+1;;
 
let y = inc 10;;

Ovšem pokud se funkce volá v pozici, že její výsledek je parametrem jiné funkce, závorkám se nevyhneme. Ovšem píšou se okolo celého vyhodnocovaného parametru – podvýrazu:

let inc x = x+1;;
 
print_int (inc 10);;

Alternativní způsob, kdy voláme funkci Prinft.printf s dvojicí parametrů, by mohl vypadat takto:

let inc x = x+1;;
 
Printf.printf "%d" (inc 10);;
Poznámka: tím jsme si současně ukázali, jak se volá funkce s více parametry – opět žádné závorky (až na případné podvýrazy), žádné čárky.

12. Anonymní funkce

V jazyku OCaml taktéž existuje klíčové slovo fun, ovšem na rozdíl od jazyka ML (ze kterého OCaml vychází) se používá pro definici anonymních funkcí (známé lambda výrazy):

fun x -> x + 1;;

Předchozí řádek zapsaný uživatelem vytvořil anonymní funkci (bez jména) a navázal ji na speciální symbol it, jenž vždy (v interaktivním prostředí) obsahuje výsledek posledního výrazu. To znamená, že anonymní funkci můžeme zavolat (a ihned poté ztratit odkaz na ni).

Ve skutečnosti je definice klasické funkce ukázaná v předchozích kapitolách jen syntaktickým cukrem k plnému zápisu:

let inc = fun x -> x+1;;
 
Printf.printf "%d" (inc 2);;

nebo:

let add = fun x y -> x+y;;
 
Printf.printf "%d" (add 1 2);;

Což je vlastně ekvivalentní zápisu anonymní funkce v JavaScriptu s přiřazením výsledku do konstanty:

const add = function (x, y) {
  return x + y;
};

nebo možná ještě lépe (stále se nacházíme v peklu zvaném JavaScript):

let add = (x, y) => x + y;

13. Explicitní specifikace návratového typu u funkcí

U funkce inc v původním tvaru:

let inc x = x + 1;;

se typ jejího argumentu a taktéž i typ výsledné hodnoty odvodí na základě použitého operátoru.

V případě potřeby je pochopitelně možné explicitně specifikovat typ argumentu či argumentů funkce, popř. můžeme zapsat typ návratové hodnoty. Syntaxe je v tomto případě jednoduchá – za jméno argumentu (či argumentů) se zapíše dvojtečka a za ní požadovaný datový typ, přičemž argument i typ musí být v závorce:

let inc (x:int) = x+1;;

Typ návratové hodnoty se píše pouze za dvojtečku; nyní již bez závorek. Například můžeme specifikovat, že typ argumentu x má být explicitně celočíselná hodnota:

let inc x:int = x + 1;;

Na rozdíl od programovacího jazyka F# však nemůžeme specifikovat typ argumentu jako float, protože se provádí celočíselné sčítání (operátor + není v OCamlu přetížený):

let inc x:float = x + 1;;

Zjištěná chyba ve výrazu x + 1:

Error: This expression has type int but an expression was expected of type float

14. Nepřetížené operátory

V jazyku OCaml (ale nikoli už v F#) se striktně rozlišuje mezi celočíselnými operátory a operátory pro hodnoty typu float (což dále zpřísňuje typovou kontrolu). Konkrétně to znamená, že pro typ float je za všemi základními aritmetickými operátory zapsaná tečka. Následující příklad je tedy nekorektní a OCaml (interpret i překladač) na chybu upozorní:

let inc x:float = x+1.0;;
 
Printf.printf "%f" (inc 2.0);;

Korektní zápis vypadá následovně (povšimněte si, že voláme operátor +. a nikoli jen +):

let inc x:float = x+.1.0;;
 
Printf.printf "%f" (inc 2.0);;

15. Lokální symboly

Na závěr dnešního článku se zmiňme ještě o jednom rozdílu mezi jazyky OCaml a F#. Oba jazyky umožňují definice lokálních symbolů (a tedy i prostředí navázaného na tyto symboly), ovšem OCaml vyžaduje použití klíčového slova in (v F# je situace složitější, protože tento jazyk umožňuje přepínání mezi více syntaxemi). Použití lokálního symbolu x při výpočtu hodnoty proměnné answer tedy může vypadat následovně:

bitcoin školení listopad 24

let answer =
        let x = 6 in
        x*7;;
 
Printf.printf "anwser=%d" answer

Podobně lze vytvořit více lokálních symbolů:

let answer =
  let x = 6 in
  let y = 7 in
  x*y
;;
 
Printf.printf "anwser=%d" answer
Poznámka: třetí a čtvrtý řádek by měl být teoreticky odsazen, ovšem v reálných programech se setkáme s předchozím stylem odsazení.

16. Repositář s demonstračními příklady

Všechny výše popsané demonstrační příklady byly uloženy do repositáře dostupného na adrese https://github.com/tisnik/ocaml-examples/. V tabulce umístěné pod tímto odstavcem jsou uvedeny odkazy na tyto příklady:

# Příklad Popis příkladu Cesta
1 hello_world1.ml zavolání funkce print_string https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/hello_world1.ml
2 hello_world2.ml zavolání funkce printf.Printf https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/hello_world2.ml
       
3 function.ml definice funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/function.ml
4 lambda.ml anonymní funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/lambda.ml
       
5 function_type1.ml explicitní specifikace typu návratové hodnoty funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/function_type1.ml
6 function_type2.ml explicitní specifikace typu návratové hodnoty funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/function_type2.ml
       
7 call_function1.ml definice jednoduché funkce s jejím zavoláním https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function1.ml
8 call_function2.ml definice jednoduché funkce s jejím zavoláním https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function2.ml
9 call_function3.ml použití operátoru + pro dvojici hodnot typu float https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function3.ml
10 call_function4.ml použití operátoru +. pro dvojici hodnot typu float https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function4.ml
11 call_function5.ml plná deklarace funkce bez syntaktického cukru https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function5.ml
12 call_function6.ml plná deklarace funkce bez syntaktického cukru https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function6.ml
       
13 local_binding1.ml definice lokálních symbolů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/local_binding1.ml
14 local_binding2.ml definice lokálních symbolů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/local_binding2.ml

17. Odkazy na Internetu

  1. General-Purpose, Industrial-Strength, Expressive, and Safe
    https://ocaml.org/
  2. OCaml playground
    https://ocaml.org/play
  3. Online Ocaml Compiler IDE
    https://www.jdoodle.com/compile-ocaml-online/
  4. Get Started – OCaml
    https://www.ocaml.org/docs
  5. Get Up and Running With OCaml
    https://www.ocaml.org/docs/up-and-running
  6. Better OCaml (Online prostředí)
    https://betterocaml.ml/?ver­sion=4.14.0
  7. OCaml file extensions
    https://blog.waleedkhan.name/ocaml-file-extensions/
  8. First thoughts on Rust vs OCaml
    https://blog.darklang.com/first-thoughts-on-rust-vs-ocaml/
  9. Standard ML of New Jersey
    https://www.smlnj.org/
  10. Programming Languages: Standard ML – 1 (a navazující videa)
    https://www.youtube.com/wat­ch?v=2sqjUWGGzTo
  11. 6 Excellent Free Books to Learn Standard ML
    https://www.linuxlinks.com/excellent-free-books-learn-standard-ml/
  12. SOSML: The Online Interpreter for Standard ML
    https://sosml.org/
  13. ML (Computer program language)
    https://www.barnesandnoble­.com/b/books/other-programming-languages/ml-computer-program-language/_/N-29Z8q8Zvy7
  14. Strong Typing
    https://perl.plover.com/y­ak/typing/notes.html
  15. What to know before debating type systems
    http://blogs.perl.org/user­s/ovid/2010/08/what-to-know-before-debating-type-systems.html
  16. Types, and Why You Should Care (Youtube)
    https://www.youtube.com/wat­ch?v=0arFPIQatCU
  17. DynamicTyping (Martin Fowler)
    https://www.martinfowler.com/bli­ki/DynamicTyping.html
  18. DomainSpecificLanguage (Martin Fowler)
    https://www.martinfowler.com/bli­ki/DomainSpecificLanguage­.html
  19. Language Workbenches: The Killer-App for Domain Specific Languages?
    https://www.martinfowler.com/ar­ticles/languageWorkbench.html
  20. Effective ML (Youtube)
    https://www.youtube.com/watch?v=-J8YyfrSwTk
  21. Why OCaml (Youtube)
    https://www.youtube.com/wat­ch?v=v1CmGbOGb2I
  22. Try OCaml
    https://try.ocaml.pro/
  23. CSE 341: Functions and patterns
    https://courses.cs.washin­gton.edu/courses/cse341/04wi/lec­tures/03-ml-functions.html
  24. Comparing Objective Caml and Standard ML
    http://adam.chlipala.net/mlcomp/
  25. What are the key differences between Standard ML and OCaml?
    https://www.quora.com/What-are-the-key-differences-between-Standard-ML-and-OCaml?share=1
  26. Cheat Sheets (pro OCaml)
    https://www.ocaml.org/doc­s/cheat_sheets.html
  27. Think OCaml: How to Think Like a (Functional) Programmer
    https://www.greenteapress­.com/thinkocaml/thinkocam­l.pdf
  28. The OCaml Language Cheat Sheet
    https://ocamlpro.github.io/ocaml-cheat-sheets/ocaml-lang.pdf
  29. Syllabus (FAS CS51)
    https://cs51.io/college/syllabus/
  30. Abstraction and Design In Computation
    http://book.cs51.io/
  31. Learn X in Y minutes Where X=Standard ML
    https://learnxinyminutes.com/doc­s/standard-ml/
  32. CSE307 Online – Summer 2018: Principles of Programing Languages course
    https://www3.cs.stonybrook­.edu/~pfodor/courses/summer/cse307­.html
  33. CSE307 Principles of Programming Languages course: SML part 1
    https://www.youtube.com/wat­ch?v=p1n0_PsM6hw
  34. CSE 307 – Principles of Programming Languages – SML
    https://www3.cs.stonybrook­.edu/~pfodor/courses/summer/CSE307/L01_SML­.pdf
  35. History of programming languages
    https://devskiller.com/history-of-programming-languages/
  36. History of programming languages (Wikipedia)
    https://en.wikipedia.org/wi­ki/History_of_programming_lan­guages
  37. The Evolution Of Programming Languages
    https://www.i-programmer.info/news/98-languages/8809-the-evolution-of-programming-languages.html
  38. Evoluce programovacích jazyků
    https://ccrma.stanford.edu/cou­rses/250a-fall-2005/docs/ComputerLanguagesChart.png
  39. Currying
    https://sw-samuraj.cz/2011/02/currying/
  40. Currying (Wikipedia)
    https://en.wikipedia.org/wi­ki/Currying
  41. Currying (Haskell wiki)
    https://wiki.haskell.org/Currying
  42. Haskell Curry
    https://en.wikipedia.org/wi­ki/Haskell_Curry
  43. Moses Schönfinkel
    https://en.wikipedia.org/wi­ki/Moses_Sch%C3%B6nfinkel
  44. So You Want to be a Functional Programmer (Part 1)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-1–1f15e387e536
  45. So You Want to be a Functional Programmer (Part 2)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-2–7005682cec4a
  46. So You Want to be a Functional Programmer (Part 3)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-3–1b0fd14eb1a7
  47. So You Want to be a Functional Programmer (Part 4)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-4–18fbe3ea9e49
  48. So You Want to be a Functional Programmer (Part 5)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-5-c70adc9cf56a
  49. So You Want to be a Functional Programmer (Part 6)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-6-db502830403
  50. Python to OCaml: Retrospective
    http://roscidus.com/blog/blog/2014/06/0­6/python-to-ocaml-retrospective/
  51. Why does Cambridge teach OCaml as the first programming language?
    https://www.youtube.com/wat­ch?v=6APBx0WsgeQ
  52. OCaml and 7 Things You Need To Know About It In 2021 | Functional Programming | Caml
    https://www.youtube.com/wat­ch?v=s0itOsgcf9Q
  53. OCaml 2021 – 25 years of OCaml
    https://www.youtube.com/watch?v=-u_zKPXj6mw

Autor článku

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