Programovací jazyk F#: proměnné, funkce a datové typy

14. 9. 2023
Doba čtení: 26 minut

Sdílet

 Autor: Depositphotos
V úvodním článku o programovacím jazyku F# jsme si řekli, že základními stavebními kameny tohoto jazyka jsou neměnitelné hodnoty, funkce a datové typy. Dnes se na tyto koncepty podíváme podrobněji.

Obsah

1. Tisk hodnot na terminál mimo smyčku REPL

2. Přiřazení hodnot k symbolům

3. Rozdílné chování interpretru fsi

4. Neměnitelné hodnoty v jazyku F#

5. Syntaxe pro modifikaci proměnné

6. Měnitelné hodnoty aneb vstup do prvního stupně programátorského pekla

7. Reference

8. Použití referencí – jednoduchý čítač

9. Alternativní syntaxe zápisu operací s referencemi

10. Malá odbočka – standardní funkce incr

11. Základní datové typy v jazyku F#

12. Typ unit

13. Typová inference a konstanty

14. Polymorfické funkce

15. n-tice

16. Záznamy

17. Typová inference u záznamů

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

19. Literatura

20. Odkazy na Internetu

1. Tisk hodnot na terminál mimo smyčku REPL

V programovacím jazyku F# můžeme využít interaktivní smyčku REPL pro postupné vyhodnocování jednotlivých výrazů. Výsledky těchto výrazů, což je vždy jak hodnota, tak i typ, jsou ihned vypisovány na terminál. Ovšem v reálných aplikacích nebo při spouštění skriptů přes dotnet fsi se výsledky jednotlivých výrazů pochopitelně nevypisují. Jak je tedy možné i v aplikacích, popř. ve skriptech vypsat nějakou hodnotu na obrazovku, resp. na terminál? K tomuto účelu můžeme použít standardní funkci nazvanou printf, která se, jak ostatně uvidíme dále, používá podobně jako stejně pojmenovaná funkce v céčku či dalších jazycích.

Prvním parametrem této funkce je formátovací řetězec, který může, ale také nemusí obsahovat specifikaci formátování, řídicí znaky atd. Samozřejmě v případě, že tento řetězec žádné speciální znaky neobsahuje, vypsat zprávu na terminál přímo následujícím způsobem:

printf "www.root.cz"

To ve skutečnosti není ideální řešení; lepší je řetězec předat jako další parametr:

printf "%s" "www.root.cz"

Překladač i interpret provádí kontrolu formátovacího řetězce a typu dalších parametrů:

printf "%d" "Hello world"

Tento program je označen jako chybný:

The type 'string' is not compatible with any of the types
byte,int16,int32,int64,sbyte,uint16,uint32,uint64,nativeint,unativeint, arising
from the use of a printf-style format string

Prvním parametrem funkce printf musí být formátovací řetězec, což je opět kontrolováno:

printf 42

I tento program je označen jako chybný:

The type 'int' is not compatible with the type 'Printf.TextWriterFormat<'a>'

Naopak tento program je plně funkční:

printf "answer is %d" 42

2. Přiřazení hodnot k symbolům

V programovacím jazyku F# se setkáme s konceptem, který se do jisté míry podobá konceptu proměnných v dalších programovacích jazycích. S využitím klíčového slova let je možné vytvořit takzvanou vazbu (neboli binding) mezi novým symbolem (jménem) a nějakou hodnotou, která je obecně výsledkem nějakého výrazu (i konstanta je výrazem). V tom nejjednodušším případě může definice takové vazby vypadat následovně:

let x = 42

S nově vzniklým symbolem můžeme provádět výpočty nebo s ním manipulovat tak, jako přímo s hodnotou:

let x = 42
printf "x=%d" x

Možné je pochopitelně i provedení jednoduchého výpočtu s dosazením výsledku do nového symbolu:

let x = 42
printf "x=%d" x
 
let y = x + 1
printf "y=%d" y

Jednou definovaný symbol ovšem nelze v daném bloku (viz dále) redefinovat, takže následující řádky nejsou korektní a překladač nás na tento problém upozorní:

let x = 42
printf "x=%d" x
 
let x = 6502
printf "x=%d" x

Chyba je v tomto případě detekována na čtvrtém řádku:

Duplicate definition of value 'x'

To ovšem znamená, že ani následující zápis není korektní:

let x = 42
printf "x=%d" x
 
let y = x + 1
printf "y=%d" y
 
let x = y + 1
printf "x=%d" x

