Operátory v programovacím jazyku OCaml

17. 10. 2023
Doba čtení: 35 minut

Sdílet

 Autor: Depositphotos
Operátory hrají v jazycích odvozených od ML podstatnou roli. Jedná se jak o standardní operátory, tak i o možnost vytvoření operátorů zcela nových, u nichž lze určit i jejich prioritu a asociativitu.

Obsah

1. Operátory v programovacím jazyku OCaml

2. Problematika přetěžování operátorů

3. Definice nových operátorů, další přetížení existujících operátorů

4. Rozdělení programovacích jazyků podle jejich přístupu k operátorům

5. Standardní operátory v OCamlu

6. Unární aritmetické operátory

7. Binární aritmetické operátory

8. Booleovské operátory

9. Relační operátory

10. Testy na ekvivalenci

11. Operátory pro spojování řetězců a seznamů

12. Operátory pro čtení a zápis hodnoty přes referenci

13. Ostatní standardní operátory

14. Definice nových operátorů v jazyce OCaml

15. Pravidla pro definici nových operátorů

16. Definice vlastních unárních operátorů

17. Definice vlastních binárních operátorů

18. Asociativita a priorita vlastních operátorů

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

20. Odkazy na Internetu

1. Operátory v programovacím jazyku OCaml

V předchozím článku o programovacím jazyku OCaml jsme si kromě hlavních témat (jednalo se o datové typy Option, Result a Array) ukázali i způsob definice nového operátoru:

let (>>=) = Result.bind ;;

Operátory hrají v jazycích odvozených od jazyka ML podstatnou roli. Jedná se jak o standardní operátory (v OCamlu jich existuje téměř čtyřicet), tak i o možnost vytvoření operátorů zcela nových, u nichž lze dokonce určit i jejich prioritu a asociativitu. Vlastnosti existujících i nových operátorů budou tématem dnešního článku.

2. Problematika přetěžování operátorů

V mnoha programovacích jazycích se setkáme s takzvanými přetíženými operátory. Jedná se o operátory, jejichž funkce a vlastnosti se mění podle typu operandů. Pravděpodobně nejznámější formou přetížených operátorů jsou operátory určené pro provádění základních aritmetických operací, které bývají definovány pro různé numerické datové typy. Ovšem například operátor + může být přetížen vícekrát, typicky pro operaci spojení řetězců (viz například Java) či například n-tic a seznamů (Python). V těchto případech se nejenom mění funkce operátoru (tj. součet je zcela rozdílná operace od spojení řetězců), ale i jejich další vlastnosti, v tomto případě například komutativita (a nepřímo taktéž asociativita v případě hodnot s plovoucí řádovou čárkou).