Chybová zpráva je v tomto případě detekována na sedmém řádku:

Duplicate definition of value 'x'
Poznámka: z výše uvedeného plyne, že let slouží k definici symbolu, nikoli však k přiřazení nové hodnoty k symbolu.

3. Rozdílné chování interpretru fsi

V případě, že předchozí programové řádky (a v tomto případě klidně i bez řádků s printf) přepíšete do interaktivního REPLu jazyka F# (dotnet fsi, lze ho však spustit i na repl.it, jak již víme z úvodního článku), bude chování kupodivu velmi odlišné, protože se bude zdát, že s pomocí let skutečně můžeme proměnné redefinovat a tím pádem jim přiřazovat nové hodnoty:

> let x = 42;;
val x: int = 42
 
> let y = x + 1;;
val y: int = 43
 
> let x = x + 1;;
val x: int = 43

Ve skutečnosti se zde ovšem jedná o odlišný koncept – takzvaný shadowing. Nově definovaný symbol (v tomto případě symbol x) „zastíní“ předchozí symbol. Ten sice stále existuje, ale je v daném kontextu nedostupný.

Sice poněkud předbíháme, ale shadowing se projeví například i uvnitř funkce:

let shadow =
   let a = 1
   let a = 2
   a
 
printf "%d" shadow

Tento program vypíše hodnotu 2.

Poznámka: v OCamlu, jak ostatně uvidíme v dalším článku, k tomuto problému nedochází, neboť tento jazyk vyžaduje použití klíčového slova in, které celý koncept osvětluje.

4. Neměnitelné hodnoty v jazyku F#

Až do této chvíle by se mohlo zdát, že se v případě příkazu let vlastně jedná o klasickou deklaraci proměnné, což je i důvod, proč se i v programovacím jazyku F# mluví o proměnných. Co ovšem může být zpočátku matoucí, je fakt, že takto definované proměnné nejsou ve skutečnosti měnitelné (mutable), takže samotný termín „proměnná“ (variable) může vést k nesprávným závěrům. Ostatně pokusme se pro zajímavost změnit hodnotu proměnné x. První úkol bude zjistit, jak se vlastně tato operace (modifikace hodnoty proměnné) provádí. První pokus může vypadat takto:

let x = 42
printf "x=%d" x
 
x = x + 1
printf "x=%d" x

Tento příklad je po syntaktické stránce (do určité míry!) korektní, ovšem jak je tomu z pohledu sémantiky? Po spuštění tohoto prográmku se vypíše:

x=42
x=42

Navíc překladač u tohoto příkladu vypíše varování:

The result of this equality expression has type 'bool' and is implicitly
discarded. Consider using 'let' to bind the result to a name, e.g. 'let result
= expression'. If you intended to mutate a value, then mark the value 'mutable'
and use the '<-' operator e.g. 'x <- expression'.

Důvod pro toto varování je jednoduchý – zápis x = x + 1 totiž ve skutečnosti neznamená přiřazení nové hodnoty do proměnné x, ale jedná se o porovnání, zda x je rovno x+1 (což evidentně nemůže nastat) a výsledná hodnota typu bool (zde konkrétně false) je zahozena. Ostatně funkci operátoru = si lze velmi snadno ověřit na tomto demonstračním příkladu (operátor = je zvýrazněn i se svými operandy):

let x = 42
printf "x=%d" x
 
printf "x=x+1? %b" (x=x+1)
printf "x=42?  %b" (x=42)

Výsledky budou vypadat následovně:

x=42
x=x+1? false
x=42?  true

5. Syntaxe pro modifikaci proměnné

Pro modifikaci proměnné je v programovacím jazyku F# zvolen poměrně dobře čitelný zápis (který ale pravděpodobně bude mást programátory v Go, kde znamená něco zcela odlišného):

existující_proměnná <- nová hodnota

V předchozím textu jsme si řekli, že proměnné jsou ve výchozím stavu neměnitelné, takže si vyzkoušejme, zda je tomu skutečně tak. V následujícím programu nejdříve deklarujeme a inicializujeme novou proměnnou x, poté se ji pokusíme modifikovat:

let x = 42
printf "x=%d" x
 
x <- x + 1
printf "x=%d" x

Překladač nás v tomto případě správně upozorní na to, že se snažíme měnit neměnitelnou proměnnou. A dokonce nám ihned nabídne řešení, ke kterému se vrátíme v navazující kapitole:

This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable x = expression'.

6. Měnitelné hodnoty aneb vstup do prvního stupně programátorského pekla

U předchozího demonstračního příkladu nám překladač nabídl jedno z možných řešení použitelných ve chvíli, kdy skutečně potřebujeme pracovat s modifikovatelnými proměnnými. Proměnnou musíme jako měnitelnou označit při její deklaraci klíčovým slovem mutable. Po takové úpravě již bude možné hodnotu proměnné měnit tak, jak to známe z klasických imperativních programovacích jazyků (zde konkrétně s využitím ← ):

let mutable x = 42
printf "x=%d" x
 
x <- x + 1
printf "x=%d" x

Výsledky získané po spuštění tohoto demonstračního příkladu ukazují, že proměnná je skutečně měnitelná (a jedná se tedy o proměnnou v původním slova smyslu tohoto termínu):

x=42
x=43
Poznámka: zápis s mutable je zdlouhavý a je to tak vlastně dobře, protože použití měnitelných proměnných by mělo být spíše výjimečnou záležitostí (alespoň tak by tomu mělo být v „ideálním“ FP světě). Podobným směrem ostatně šel i jazyk Rust, kde se používá kratší modifikátor mut, takže vývojář není za použití měnitelné proměnné tak „trestán“ jako v jazyku F#.

7. Reference

Kromě explicitně měnitelných proměnných můžeme v jazyku F# používat i takzvané reference, což je koncept převzatý z jazyka OCaml (a dále upravený). Referenci si můžeme představit jako proměnnou obsahující adresu hodnoty uložené v operační paměti. Ovšem na rozdíl od céčka s jeho konceptem ukazatelů jsou ve skutečnosti reference v programovacím jazyku F# plně typované.

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 nikoli šipky, jako je tomu u měnitelné proměnné):

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
Poznámka: tyto zápisy jsou převzaty z OCamlu. V jazyku F# je navíc nabízen i alternativní zápis (který vypadá více „objektově“). Ten si ukážeme v dalším textu.

8. Použití referencí – jednoduchý čítač

Podívejme se nyní na jednoduchý „školní“ příklad, v němž je využita reference pro realizaci jednoduchého čítače. Bude se tedy jednat o proměnnou, jejíž hodnotu lze zvýšit o jedničku, popř. danou hodnotu přečíst. Víme již, že proměnnou s referencí musíme deklarovat s využitím modifikátoru ref, změnu reference zařizuje operátor := a přečtení referencované hodnoty operátor !. Zbytek je již jednoduchý:

let x = ref 42
Printf.printf "x=%d\n" !x
 
x := !x + 1
Printf.printf "x=%d\n" !x

Tento prográmek po svém spuštění vypíše:

x=42
x=43
Poznámka: reference ovšem mají i mnohem užitečnější způsoby využití, což je opět téma, kterému se ještě budeme věnovat.

9. Alternativní syntaxe zápisu operací s referencemi

Přístup k referencované hodnotě přes operátor ! a modifikace reference operátorem := je ve skutečnosti syntaxe, která byla převzata z jazyka OCaml. V F# je nabízena ještě jedna alternativní syntaxe, která s referencí pracuje tak, jakoby se jednalo o datovou strukturu s jediným měnitelným prvkem nazvaným Value. To tedy znamená, že namísto zápisu:

!reference

můžeme psát:

reference.Value

Navíc operace přiřazení nové hodnoty se namísto:

reference := výraz

může zapsat stylem:

reference.Value <- výraz

Náš příklad s čítačem je tedy možné přepsat do této podoby:

let x = ref 42
Printf.printf "x=%d\n" x.Value
 
x.Value <- x.Value + 1
Printf.printf "x=%d\n" x.Value

10. Malá odbočka – standardní funkce incr

V jazyku OCaml existuje standardní funkce nazvaná incr, která dokáže zvýšit referencovanou celočíselnou hodnotu o jedničku (a současně nevrací žádnou hodnotu, k čemuž se záhy dostaneme). Typ této funkce tedy je:

val incr : int ref -> unit

Programovací jazyk F# tuto funkci převzal do své standardní knihovny, takže ji můžeme použít i zde. Oba příklady z předchozích dvou kapitol je tedy možné přepsat následujícím způsobem:

let x = ref 42
printf "x=%d\n" x.Value
 
incr x
printf "x=%d\n" x.Value

Výsledkem bude podle očekávání:

x=42
x=43
Poznámka: povšimněte si, jak je tento kód nefunkcionální, a to dokonce na několika místech. Používáme zde měnitelné hodnoty (dostupné přes reference) a funkci s vedlejším efektem.