V programovacím jazyku OCaml je většina standardních operátorů nepřetížených, což v důsledku znamená, že například aritmetické operace nad celými čísly jsou realizovány odlišnými operátory, než tytéž operace, ovšem na hodnotami s plovoucí řádovou čárkou (v F# je tomu ovšem jinak). Přetížené jsou jen některé operátory, zejména operátory pro porovnání dvou hodnot. Takové operátory akceptují dvojici hodnot se stejným typem, jak si ukážeme dále (a jsou vlastně definovány jako generická funkce).

3. Definice nových operátorů, další přetížení existujících operátorů

Některé programovací jazyky umožňují definici zcela nových operátorů popř. přetížení existujících operátorů. Z tohoto pohledu můžeme programovací jazyky rozdělit do čtyř skupin na základě dvou vlastností (které jsou na sobě nezávislé):

  1. Lze definovat nové operátory?
  2. Lze přetížit stávající operátory?
Poznámka: existující „původní“ operátory jsou v mnoha programovacích jazycích již přetíženy tvůrci jazyka, což ovšem nic neříká o tom, zda je možné je dále přetížit na úrovni programu nebo knihovny. Dobrým příkladem je například již zmíněná Java, v níž nelze dále přetížit operátor + pro různé třídy, například typu BigDecimal, i když by to bylo sémanticky naprosto vyhovující.

4. Rozdělení programovacích jazyků podle jejich přístupu k operátorům

Zajímavé je, že každá ze čtyř kombinací zmíněných v předchozí kapitole je obsazena nějakým jazykem (a to zcela nezávisle na dalších vlastnostech daného jazyka, tedy nezávisle na typovém systému, podpoře OOP, maker atd.):

Nové operátory nelze přidávat a existující operátory nelze dále přetěžovat

BASIC
C
Go
Java
JavaScript
Modula-2
Objective-C
Pascal
TypeScript
Visual Basic

Nové operátory nelze přidávat, ale existující operátory je možné přetěžovat

Ada
C#
C++
D
Dart
FreeBASIC
Groovy
Java
Kotlin
Lua
MATLAB
Object Pascal
PHP
Perl
Python
Ruby
Rust
Visual Basic .NET

Lze definovat nové operátory, existující operátory ovšem nelze dále přetěžovat

ML
Pico
Prolog
Smalltalk

Lze definovat nové operátory, navíc je možné přetěžovat existující operátory

ALGOL 68
Eiffel
Fortran
F#
Haskell
Io
Nim
R
Raku
Scala
Swift

5. Standardní operátory v OCamlu

V programovacím jazyce OCaml nalezneme celkem 39 standardních operátorů, tj. operátorů, u kterých je nejenom přesně specifikována prováděná operace, ale taktéž datové typy operandu či (obou) operandů; v závislosti na tom, zda se jedná o unární či o binární operátor. Jedná se o následující operátory:

 
    =        <>       <         >
    <=       >=       ==        !=
    &&       &        ||        |
    |>       @@       **        ^
    +        -        *         /
    +.       -.       *.        /.
    ~+       ~-       ~+.       ~-.
    @        !        :=        ^^
    mod      land     lor      lxor
    lsl      lsr      asr
 

Jednotlivé operátory z výše uvedeného seznamu budou popsány v navazujících kapitolách.

6. Unární aritmetické operátory

Začneme popisem unárních aritmetických operátorů, protože jejich popis je (alespoň na první pohled) snadný. Unární operátory akceptují jediný operand na pravé straně:

Operátor Vstupní operand Výsledek Popis operátoru
~- int int unární – (změna znaménka)
~+ int int unární +
       
~-. float float unární – (změna znaménka)
~+. float float unární +
Poznámka: tyto operátory lze zapisovat i bez tildy na začátku, tj.:
Operátor Vstupní operand Výsledek Popis operátoru
int int unární – (změna znaménka)
+ int int unární +
       
-. float float unární – (změna znaménka)
+. float float unární +

Navíc platí ještě jedna konvence – operátory + a – akceptují i hodnotu typu float a vrací float (takže jsou z tohoto pohledu přetížené, i když to jejich deklarace nenaznačuje.

Podívejme se na několik příkladů:

+42;;
- : int = 42
 
+1.5;;
- : float = 1.5
 
-1.5;;
- : float = -1.5
 
- -42;;
- : int = 42
 
- -1.5;;
- : float = 1.5
 
+.3.14;;
- : float = 3.14
 
-.3.14;;
- : float = -3.14
 
~-42;;
- : int = -42
 
~-.3.14;;
- : float = -3.14

Deklarace všech čtyř zmíněných operátorů lze získat takto:

(~+) ;;
- : int -> int = <fun>
 
(~-) ;;
- : int -> int = <fun>
 
(~+.) ;;
- : float -> float = <fun>
 
(~-.) ;;
- : float -> float = <fun>
Poznámka: jedná se tedy o funkce, pouze se svým „syntaktickým cukrem“.

7. Binární aritmetické operátory

Následuje poměrně velké množství binárních aritmetických operátorů, které jsou opět rozděleny podle toho, zda jsou definovány pro operandy typu int či float (devátý operátor je definován pouze pro typ float):

Operátor Vstupní operandy Výsledek Popis operátoru
+ int int součet
int int rozdíl
* int int součin
/ int int podíl
mod int int zbytek po celočíselném dělení
       
land int int bitový součin
lor int int bitový součet
lxor int int bitová nonekvivalence
lsl int int bitový posun doleva
lsr int int bitový posun doprava
asr int int aritmetický posun doprava
       
+. float float součet
-. float float rozdíl
*. float float součin
/. float float podíl
** float float umocnění

Příklady použití těchto operátorů:

10 + 3;;
- : int = 13
 
10 - 3;;
- : int = 7
 
10 * 3;;
- : int = 30
 
10 / 3;;
- : int = 3
 
10.0 +. 3.0;;
- : float = 13.
 
10.0 -. 3.0;;
- : float = 7.
 
10.0 *. 3.0;;
- : float = 30.
 
10.0 /. 3.0;;
- : float = 3.33333333333333348
 
10.0 ** 3.0;;
- : float = 1000.

V OCamlu jsou prováděny striktní typové kontroly:

1 + 2.0;;
Line 1, characters 4-7:
Error: This expression has type float but an expression was expected of type int
 
1 +. 2;;
Line 1, characters 0-1:
Error: This expression has type int but an expression was expected of type float
  Hint: Did you mean `1.'?

Opět se podívejme na typovou definici všech operátorů. Mezi závorkami a operátorem jsou přidány mezery, protože (* a *) se používá i pro zápis komentářů:

( + ) ;;
- : int -> int -> int = <fun>
 
( - ) ;;
- : int -> int -> int = <fun>
 
( * ) ;;
- : int -> int -> int = <fun>
 
( / ) ;;
- : int -> int -> int = <fun>
 
( +. ) ;;
- : float -> float -> float = <fun>
 
( -. ) ;;
- : float -> float -> float = <fun>
 
( *. ) ;;
- : float -> float -> float = <fun>
 
( /. ) ;;
- : float -> float -> float = <fun>
 
( ** ) ;;
- : float -> float -> float = <fun>

8. Booleovské operátory

Tato kapitola bude velmi krátká, protože programátoři mají v jazyce OCaml k dispozici pouze dva standardní booleovské operátory. Jedná se o logický součin a logický součet:

Operátor Vstupní operandy Výsledek Popis operátoru
&& bool bool logický součin
|| bool bool logický součet

Můžete se stále setkat se starším zápisem těchto operátorů pomocí znaků & a |. Ovšem překladač již bude vypisovat varování a znak | nemusí rozpoznat vůbec.

Poznámka: logická negace je představována funkcí not a není zapisována formou standardního operátoru. Jak však uvidíme dále, nic nám nebude bránit v definici nového operátoru s podobnou či naprosto stejnou sémantikou.

Příklady použití:

false && false ;;
- : bool = false
 
false && true ;;
- : bool = false
 
true && false ;;
- : bool = false
 
true&& true ;;
- : bool = true
 
false || false ;;
- : bool = false
 
false || true ;;
- : bool = true
 
true || false ;;
- : bool = true
 
true || true ;;
- : bool = true

Typy těchto operátorů opět zjistíme snadno:

( && ) ;;
- : bool -> bool -> bool = <fun>
 
( || ) ;;
- : bool -> bool -> bool = <fun>
 
( & ) ;;
Line 1, characters 0-5:
1 | ( & ) ;;
    ^^^^^
Alert deprecated: Stdlib.&
Use (&&) instead.
- : bool -> bool -> bool = <fun>

9. Relační operátory

Zajímavé jsou v programovacím jazyce OCaml relační operátory, protože jsou implementovány takovým způsobem, že oba operandy musí být sice stejného typu, ovšem tímto typem mohou být jak číselné hodnoty, tak i řetězce, seznamy, pole atd.

Operátor Vstupní operandy Výsledek Popis operátoru
< 'a bool test na relaci „menší než“
<= 'a bool test na relaci „menší nebo rovno“
> 'a bool test na relaci „větší než“
>= 'a bool test na relaci „větší nebo rovno“

Podívejme se na porovnání numerických hodnot, které je zcela jednoznačné:

1 < 2 ;;
- : bool = true
 
1 > 2 ;;
- : bool = false

Řetězce se porovnávají lexikograficky:

"abc" < "zzz" ;;
- : bool = true

Nelze se ovšem spoléhat na to, že bude dodržena například česká norma řazení:

a" < "á" ;;
- : bool = true
 
"á" < "b" ;;
- : bool = false

Zajímavé je, že se dají porovnávat i seznamy. Opět se jedná o lexikografické porovnání s tím, že pokud je relace zaručena pro n-tý prvek, porovnání se v tomto místě zastaví. To je patrné na posledních třech příkladech, kdy postačuje porovnat druhý resp. první prvek:

[1;2;3] < [4;5;6] ;;
- : bool = true
 
[1;2;3] < [1;2;3] ;;
- : bool = false
 
[1;2;3] < [1;2;4] ;;
- : bool = true
 
[1;2;3] < [1;3;3] ;;
- : bool = true
 
[1;2;3] < [2;2;3] ;;
- : bool = true
 
[1;2;3;4;5;6] < [9] ;;
- : bool = true

V případě polí je nutné zaručit jejich shodnou délku:

[|1;2;3|] < [|4;5;6|] ;;
- : bool = true
 
[|1;2;3|] < [|1;2;3|] ;;
- : bool = false
 
[|1;2;3|] < [|1;3;3|] ;;
- : bool = true
 
[|1;2;3|] < [|1;3;0|] ;;
- : bool = true
 
[|1;2;3;4;5;6|] < [|9;0;0;0;0;0|] ;;
- : bool = true
Poznámka: popravdě si nejsem jist, jestli je toto chování popsáno ve specifikaci jazyka nebo se jedná o implementační detail, který se může v budoucnosti změnit.

n-tice se porovnávají prvek po prvku (samozřejmě musí být shodné typy těchto prvků) a opět stačí, aby byla relace splněna pro n-tý prvek, aby byl známý i výsledek operace:

("abc", 1) < ("abc", 2);;
- : bool = true
 
("abc", 1) < ("abc", 0) ;;
- : bool = false
 
("abc", 1) < ("zzz", 1) ;;
- : bool = true
 
("zzz", 1) < ("aaa", 1) ;;
- : bool = false

Opět se pro úplnost podívejme na typy všech čtyř výše zmíněných operátorů:

( < ) ;;
- : 'a -> 'a -> bool = <fun>
 
( > ) ;;
- : 'a -> 'a -> bool = <fun>
 
( <= ) ;;
- : 'a -> 'a -> bool = <fun>
 
( >= ) ;;
- : 'a -> 'a -> bool = <fun>

10. Testy na ekvivalenci

Samostatná kapitola je vyhrazena pro popis operátorů, které testují ekvivalenci dvou hodnot. Jedná se totiž o poměrně složité téma, které je v mnoha programovacích jazycích realizováno problematickým způsobem (čtyři různé funkce pro ekvivalenci v LISPu eq, eql, equal, equalp, dvojí funkce operátoru == v Javě, dvojice operátorů == a === v JavaScriptu atd.). Můžeme totiž testovat, zda jsou dvě hodnoty totožné z hlediska jejich struktury nebo zda se jedná o totožné objekty uložené ve stejné oblasti paměti.

Z tohoto důvodu nalezneme v jazyku OCaml dva operátory = a ==, jejichž opakem jsou operátory <> a != (pozor si tedy musí dát céčkaři a Javisti na druhý zmíněný operátor). Operátor = testuje strukturální ekvivalenci, tj. zda mají hodnoty stejný typ (to kontroluje překladač) i obsah, zatímco operátor == testuje, zda se jedná o shodné oblasti paměti popř. u číselných hodnot o shodná čísla (ostatní typy jsou totiž boxovány). A ještě problematičtější situace je u měnitelných objektů, kdy tento operátor vrací true za předpokladu, že jedna operace mutace změní obě předávané hodnoty (což musí být pole nebo reference). V praxi se nejčastěji setkáme s použitím = a nikoli ==:

Operátor Vstupní operandy Výsledek Popis operátoru
= 'a bool strukturální ekvivalence
<> 'a bool opak =
       
== 'a bool fyzická ekvivalence
!= 'a bool opak ==

Ukažme si použití obou operátorů == a = i rozdílné výsledky, které (někdy) dostaneme:

1 == 1 ;;
- : bool = true
 
1 = 1 ;;
- : bool = true
 
[1,2] == [1,2] ;;
- : bool = false
 
[1,2] = [1,2] ;;
- : bool = true
 
[|1,2|] == [|1,2|] ;;
- : bool = false
 
[|1,2|] = [|1,2|] ;;
- : bool = true
 
("foo", 42) == ("foo", 42) ;;
- : bool = false
 
("foo", 42) = ("foo", 42) ;;
- : bool = true
Poznámka: ve skutečnosti se může v závislosti na tom, jak se program překládá, stát, že operátor == bude vracet různé výsledky pro složené typy.

Typy výše zmíněných operátorů:

( = ) ;;
- : 'a -> 'a -> bool = <fun>
 
( == ) ;;
- : 'a -> 'a -> bool = <fun>
 
( <> ) ;;
- : 'a -> 'a -> bool = <fun>
 
( != ) ;;
- : 'a -> 'a -> bool = <fun>

11. Operátory pro spojování řetězců a seznamů

Další operátory, které v jazyce OCaml nalezneme, slouží ke spojování řetězců nebo seznamů. I když pracují s různými typy, popíšeme si je v jedné kapitole:

Operátor Vstupní operandy Výsledek Popis operátoru
@ seznam 'a seznam 'a spojení dvou seznamů s prvky stejných typů
^ řetězec řetězec spojení dvou řetězců
^^ formátovací řetězec formátovací řetězec spojení dvou formátovacích řetězců

Formátovací řetězce budou tématem samostatného článku, ovšem podívejme se na způsoby použití operátorů @ a ^. Je to snadné a přímočaré (připomeňme typ prázdného seznamu):

[] @ [] ;;
- : 'a list = []
 
[] @ [1] ;;
- : int list = [1]
 
[1] @ [2] ;;
- : int list = [1; 2]
 
[1;2] @ [3;4] ;;
- : int list = [1; 2; 3; 4]
 
"" ^ "" ;;
- : string = ""
 
"" ^ "bar" ;;
- : string = "bar"
 
"foo" ^ "" ;;
- : string = "foo"
 
"foo" ^ "bar" ;;
- : string = "foobar"

Typy těchto operátorů:

( @ ) ;;
- : 'a list -> 'a list -> 'a list = <fun>
 
( ^ ) ;;
- : string -> string -> string = <fun>
 
( ^^) ;;
- : ('a, 'b, 'c, 'd, 'e, 'f) format6 ->
    ('f, 'b, 'c, 'e, 'g, 'h) format6 -> ('a, 'b, 'c, 'd, 'g, 'h) format6
= <fun>

12. Operátory pro čtení a zápis hodnoty přes referenci

Připomeňme si, jak se v jazyku OCaml pracuje s referencemi.

Proměnná obsahující referenci je deklarována s využitím modifikátoru ref:

let x = ref 42

Modifikace referencované hodnoty se provádí s využitím operátoru :=, tedy takto:

x := 0

A pro získání hodnoty se používá operátor !, což je ukázáno na dalším řádku:

Printf.printf "x=%d\n" !x

V tomto popisu jsme použili dva operátory:

Operátor Vstupní operandy Výsledek Popis operátoru
:= 'a ref unit () nastavení hodnoty přes referenci
! 'a ref 'a přečtení hodnoty přes referenci

Typy těchto operátorů si zobrazíme snadno:

( := ) ;;
- : 'a ref -> 'a -> unit = <fun>
 
( ! ) ;;
- : 'a ref -> 'a = <fun>

13. Ostatní standardní operátory

Zbývá nám popis pouhých dvou standardních operátorů:

Operátor Vstupní operandy Výsledek Popis operátoru
@@ funkce, hodnota vypočtená hodnota aplikace funkce
|> hodnota, funkce vypočtená hodnota aplikace funkce, ovšem funkce se zapisuje za operátor

Oba výše uvedené operátory jsou vlastně pouze jinak zapsanou formou volání (aplikace) funkce na jednu hodnotu. Oba dále uvedené výrazy vrací 11, tedy totéž, co inc 10;;:

let inc x = x + 1 ;;
val inc : int -> int = <fun>
 
inc @@ 10 ;;
- : int = 11
 
10 |> inc ;;
- : int = 11

Jak je asi patrné, je praktický především operátor |>, který nám umožňuje tvorbu kolony:

let inc x = x + 1;;
let double x = x * 2;;
let negate x = -x;;
 
10 |> inc |> double |> negate;;
 
-22
( @@ ) ;;
- : ('a -> 'b) -> 'a -> 'b = <fun>
 
( |> ) ;;
- : 'a -> ('a -> 'b) -> 'b = <fun>

14. Definice nových operátorů v jazyce OCaml

Důležitým rysem programovacího jazyka OCaml je fakt, že je v něm možné vytvářet další operátory. Pro jména těchto operátorů existují pravidla zmíněná v navazující kapitole. Jedná se o poměrně důležitou vlastnost tohoto jazyka, ovšem (pochopitelně) je nutné dát pozor na to, aby byl výsledný program, který nové operátory používá, čitelný. Z hlediska implementace je vhodné si uvědomit, že operátory nejsou v OCamlu vlastně nic jiného než „zajímavým“ způsobem zapsané funkce s jedním či dvěma parametry – nejedná se tedy o žádnou magii. Zajímavé je, že již v názvu nového operátoru je zakódována i jeho asociativita, což si ostatně ukážeme.

Poznámka: operátory se chovají podobně jako všechny další symboly, což znamená, že je lze definovat jak na globální úrovni, tak i na úrovni jednotlivých modulů či dokonce bloků (třeba jen uvnitř funkcí).

15. Pravidla pro definici nových operátorů

Nové operátory se definují stylem:

let (jméno_operátoru) = funkce_s_implementací ;;

Ovšem jména operátorů musí splňovat určitá pravidla. Tato pravidla taktéž určují aritu, prioritu a asociativitu operátoru:

  • Prvním znakem prefixového (unárního) operátoru může být ?, ~ nebo !.
  • Následovat mohou znaky $, &, *, +, -, /, =, >, @, ^, |, %, < (po znaku ! je následující znak nepovinný).
  • Prvním znakem infixového (binárního) operátoru může být $, &, *, +, -, /, =, >, @, ^, |, %, < nebo #.
  • Následovat mohou znaky $, &, *, +, -, /, =, >, @, ^, |, %, <, !, ., :, ?, ~,

Současně první znak operátoru určuje jeho prioritu a asociativitu:

Znak Priorita Asociativita
# 1 zleva doprava
% * / 2 zleva doprava
+ – 3 zleva doprava
@ ^ 4 zprava doleva
$ & < = > 5 zleva doprava

16. Definice vlastních unárních operátorů

Podívejme se nyní na definici jednoduchého binárního operátoru, který bude implementovat operaci logické negace. Pro tento účel můžeme (ideálně jen lokálně) předefinovat existující operátor !, nebo si vytvořit operátor nový. Nazvěme ho například ~/, protože oba tyto znaky se někdy v matematice či elektronice používají pro zápis negace:

let negate x = not x;;
 
let ( ~/ ) = negate;;
 
~/true;;
~/false;;

Výsledkem obou výrazů s novým operátorem bude skutečně logická negace:

~/true ;;
- : bool = false
 
~/false ;;
- : bool = true

Samozřejmě si můžeme vytvořit i další podobné operátory, například operátory (predikáty) testující, zda je celočíselná hodnota kladná, záporná nebo nulová. Pro tyto účely použijeme symboly ?+, ?- a ?=:

let pos x = x > 0;;
let neg x = x < 0;;
let zero x = x = 0;;
 
let ( ?+ ) = pos;;
let ( ?- ) = neg;;
let ( ?= ) = zero;;
 
?+ 42;;
?- 42;;
?= 42;;

Podívejme se na výsledky všech tří výrazů:

+ 42 ;;
- : bool = true
 
?- 42 ;;
- : bool = false
 
?= 42 ;;
- : bool = false

17. Definice vlastních binárních operátorů

V praxi bude pravděpodobně zajímavější definice operátorů binárních, protože výše popsané unární operátory jsou vlastně jen „divnými znaky“ zapsaná volání funkcí. U binárních operátorů je tomu ovšem jinak, protože tyto operátory se píšou mezi své operandy a nikoli před nimi. Můžeme si například zadefinovat nový operátor +@, který bude spojovat dvojici řetězců (operandů), ovšem výsledek navíc umístí do hranatých závorek a mezi spojené řetězce přidá znak podtržítka (podobný příklad naleznete i v manuálu k jazyku OCaml):

let strjoin s1 s2 = "[" ^ s1 ^ "_" ^ s2 ^ "]";;
 
let ( +@ ) = strjoin;;
 
"foo" +@ "bar";;
 
"foo" +@ "bar" +@ "baz";;

Z prvního výsledku je patrná základní funkce nového operátoru, z výsledku druhého pak jeho asociativita (zleva):

"foo" +@ "bar";;
- : string = "[foo_bar]"
 
"foo" +@ "bar" +@ "baz" ;;
- : string = "[[foo_bar]_baz]"

18. Asociativita a priorita vlastních operátorů

V patnácté kapitole byla vypsána pravidla platná pro nově definované operátory. Mj. jsme se v ní zmínili o asociativitě, tedy o tom, zda bude zápis:

x op y op z

vyhodnocen takto:

(x op y) op z

či naopak takto:

x op (y op z)

Náš první binární operátor byl asociativní zleva, ovšem změnou jeho názvu můžeme vytvořit operátor asociativní zprava (viz opět patnáctou kapitolu):

let strjoin s1 s2 = "[" ^ s1 ^ "_" ^ s2 ^ "]";;
 
let ( @@ ) = strjoin;;
 
"foo" @@ "bar";;
 
"foo" @@ "bar" @@ "baz";;

Z druhého výrazu je patrné odlišné „uzávorkování“:

"foo" @@ "bar" ;;
- : string = "[foo_bar]"
 
"foo" @@ "bar" @@ "baz" ;;
- : string = "[foo_[bar_baz]]"

Podobně je možné volbou jména binárního operátoru určit jeho prioritu, tj. do které z pěti skupin bude operátor spadat. Pro jednoduchost použijeme vlastní operátory začínající znaky + a *, protože jejich vzájemná priorita bude stejná, jako je tomu v matematice. Oba operátory budou provádět stejnou operaci, ovšem vyhodnocení výrazu bude prioritou ovlivněno:

let strjoin s1 s2 = "[" ^ s1 ^ "_" ^ s2 ^ "]";;
 
let ( +@ ) = strjoin;;
let ( *@ ) = strjoin;;
 
"foo" +@ "bar" +@ "baz";;
"foo" *@ "bar" *@ "baz";;
 
"foo" +@ "bar" *@ "baz";;
"foo" *@ "bar" +@ "baz";;

První dva výrazy ukazují, že asociativita obou operátorů je zleva doprava (a nemusíme se jí tedy dále zabývat):

bitcoin školení listopad 24

"foo" +@ "bar" +@ "baz" ;;
- : string = "[[foo_bar]_baz]"
 
"foo" *@ "bar" *@ "baz" ;;
- : string = "[[foo_bar]_baz]"

Ovšem další dva výrazy ukazují, že operátor *@ má vyšší prioritu než operátor +@:

"foo" +@ "bar" *@ "baz" ;;
- : string = "[foo_[bar_baz]]"
 
"foo" *@ "bar" +@ "baz" ;;
- : string = "[[foo_bar]_baz]"
Poznámka: z uvedených příkladů je zřejmé, že se to s novými operátory nesmí příliš přehánět. Ovšem jejich lokální definice či redefinice existujících operátorů mohou být naopak velmi vhodné.

19. 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 article01/hello_world1.ml zavolání funkce print_string https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/hello_world1.ml
2 article01/hello_world2.ml zavolání funkce printf.Printf https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/hello_world2.ml
       
3 article01/function.ml definice funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/function.ml
4 article01/lambda.ml anonymní funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/lambda.ml
       
5 article01/function_type1.ml explicitní specifikace typu návratové hodnoty funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/function_type1.ml
6 article01/function_type2.ml explicitní specifikace typu návratové hodnoty funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/function_type2.ml
       
7 article01/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 article01/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 article01/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 article01/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 article01/call_function5.ml plná deklarace funkce bez syntaktického cukru https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function5.ml
12 article01/call_function6.ml plná deklarace funkce bez syntaktického cukru https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/call_function6.ml
       
13 article01/local_binding1.ml definice lokálních symbolů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/local_binding1.ml
14 article01/local_binding2.ml definice lokálních symbolů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle01/local_binding2.ml
       
15 article02/basic_binding.ml navázání hodnoty na symbol (deklarace proměnné) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/basic_binding.ml
16 article02/print_variable.ml tisk hodnoty proměnné https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/print_variable.ml
17 article02/variables_and_functions.ml předání proměnné do funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/variables_and_functi­ons.ml
18 article02/redefine_symbol1.ml pokus o redefinici symbolu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/redefine_symbol1.ml
19 article02/redefine_symbol2.ml pokus o redefinici symbolu (složitější příklad) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/redefine_symbol2.ml
       
20 article02/requal_operator1.ml operátor = https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/equal_operator1.ml
21 article02/requal_operator2.ml operátor = https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/equal_operator2.ml
       
22 article02/immutable_variable.ml „změna“ neměnitelné proměnné https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/immutable_variable.ml
22 article02/mutable_variable.ml změna měnitelné proměnné https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/mutable_variable.ml
23 article02/shadow.ml shadowing symbolu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/shadow.ml
24 article02/incr.ml standardní funkce incr https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/incr.ml
25 article02/ident.ml nejjednodušší polymorfická funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/ident.ml
       
26 article02/tuple1.ml datový typ n-tice (tuple) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/tuple1.ml
27 article02/tuple2.ml datový typ n-tice (tuple) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/tuple2.ml
28 article02/record1.ml datový typ záznam (record), deklarace proměnné tohoto typu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/record1.ml
29 article02/record2.ml datový typ záznam (record) a typová inference https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/record2.ml
       
30 article02/unit.ml datový typ unit a rozdíl oproti funkcím bez parametrů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/unit.ml
31 article02/polymorphic.ml použití polymorfických funkcí https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/polymorphic.ml
32 article02/two_same_records.ml dva datové typy záznam se shodnými prvky https://github.com/tisnik/ocaml-examples/tree/master/arti­cle02/two_same_records.ml
       
33 article03/recursion1.ml pokus o deklaraci funkce s přímou rekurzí založený na let https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/recursion1.ml
34 article03/recursion2.ml deklarace funkce s přímou rekurzí založená na let rec https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/recursion2.ml
35 article03/recursion3.ml využití tail rekurze pro výpočet členu Fibonacciho posloupnosti https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/recursion3.ml
36 article03/recursion4.ml obyčejná nerekurzivní funkce definovaná přes let rec https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/recursion4.ml
       
37 article03/odd_even1.ml nepřímá rekurze (nekorektní varianta) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/odd_even1.ml
38 article03/odd_even2.ml nepřímá rekurze (taktéž nekorektní varianta) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/odd_even2.ml
39 article03/odd_even3.ml jediný korektní zápis nepřímé rekurze https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/odd_even3.ml
40 article03/odd_even4.ml nepřímá rekurze bez použití klíčového slova rec https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/odd_even4.ml
       
41 article03/pattern1.ml výpočet Faktoriálu založený na pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/pattern1.ml
42 article03/pattern2.ml výpočet Faktoriálu založený na pattern matchingu, sloučení vstupů se stejným výstupem https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/pattern2.ml
43 article03/pattern3.ml kontrola neplatného vstupu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/pattern3.ml
44 article03/pattern4.ml pattern matching pro větší množství hodnot https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/pattern4.ml
45 article03/pattern5.ml rekurzivní implementace Ackermannovy funkce https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/pattern5.ml
46 article03/pattern6.ml kontrola neplatných vstupních hodnot pro Ackermannovu funkci https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/pattern6.ml
       
47 article03/fibonacci1.ml výpočet Fibonacciho posloupnosti založený na pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/fibonacci1.ml
48 article03/fibonacci2.ml výpočet Fibonacciho posloupnosti založený na pattern matchingu (více idiomatický zápis) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/fibonacci2.ml
       
49 article03/first.ml funkce vracející první prvek z dvojice založená na pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/first.ml
50 article03/second.ml funkce vracející druhý prvek z dvojice založená na pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/second.ml
51 article03/zero_coordinate.ml test na nulovou souřadnici/souřadnice založený na pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/zero_coordinate.ml
       
52 article03/get_model.ml získání prvku ze záznamu (opět založeno na pattern matchingu) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/get_model.ml
       
53 article03/list_literal1.ml seznam se třemi prvky typu celé číslo https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/list_literal1.ml
54 article03/list_literal2.ml seznam se třemi prvky typu řetězec https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/list_literal2.ml
55 article03/list_literal3.ml seznam se třemi prvky typu n-tice https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/list_literal3.ml
56 article03/list_literal4.ml nekorektní pokus o vytvoření seznamu s prvky různých typů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/list_literal4.ml
57 article03/empty_list.ml konstrukce prázdného seznamu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/empty_list.ml
       
58 article03/head_tail1.ml složení seznamu se dvěma prvky s využitím operátoru :: https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/head_tail1.ml
59 article03/head_tail2.ml složení seznamu se třemi prvky s využitím operátoru :: https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/head_tail2.ml
       
60 article03/list_properties.ml vlastnosti (properties) seznamů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/list_properties.ml
61 article03/len1.ml naivní rekurzivní výpočet délky seznamu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/len1.ml
62 article03/len2.ml vylepšený rekurzivní výpočet délky seznamu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/len2.ml
63 article03/len3.ml vylepšený rekurzivní výpočet délky seznamu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/len3.ml
       
64 article03/join_lists.ml spojení dvou seznamů operátorem :: https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/join_lists.ml
65 article03/append1.ml implementace spojení dvou seznamů rekurzivním výpočtem https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/append1.ml
66 article03/append2.ml implementace spojení dvou seznamů rekurzivním výpočtem, použití pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/append2.ml
       
67 article03/sum1.ml součet hodnot všech prvků v seznamu (bez tail rekurze) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/sum1.ml
68 article03/sum2.ml součet hodnot všech prvků v seznamu (s využitím tail rekurze) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/sum2.ml
       
69 article03/print_int_list.ml tisk seznamu celých čísel https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/print_int_list.ml
70 article03/print_string_list.ml tisk seznamu řetězců https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/print_string_list.ml
71 article03/print_list_prefix.ml tisk seznamu s prefixem https://github.com/tisnik/ocaml-examples/tree/master/arti­cle03/print_list_prefix.ml
       
72 article04/none_value.ml hodnota None https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/none_value.ml
73 article04/some_value1.ml hodnota Some(typ) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/some_value1.ml
74 article04/some_value2.ml hodnota Some(typ) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/some_value2.ml
75 article04/some_value3.ml hodnota Some(typ) https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/some_value3.ml
76 article04/option_exists1.ml základní pattern matching, korektní varianta https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_exists1.ml
77 article04/option_exists2.ml základní pattern matching, nekorektní varianta https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_exists2.ml
78 article04/option_exists3.ml základní pattern matching, nekorektní varianta https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_exists3.ml
79 article04/find_in_list1.ml vyhledávání prvku v seznamu založené na pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/find_in_list1.ml
80 article04/find_in_list2.ml varianta předchozího programu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/find_in_list2.ml
81 article04/option_get.ml pokus o přečtení hodnoty obalené typem Option https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_get.ml
82 article04/is_none_is_some.ml predikáty is_none a is_some https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/is_none_is_some.ml
83 article04/option_equal.ml ekvivalence dvou obalených hodnot https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_equal.ml
84 article04/some_none.ml obalení obalené hodnoty https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/some_none.ml
       
85 article04/result_divide1.ml ukázka použití datového typu Result https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/result_divide1.ml
86 article04/result_divide2.ml ukázka použití datového typu Result a pattern matchingu https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/result_divide2.ml
87 article04/result_divide3.ml stejné jako result_divide1.fs, ovšem bez explicitního zápisu typů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/result_divide3.ml
88 article04/result_divide4.ml stejné jako result_divide2.fs, ovšem bez explicitního zápisu typů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/result_divide4.ml
       
89 article04/array_value.ml deklarace pole výčtem jeho prvků https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_value.ml
90 article04/array_make.ml funkce Array.make pro konstrukci pole https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_make.ml
91 article04/array_init1.ml inicializace prvků pole funkcí Array.init https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_init1.ml
92 article04/array_init2.ml inicializace prvků pole funkcí Array.init https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_init2.ml
93 article04/array_init3.ml inicializace prvků pole funkcí Array.init https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_init3.ml
94 article04/array_indexing.ml indexování prvků pole https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_indexing.ml
95 article04/array_mutation.ml mutace pole: modifikace hodnot jeho prvků https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/array_mutation.ml
       
96 article04/option_no_bind.ml zřetězení volání funkcí, které si předávají hodnoty typu Option – neidiomatické řešení https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_no_bind.ml
97 article04/option_bind.ml řešení založené na bind https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/option_bind.ml
98 article04/bind_infix_operator.ml funkce Option.bind zapsaná formou infixového operátoru https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/bind_infix_operator­.ml
99 article04/bind_infix_operator2.ml zřetězení funkcí s využitím Result.bind https://github.com/tisnik/ocaml-examples/tree/master/arti­cle04/bind_infix_operator.ml
       
100 article05/unary_arithmetic.ml unární aritmetické operátory https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/unary_arithmetic.ml
101 article05/binary_arithmetic.ml binární aritmetické operátory https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/binary_arithmetic.ml
102 article05/boolean_operators.ml booleovské operátory https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/boolean_operators.ml
103 article05/relational.ml základní čtveřice relačních operátorů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/relational.ml
104 article05/equality.ml operátory zjišťující ekvivalenci hodnot https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/equality.ml
105 article05/joins.ml operátory pro spojení řetězců a seznamů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/joins.ml
106 article05/references.ml operátory pro práci s referencemi https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/references.ml
107 article05/function_operators.ml operátory pro aplikaci funkcí https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/function_operators.ml
108 article05/conwoy.ml konvoj vytvořený operátorem |> https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/conwoy.ml
       
109 article05/usage_unary_arithmetic.ml test unárních operátorů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_unary_arithme­tic.ml
110 article05/usage_binary_arithmetic.ml test binárních operátorů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_binary_arithme­tic.ml
111 article05/usage_boolean.ml test booleovských operátorů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_boolean.ml
112 article05/usage_relational.ml test relačních operátorů vůči různým hodnotám https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_relational.ml
113 article05/usage_relational_tuples.ml test relačních operátorů vůči n-ticím https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_relational_tu­ples.ml
114 article05/usage_equality.ml testy na strukturální a fyzickou rovnost https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_equality.ml
115 article05/usage_joins.ml testy operátorů pro spojení řetězců a seznamů https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_joins.ml
116 article05/usage_function.ml testy operátorů pro aplikaci funkcí https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/usage_function.ml
       
117 article05/operator_unary1.ml vlastní unární operátor https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/operator_unary1.ml
118 article05/operator_unary2.ml vlastní unární operátory https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/operator_unary2.ml
119 article05/operator_binary1.ml vlastní binární operátor s asociativitou zleva https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/operator_binary1.ml
120 article05/operator_binary2.ml vlastní binární operátor s asociativitou zprava https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/operator_binary2.ml
121 article05/operator_binary3.ml vlastní binární operátory s rozdílnou prioritou https://github.com/tisnik/ocaml-examples/tree/master/arti­cle05/operator_binary3.ml

20. 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
  54. Introduction | OCaml Programming | Chapter 1 Video 1
    https://www.youtube.com/wat­ch?v=MUcka_SvhLw&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU
  55. Functional Programming – What | OCaml Programming | Chapter 1 Video 2
    https://www.youtube.com/wat­ch?v=JTEwC3HihFc&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=2
  56. Functional Programming – Why Part 1 | OCaml Programming | Chapter 1 Video 3
    https://www.youtube.com/wat­ch?v=SKr3ItChPSI&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=3
  57. Functional Programming – Why Part 2 | OCaml Programming | Chapter 1 Video 4
    https://www.youtube.com/wat­ch?v=eNLm5Xbgmd0&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=4
  58. OCaml | OCaml Programming | Chapter 1 Video 5
    https://www.youtube.com/watch?v=T-DIW1dhYzo&list=PLre5AT9JnKShBOPeuiD9b-I4XROIJhkIU&index=5
  59. Five Aspects of Learning a Programming Language | OCaml Programming | Chapter 2 Video 1
    https://www.youtube.com/wat­ch?v=A5IHFZtRfBs&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=6
  60. Expressions | OCaml Programming | Chapter 2 Video 2
    https://www.youtube.com/watch?v=3fzrFY-2ZQ8&list=PLre5AT9JnKShBOPeuiD9b-I4XROIJhkIU&index=7
  61. If Expressions | OCaml Programming | Chapter 2 Video 3
    https://www.youtube.com/wat­ch?v=XJ6QPtlPD7s&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=8
  62. Let Definitions | OCaml Programming | Chapter 2 Video 4
    https://www.youtube.com/wat­ch?v=eRnG4gwOTlI&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=10
  63. Let Expressions | OCaml Programming | Chapter 2 Video 5
    https://www.youtube.com/wat­ch?v=ug3L97FXC6A&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=10
  64. Variable Expressions and Scope | OCaml Programming | Chapter 2 Video 6
    https://www.youtube.com/wat­ch?v=_TpTC6eo34M&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=11
  65. Scope and the Toplevel | OCaml Programming | Chapter 2 Video 7
    https://www.youtube.com/wat­ch?v=4SqMkUwakEA&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=12
  66. Anonymous Functions | OCaml Programming | Chapter 2 Video 8
    https://www.youtube.com/wat­ch?v=JwoIIrj0bcM&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=13
  67. Lambdas | OCaml Programming | Chapter 2 Video 9
    https://www.youtube.com/wat­ch?v=zHHCD7MOjmw&list=PLre5AT9JnKShBO­PeuiD9b-I4XROIJhkIU&index=15
  68. Operators
    https://ocaml.org/docs/operators
  69. Operator overloading
    https://en.wikipedia.org/wi­ki/Operator_overloading

Autor článku

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