11. Základní datové typy v jazyku F#

V navazujících kapitolách se seznámíme s některými koncepty, na nichž je postaven typový systém programovacího jazyka F#. Nejprve si však pro úplnost vyjmenujme základní datové typy, které tento programovací jazyk nabízí. Vzhledem k tomu, že F# je primárně provozován v ekosystému .NET, je u každého typu ještě uveden odpovídající typ v .NET:

Typ v .NET stručný popis
bool Boolean pravdivostní hodnoty true a false
     
byte Byte celočíselné hodnoty v rozsahu 0 to 255
sbyte SByte celočíselné hodnoty v rozsahu –128 to 127
int16 Int16 celočíselné hodnoty v rozsahu –32768 to 32767
uint16 UInt16 celočíselné hodnoty v rozsahu 0 to 65535
int Int32 celočíselné hodnoty v rozsahu –2 147 483 648 to 2 147 483 647
uint UInt32 celočíselné hodnoty v rozsahu 0 to 4 294 967 295
int64 Int64 celočíselné hodnoty v rozsahu –9 223 372 036 854 775 808 to 9 223 372 036 854 775 807
uint64 UInt64 celočíselné hodnoty v rozsahu 0 to 18 446 744 073 709 551 615
     
nativeint IntPtr ukazatel na celočíselnou hodnotu se znaménkem
unativeint UIntPtr ukazatel na celočíselnou hodnotu bez znaménka
     
decimal Decimal hodnota s plovoucí řádovou čárkou
float, double Double hodnota s plovoucí řádovou čárkou dle IEEE 754 double precision
float32, single Single hodnota s plovoucí řádovou čárkou dle IEEE 754 single precision
     
char Char znak v Unicode
string String řetězec Unicode znaků
Poznámka: povšimněte si, že zejména u typu float může lehce dojít ke zmatkům.

12. Typ unit

Ve skutečnosti se ještě setkáme (a vlastně už i setkali v případě funkce incr s dalším datovým typem, který se nazývá unit (viz též toto heslo). Tento datový typ má jedinou (formální) hodnotu zapisovanou s využitím prázdných kulatých závorek, tedy takto: (). V jazyku F# se tato hodnota používá v těch místech, kde je formálně nutné zapsat nějaký typ či hodnotu, ale žádný takový typ ani hodnota nedává smysl. Příkladem je opět funkce incr, která provádí nějakou činnost (zvyšuje hodnotu referencované proměnné), ovšem nic nevrací. A právě návratovým typem takové funkce je (). Tento typ se ovšem odlišuje od void z céčka, k čemuž se ještě vrátíme (ve stručnosti – void není plnohodnotným typem).

Poznámka: tím, že má typ unit jedinou hodnotu vlastně říkáme, že tato hodnota nenese žádnou informaci (když je pravděpodobnost, že z komunikačního kanálu získám ve 100% stejný symbol, jeho informační hodnota je 0 bitů).

13. Typová inference a konstanty

Vzhledem k tomu, jakým způsobem je realizována typová inference v jazyku F#, je v naprosté většině případů možné vynechat specifikaci datových typů. Ovšem jakým způsobem se například rozliší mezi hodnotou typu byte a hodnotou typu int, když se například bude jednat o nulovou hodnotu? Řešení, které F# nabízí, spočívá v použití suffixů u zapisovaných konstant:

Typ Suffix (příklad)
byte 1uy
sbyte 1y
int16 1s
uint16 1us
int 1
uint 1u
int64 1L
uint64 1UL
   
decimal 1.0m
float, double 1.0
float32, single 1.0f
   
char ‚*‘
string „www.root.cz“

14. Polymorfické funkce

Podívejme se nyní na zajímavý problém. Nadeklarujeme funkci (pro jednoduchost pojmenovanou ident), která akceptuje nějaký parametr pojmenovaný x a hodnotu tohoto parametru vrátí jako svůj výsledek. U této funkce ovšem nikde nespecifikujeme ani typ parametru ani typ návratové hodnoty:

let ident x = x;;

Nyní si asi položíte otázku, zda je vůbec možné takovou funkci v silně typovaném jazyku, jakým F# bezesporu je, nadeklarovat. Překladač totiž nyní nemá k dispozici žádné nápovědy k určení typu parametru či typu návratové hodnoty (tak jako to měl v případě funkce s nějakým „typově jednoznačným“ výrazem).

Tato deklarace funkce ve skutečnosti je v Hindleyho-Milnerově typovém systému řešitelná (řešení přidal právě Milner). Výsledkem bude funkce akceptující i vracející obecný (dále nespecifikovaný) typ a:

val ident : 'a -> 'a = <fun>

Funkci nyní můžeme zavolat s parametry různých typů a výsledkem opět budou hodnoty různých typů (viz znaky ve formátovacím řetězci):

Printf.printf "ident=%d\n" (ident 10);;
Printf.printf "ident=%s\n" (ident "foo");;
Poznámka: zajímavé bude zjistit, jak tento polymorfický typ „probublává“ přes větší množství funkcí. K tomuto konceptu se pochopitelně ještě dostaneme.

15. n-tice

V programovacím jazyku F# jsou podporovány tři základní složené datové typy. Jedná se o n-tice, záznamy a seznamy. Nejjednodušší jsou n-tice, které mohou obsahovat prvky libovolných typů. Typ n-tice jako celku je pak odvozen od typů jednotlivých prvků. Speciálním případem je n-tice bez prvků, neboli datový typ unit zmíněný výše.

Použití n-tice se dvěma prvky typu int:

Printf.printf "%A" (1,2)

Typ této n-tice se zapisuje takto:

int * int = (1, 2)

Typ složitější n-tice:

(1, 1.5, "foo", (1,2)) ;;
 
- : int * float * string * (int * int) = (1, 1.5, "foo", (1, 2))

N-tici je samozřejmě možné přiřadit do proměnné a poté si nechat vytisknout její obsah:

let x = (1,2,3)
Printf.printf "%A" x
Poznámka: vzhledem k tomu, že n-tice s jediným prvkem nemá praktický význam, není podporována (na rozdíl od Pythonu, kde se však jedná o syntakticky problematický rys jazyka).

16. Záznamy

Následují záznamy (records), v nichž jsou uloženy prvky taktéž libovolného typu, ovšem na rozdíl od n-tic jsou tyto prvky pojmenovány. Zde je již nutné definovat nový datový typ s explicitním určením typů jednotlivých položek (další možnosti si popíšeme jindy). Datový typ car může být definován takto:

type car = {
    Color: string;
    Model: string;
    Manufacturer: string;
    Year: int;
}

Vytvoření proměnné s hodnotou tohoto typu se zapisuje následujícím stylem:

bitcoin_skoleni

let toyota :car = {Color="silver"; Model="Corolla"; Manufacturer="Toyota"; Year=1986};;
 
Printf.printf "%A" toyota
Poznámka: pro novou proměnnou toyota platí všechny vlastnosti proměnných zmíněné výše, tj. neměnitelnost atd.

17. Typová inference u záznamů

I u proměnných či parametrů typu záznam se uplatňuje typová inference, což konkrétně znamená, že například v následujícím příkladu nemusíme u proměnné toyota explicitně deklarovat její typ:

type car = {
    Color: string;
    Model: string;
    Manufacturer: string;
    Year: int;
}
 
let toyota = {Color="silver"; Model="Corolla"; Manufacturer="Toyota"; Year=1986};;
 
Printf.printf "%A" toyota

18. 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/f-sharp-examples/. V tabulce umístěné pod tímto odstavcem jsou uvedeny odkazy na tyto příklady:

# Příklad Popis příkladu Cesta
1 ML/fib_recursive.ml výpočet hodnoty z Fibonacciho posloupnosti rekurzivně https://github.com/tisnik/f-sharp-examples/tree/master/ML/fib_re­cursive.ml
2 ML/fib_pattern_matching.ml výpočet hodnoty z Fibonacciho posloupnosti založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/ML/fib_pat­tern_matching.ml
3 ML/len_pattern_matching1.ml výpočet délky seznamu založený na pattern matchingu (první varianta) https://github.com/tisnik/f-sharp-examples/tree/master/ML/len_pat­tern_matching1.ml
4 ML/len_pattern_matching2.ml výpočet délky seznamu založený na pattern matchingu (zkrácená varianta) https://github.com/tisnik/f-sharp-examples/tree/master/ML/len_pat­tern_matching2.ml
       
5 OCaml/fib_recursive.ml výpočet hodnoty z Fibonacciho posloupnosti rekurzivně https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/fib_recursive.ml
6 OCaml/fib_tail_recursive.ml výpočet hodnoty z Fibonacciho posloupnosti s využitím koncové rekurze https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/fib_tail_recursive.ml
7 OCaml/fib_pattern_matching.ml výpočet hodnoty z Fibonacciho posloupnosti založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/fib_pattern_matching.ml
8 OCaml/local_binding.ml symbol lokální uvnitř funkce https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/local_binding.ml
       
9 article01/function.fs deklarace pojmenované funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/function.fs
10 article01/lambda.fs deklarace anonymní funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/lambda.fs
11 article01/local_binding1.fs lokální symboly ve funkci https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/local_binding1.fs
12 article01/local_binding2.fs lokální symboly ve funkci https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/local_binding2.fs
13 article01/function_type1.fs explicitní definice návratového typu funkce (korektní) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/function_type1.fs
14 article01/function_type2.fs explicitní definice návratového typu funkce (nekorektní) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/function_type2.fs
       
15 article02/basic_binding.fs navázání hodnoty na symbol (deklarace proměnné) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/basic_binding.fs
16 article02/print_variable.fs tisk hodnoty proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/print_variable.fs
17 article02/variables_and_functions.fs předání proměnné do funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/variables_and_functi­ons.fs
18 article02/redefine_symbol1.fs pokus o redefinici symbolu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol1.fs
19 article02/redefine_symbol2.fs pokus o redefinici symbolu (složitější příklad) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol2.fs
       
20 article02/equal_operator1.fs operátor = https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator1.fs
21 article02/equal_operator2.fs operátor = https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator2.fs
       
22 article02/immutable_variable.fs „změna“ neměnitelné proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/immutable_variable.fs
23 article02/mutable_variable.fs změna měnitelné proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/mutable_variable.fs
24 article02/reference1.fs reference, příklad kompatibilní s OCamlem https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference1.fs
25 article02/reference2.fs reference, nová syntaxe pro F# https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference2.fs
26 article02/incr1.fs standardní funkce incr https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr1.fs
27 article02/incr2.fs zvýšení referencované hodnoty o jedničku https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr2.fs
28 article02/shadow.fs shadowing symbolu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/shadow.fs
       
29 article02/tuple.fs datový typ n-tice (tuple) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/tuple.fs
30 article02/record1.fs datový typ záznam (record), deklarace proměnné tohoto typu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/record1.fs
31 article02/record2.fs datový typ záznam (record) a typová inference https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/record2.fs
       
32 article02/basic_binding.fsx demonstrační příklad basic_binding.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/basic_binding.fsx
33 article02/equal_operator1.fsx demonstrační příklad equal_operator1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator1.fsx
34 article02/equal_operator2.fsx demonstrační příklad equal_operator2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator2.fsx
35 article02/immutable_variable.fsx demonstrační příklad immutable_variable.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/immutable_variable.fsx
36 article02/mutable_variable.fsx demonstrační příklad mutable_variable.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/mutable_variable.fsx
37 article02/print_variable.fsx demonstrační příklad print_variable.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/print_variable.fsx
38 article02/redefine_symbol1.fsx demonstrační příklad redefine_symbol1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol1.fsx
39 article02/redefine_symbol2.fsx demonstrační příklad redefine_symbol2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol2.fsx
40 article02/variables_and_functions.fsx demonstrační příklad variables_and_functions.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/variables_and_functi­ons.fsx
41 article02/incr1.fsx demonstrační příklad incr1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr1.fsx
42 article02/incr2.fsx demonstrační příklad incr2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr2.fsx
43 article02/reference1.fsx demonstrační příklad reference1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference1.fsx
44 article02/reference2.fsx demonstrační příklad reference2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference2.fsx
45 article02/ident.fsx demonstrační příklad ident.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/ident.fsx

19. Literatura

Poznámka: v této kapitole jsou uvedeny knihy o jazyku ML, resp. Standard ML i knihy o programovacím jazyku OCaml, který ze Standard ML ze značné míry vychází. A samozřejmě nezapomeneme ani na knihy o jazyku F#:
  1. Get Programming with F#
    https://www.manning.com/books/get-programming-with-f-sharp
  2. F# for Scientists
    https://www.amazon.com/F-Scientists-Jon-Harrop-ebook/dp/B005PS97RO
  3. Domain Modeling Made Functional
    https://fsharpforfunandpro­fit.com/books/
  4. Functional Programming with F# (na Overleaf, tedy i se zdrojovými kódy)
    https://www.overleaf.com/pro­ject/5bf2cb3cd9568d5a75bfcb­a9
  5. Book of F#
    https://nostarch.com/fsharp
  6. F# Programming (Wikibook)
    https://en.wikibooks.org/wi­ki/F_Sharp_Programming
  7. Stylish F#: Crafting Elegant Functional Code for .NET and .NET Core
    https://www.amazon.com/dp/1484239997/
  8. ML for the Working Programmer
    https://www.cl.cam.ac.uk/~lp15/MLbo­ok/pub-details.html
  9. Elements of ML Programming, 2nd Edition (ML97)
    http://infolab.stanford.e­du/~ullman/emlp.html
  10. A tour of Standard ML
    https://saityi.github.io/sml-tour/tour/welcome
  11. The History of Standard ML
    https://smlfamily.github.i­o/history/SML-history.pdf
  12. The Standard ML Basis Library
    https://smlfamily.github.io/Basis/
  13. Programming in Standard ML
    http://www.cs.cmu.edu/~rwh/is­ml/book.pdf
  14. Programming in Standard ML '97: A Tutorial Introduction
    http://www.lfcs.inf.ed.ac­.uk/reports/97/ECS-LFCS-97–364/
  15. Programming in Standard ML '97: An On-line Tutorial
    https://homepages.inf.ed.ac­.uk/stg/NOTES/
  16. The OCaml system release 4.13
    https://ocaml.org/releases/4­.13/htmlman/index.html
  17. Real World OCaml: Functional programming for the masses
    https://dev.realworldocaml.org/
  18. OCaml from the Very Beginning
    http://ocaml-book.com/
  19. OCaml from the Very Beginning: More OCaml : Algorithms, Methods & Diversions
    http://ocaml-book.com/more-ocaml-algorithms-methods-diversions/
  20. Unix system programming in OCaml
    http://ocaml.github.io/ocamlunix/
  21. OCaml for Scientists
    https://www.ffconsultancy­.com/products/ocaml_for_sci­entists/index.html
  22. Using, Understanding, and Unraveling The OCaml Language
    https://caml.inria.fr/pub/docs/u3-ocaml/
  23. Developing Applications With objective Caml
    https://caml.inria.fr/pub/docs/oreilly-book/index.html
  24. Introduction to Objective Caml
    http://courses.cms.caltech­.edu/cs134/cs134b/book.pdf
  25. How to Think Like a (Functional) Programmer
    https://greenteapress.com/thin­kocaml/index.html

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. CSE 341: Functions and patterns
    https://courses.cs.washin­gton.edu/courses/cse341/04wi/lec­tures/03-ml-functions.html
  23. Comparing Objective Caml and Standard ML
    http://adam.chlipala.net/mlcomp/
  24. 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
  25. Cheat Sheets (pro OCaml)
    https://www.ocaml.org/doc­s/cheat_sheets.html
  26. Syllabus (FAS CS51)
    https://cs51.io/college/syllabus/
  27. Abstraction and Design In Computation
    http://book.cs51.io/
  28. Learn X in Y minutes Where X=Standard ML
    https://learnxinyminutes.com/doc­s/standard-ml/
  29. CSE307 Online – Summer 2018: Principles of Programing Languages course
    https://www3.cs.stonybrook­.edu/~pfodor/courses/summer/cse307­.html
  30. CSE307 Principles of Programming Languages course: SML part 1
    https://www.youtube.com/wat­ch?v=p1n0_PsM6hw
  31. CSE 307 – Principles of Programming Languages – SML
    https://www3.cs.stonybrook­.edu/~pfodor/courses/summer/CSE307/L01_SML­.pdf
  32. SML, Some Basic Examples
    https://cs.fit.edu/~ryan/sml/in­tro.html
  33. History of programming languages
    https://devskiller.com/history-of-programming-languages/
  34. History of programming languages (Wikipedia)
    https://en.wikipedia.org/wi­ki/History_of_programming_lan­guages
  35. Jemný úvod do rozsáhlého světa jazyků LISP a Scheme
    https://www.root.cz/clanky/jemny-uvod-do-rozsahleho-sveta-jazyku-lisp-a-scheme/
  36. The Evolution Of Programming Languages
    https://www.i-programmer.info/news/98-languages/8809-the-evolution-of-programming-languages.html
  37. Evoluce programovacích jazyků
    https://ccrma.stanford.edu/cou­rses/250a-fall-2005/docs/ComputerLanguagesChart.png
  38. Poly/ML Homepage
    https://polyml.org/
  39. PolyConf 16: A brief history of F# / Rachel Reese
    https://www.youtube.com/wat­ch?v=cbDjpi727aY
  40. Programovací jazyk Clojure 18: základní techniky optimalizace aplikací
    https://www.root.cz/clanky/pro­gramovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/
  41. Moscow ML Language Overview
    https://itu.dk/people/ses­toft/mosml/mosmlref.pdf
  42. ForLoops
    http://mlton.org/ForLoops
  43. Funkcionální dobrodružství v JavaScriptu
    https://blog.kolman.cz/2015/12/fun­kcionalni-dobrodruzstvi-v-javascriptu.html
  44. Recenze knihy Functional Thinking (Paradigm over syntax)
    https://www.root.cz/clanky/recenze-knihy-functional-thinking-paradigm-over-syntax/
  45. Currying
    https://sw-samuraj.cz/2011/02/currying/
  46. Používání funkcí v F#
    https://docs.microsoft.com/cs-cz/dotnet/fsharp/tutorials/using-functions
  47. Funkce vyššího řádu
    http://naucte-se.haskell.cz/funkce-vyssiho-radu
  48. Currying (Wikipedia)
    https://en.wikipedia.org/wi­ki/Currying
  49. Currying (Haskell wiki)
    https://wiki.haskell.org/Currying
  50. Haskell Curry
    https://en.wikipedia.org/wi­ki/Haskell_Curry
  51. Moses Schönfinkel
    https://en.wikipedia.org/wi­ki/Moses_Sch%C3%B6nfinkel
  52. .NET framework
    https://dotnet.microsoft.com/en-us/
  53. F# – .NET Blog
    https://devblogs.microsof­t.com/dotnet/category/fshar­p/
  54. Playground: OCaml
    https://ocaml.org/play
  55. The F# Survival Guide
    https://web.archive.org/web/20110715231625/htt­p://www.ctocorner.com/fshar­p/book/default.aspx
  56. Object-Oriented Programming — The Trillion Dollar Disaster
    https://betterprogramming.pub/object-oriented-programming-the-trillion-dollar-disaster-92a4b666c7c7
  57. Goodbye, Object Oriented Programming
    https://cscalfani.medium.com/goodbye-object-oriented-programming-a59cda4c0e53
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. Why Programmers Need Limits
    https://cscalfani.medium.com/why-programmers-need-limits-3d96e1a0a6db
  65. Signatures
    https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/signature-files
  66. F# for Linux People
    https://carpenoctem.dev/blog/fsharp-for-linux-people/
  67. Ionide project
    https://ionide.io/
  68. FsAutoComplete
    https://ionide.io/Tools/fsac.html
  69. Interactive (.NET for Jupyter Notebook)
    https://github.com/dotnet/in­teractive/#jupyter-and-nteract
  70. let Bindings
    https://github.com/dotnet/doc­s/blob/main/docs/fsharp/lan­guage-reference/functions/let-bindings.md
  71. Lambda Expressions: The fun Keyword (F#)
    https://github.com/dotnet/doc­s/blob/main/docs/fsharp/lan­guage-reference/functions/lambda-expressions-the-fun-keyword.md
  72. Infographic showing code complexity vs developer experience
    https://twitter.com/rossi­pedia/status/1580639227313676288
  73. OCaml for the Masses: Why the next language you learn should be functional
    https://queue.acm.org/deta­il.cfm?id=2038036
  74. Try EIO
    https://patricoferris.github.io/try-eio/
  75. Try OCaml
    https://try.ocaml.pro/
  76. ML – funkcionální jazyk s revolučním typovým systémem
    https://www.root.cz/clanky/ml-funkcionalni-jazyk-s-revolucnim-typovym-systemem/
  77. Funkce a typový systém programovacího jazyka ML
    https://www.root.cz/clanky/funkce-a-typovy-system-programovaciho-jazyka-ml/
  78. Curryfikace (currying), výjimky a vlastní operátory v jazyku ML
    https://www.root.cz/clanky/curryfikace-currying-vyjimky-a-vlastni-operatory-v-jazyku-ml/
  79. Operátor J (Wikipedia)
    https://en.wikipedia.org/wi­ki/J_operator
  80. Standard ML (Wikipedia)
    https://en.wikipedia.org/wi­ki/Standard_ML
  81. Don Syme
    https://en.wikipedia.org/wi­ki/Don_Syme
  82. Python to OCaml: Retrospective
    http://roscidus.com/blog/blog/2014/06/0­6/python-to-ocaml-retrospective/
  83. Xavier Leroy
    https://en.wikipedia.org/wi­ki/Xavier_Leroy
  84. Unit type
    https://en.wikipedia.org/wi­ki/Unit_type
Seriál: F# a OCaml

Autor článku

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