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
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#
13. Typová inference a konstanty
17. Typová inference u záznamů
18. Repositář s demonstračními příklady
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'
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.
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
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
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
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
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ů |
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).
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");;
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
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:
let toyota :car = {Color="silver"; Model="Corolla"; Manufacturer="Toyota"; Year=1986};; Printf.printf "%A" toyota
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_recursive.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_pattern_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_pattern_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_pattern_matching2.ml |
5 | OCaml/fib_recursive.ml | výpočet hodnoty z Fibonacciho posloupnosti rekurzivně | https://github.com/tisnik/f-sharp-examples/tree/master/OCaml/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/OCaml/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/OCaml/fib_pattern_matching.ml |
8 | OCaml/local_binding.ml | symbol lokální uvnitř funkce | https://github.com/tisnik/f-sharp-examples/tree/master/OCaml/local_binding.ml |
9 | article01/function.fs | deklarace pojmenované funkce | https://github.com/tisnik/f-sharp-examples/tree/master/article01/function.fs |
10 | article01/lambda.fs | deklarace anonymní funkce | https://github.com/tisnik/f-sharp-examples/tree/master/article01/lambda.fs |
11 | article01/local_binding1.fs | lokální symboly ve funkci | https://github.com/tisnik/f-sharp-examples/tree/master/article01/local_binding1.fs |
12 | article01/local_binding2.fs | lokální symboly ve funkci | https://github.com/tisnik/f-sharp-examples/tree/master/article01/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/article01/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/article01/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/article02/basic_binding.fs |
16 | article02/print_variable.fs | tisk hodnoty proměnné | https://github.com/tisnik/f-sharp-examples/tree/master/article02/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/article02/variables_and_functions.fs |
18 | article02/redefine_symbol1.fs | pokus o redefinici symbolu | https://github.com/tisnik/f-sharp-examples/tree/master/article02/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/article02/redefine_symbol2.fs |
20 | article02/equal_operator1.fs | operátor = | https://github.com/tisnik/f-sharp-examples/tree/master/article02/equal_operator1.fs |
21 | article02/equal_operator2.fs | operátor = | https://github.com/tisnik/f-sharp-examples/tree/master/article02/equal_operator2.fs |
22 | article02/immutable_variable.fs | „změna“ neměnitelné proměnné | https://github.com/tisnik/f-sharp-examples/tree/master/article02/immutable_variable.fs |
23 | article02/mutable_variable.fs | změna měnitelné proměnné | https://github.com/tisnik/f-sharp-examples/tree/master/article02/mutable_variable.fs |
24 | article02/reference1.fs | reference, příklad kompatibilní s OCamlem | https://github.com/tisnik/f-sharp-examples/tree/master/article02/reference1.fs |
25 | article02/reference2.fs | reference, nová syntaxe pro F# | https://github.com/tisnik/f-sharp-examples/tree/master/article02/reference2.fs |
26 | article02/incr1.fs | standardní funkce incr | https://github.com/tisnik/f-sharp-examples/tree/master/article02/incr1.fs |
27 | article02/incr2.fs | zvýšení referencované hodnoty o jedničku | https://github.com/tisnik/f-sharp-examples/tree/master/article02/incr2.fs |
28 | article02/shadow.fs | shadowing symbolu | https://github.com/tisnik/f-sharp-examples/tree/master/article02/shadow.fs |
29 | article02/tuple.fs | datový typ n-tice (tuple) | https://github.com/tisnik/f-sharp-examples/tree/master/article02/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/article02/record1.fs |
31 | article02/record2.fs | datový typ záznam (record) a typová inference | https://github.com/tisnik/f-sharp-examples/tree/master/article02/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/article02/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/article02/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/article02/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/article02/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/article02/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/article02/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/article02/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/article02/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/article02/variables_and_functions.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/article02/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/article02/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/article02/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/article02/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/article02/ident.fsx |
19. Literatura
- Get Programming with F#
https://www.manning.com/books/get-programming-with-f-sharp - F# for Scientists
https://www.amazon.com/F-Scientists-Jon-Harrop-ebook/dp/B005PS97RO - Domain Modeling Made Functional
https://fsharpforfunandprofit.com/books/ - Functional Programming with F# (na Overleaf, tedy i se zdrojovými kódy)
https://www.overleaf.com/project/5bf2cb3cd9568d5a75bfcba9 - Book of F#
https://nostarch.com/fsharp - F# Programming (Wikibook)
https://en.wikibooks.org/wiki/F_Sharp_Programming - Stylish F#: Crafting Elegant Functional Code for .NET and .NET Core
https://www.amazon.com/dp/1484239997/ - ML for the Working Programmer
https://www.cl.cam.ac.uk/~lp15/MLbook/pub-details.html - Elements of ML Programming, 2nd Edition (ML97)
http://infolab.stanford.edu/~ullman/emlp.html - A tour of Standard ML
https://saityi.github.io/sml-tour/tour/welcome - The History of Standard ML
https://smlfamily.github.io/history/SML-history.pdf - The Standard ML Basis Library
https://smlfamily.github.io/Basis/ - Programming in Standard ML
http://www.cs.cmu.edu/~rwh/isml/book.pdf - Programming in Standard ML '97: A Tutorial Introduction
http://www.lfcs.inf.ed.ac.uk/reports/97/ECS-LFCS-97–364/ - Programming in Standard ML '97: An On-line Tutorial
https://homepages.inf.ed.ac.uk/stg/NOTES/ - The OCaml system release 4.13
https://ocaml.org/releases/4.13/htmlman/index.html - Real World OCaml: Functional programming for the masses
https://dev.realworldocaml.org/ - OCaml from the Very Beginning
http://ocaml-book.com/ - OCaml from the Very Beginning: More OCaml : Algorithms, Methods & Diversions
http://ocaml-book.com/more-ocaml-algorithms-methods-diversions/ - Unix system programming in OCaml
http://ocaml.github.io/ocamlunix/ - OCaml for Scientists
https://www.ffconsultancy.com/products/ocaml_for_scientists/index.html - Using, Understanding, and Unraveling The OCaml Language
https://caml.inria.fr/pub/docs/u3-ocaml/ - Developing Applications With objective Caml
https://caml.inria.fr/pub/docs/oreilly-book/index.html - Introduction to Objective Caml
http://courses.cms.caltech.edu/cs134/cs134b/book.pdf - How to Think Like a (Functional) Programmer
https://greenteapress.com/thinkocaml/index.html
20. Odkazy na Internetu
- General-Purpose, Industrial-Strength, Expressive, and Safe
https://ocaml.org/ - OCaml playground
https://ocaml.org/play - Online Ocaml Compiler IDE
https://www.jdoodle.com/compile-ocaml-online/ - Get Started – OCaml
https://www.ocaml.org/docs - Get Up and Running With OCaml
https://www.ocaml.org/docs/up-and-running - Better OCaml (Online prostředí)
https://betterocaml.ml/?version=4.14.0 - OCaml file extensions
https://blog.waleedkhan.name/ocaml-file-extensions/ - First thoughts on Rust vs OCaml
https://blog.darklang.com/first-thoughts-on-rust-vs-ocaml/ - Standard ML of New Jersey
https://www.smlnj.org/ - Programming Languages: Standard ML – 1 (a navazující videa)
https://www.youtube.com/watch?v=2sqjUWGGzTo - 6 Excellent Free Books to Learn Standard ML
https://www.linuxlinks.com/excellent-free-books-learn-standard-ml/ - SOSML: The Online Interpreter for Standard ML
https://sosml.org/ - ML (Computer program language)
https://www.barnesandnoble.com/b/books/other-programming-languages/ml-computer-program-language/_/N-29Z8q8Zvy7 - Strong Typing
https://perl.plover.com/yak/typing/notes.html - What to know before debating type systems
http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html - Types, and Why You Should Care (Youtube)
https://www.youtube.com/watch?v=0arFPIQatCU - DynamicTyping (Martin Fowler)
https://www.martinfowler.com/bliki/DynamicTyping.html - DomainSpecificLanguage (Martin Fowler)
https://www.martinfowler.com/bliki/DomainSpecificLanguage.html - Language Workbenches: The Killer-App for Domain Specific Languages?
https://www.martinfowler.com/articles/languageWorkbench.html - Effective ML (Youtube)
https://www.youtube.com/watch?v=-J8YyfrSwTk - Why OCaml (Youtube)
https://www.youtube.com/watch?v=v1CmGbOGb2I - CSE 341: Functions and patterns
https://courses.cs.washington.edu/courses/cse341/04wi/lectures/03-ml-functions.html - Comparing Objective Caml and Standard ML
http://adam.chlipala.net/mlcomp/ - 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 - Cheat Sheets (pro OCaml)
https://www.ocaml.org/docs/cheat_sheets.html - Syllabus (FAS CS51)
https://cs51.io/college/syllabus/ - Abstraction and Design In Computation
http://book.cs51.io/ - Learn X in Y minutes Where X=Standard ML
https://learnxinyminutes.com/docs/standard-ml/ - CSE307 Online – Summer 2018: Principles of Programing Languages course
https://www3.cs.stonybrook.edu/~pfodor/courses/summer/cse307.html - CSE307 Principles of Programming Languages course: SML part 1
https://www.youtube.com/watch?v=p1n0_PsM6hw - CSE 307 – Principles of Programming Languages – SML
https://www3.cs.stonybrook.edu/~pfodor/courses/summer/CSE307/L01_SML.pdf - SML, Some Basic Examples
https://cs.fit.edu/~ryan/sml/intro.html - History of programming languages
https://devskiller.com/history-of-programming-languages/ - History of programming languages (Wikipedia)
https://en.wikipedia.org/wiki/History_of_programming_languages - 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/ - The Evolution Of Programming Languages
https://www.i-programmer.info/news/98-languages/8809-the-evolution-of-programming-languages.html - Evoluce programovacích jazyků
https://ccrma.stanford.edu/courses/250a-fall-2005/docs/ComputerLanguagesChart.png - Poly/ML Homepage
https://polyml.org/ - PolyConf 16: A brief history of F# / Rachel Reese
https://www.youtube.com/watch?v=cbDjpi727aY - Programovací jazyk Clojure 18: základní techniky optimalizace aplikací
https://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/ - Moscow ML Language Overview
https://itu.dk/people/sestoft/mosml/mosmlref.pdf - ForLoops
http://mlton.org/ForLoops - Funkcionální dobrodružství v JavaScriptu
https://blog.kolman.cz/2015/12/funkcionalni-dobrodruzstvi-v-javascriptu.html - Recenze knihy Functional Thinking (Paradigm over syntax)
https://www.root.cz/clanky/recenze-knihy-functional-thinking-paradigm-over-syntax/ - Currying
https://sw-samuraj.cz/2011/02/currying/ - Používání funkcí v F#
https://docs.microsoft.com/cs-cz/dotnet/fsharp/tutorials/using-functions - Funkce vyššího řádu
http://naucte-se.haskell.cz/funkce-vyssiho-radu - Currying (Wikipedia)
https://en.wikipedia.org/wiki/Currying - Currying (Haskell wiki)
https://wiki.haskell.org/Currying - Haskell Curry
https://en.wikipedia.org/wiki/Haskell_Curry - Moses Schönfinkel
https://en.wikipedia.org/wiki/Moses_Sch%C3%B6nfinkel - .NET framework
https://dotnet.microsoft.com/en-us/ - F# – .NET Blog
https://devblogs.microsoft.com/dotnet/category/fsharp/ - Playground: OCaml
https://ocaml.org/play - The F# Survival Guide
https://web.archive.org/web/20110715231625/http://www.ctocorner.com/fsharp/book/default.aspx - Object-Oriented Programming — The Trillion Dollar Disaster
https://betterprogramming.pub/object-oriented-programming-the-trillion-dollar-disaster-92a4b666c7c7 - Goodbye, Object Oriented Programming
https://cscalfani.medium.com/goodbye-object-oriented-programming-a59cda4c0e53 - 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 - 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 - 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 - 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 - 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 - 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 - Why Programmers Need Limits
https://cscalfani.medium.com/why-programmers-need-limits-3d96e1a0a6db - Signatures
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/signature-files - F# for Linux People
https://carpenoctem.dev/blog/fsharp-for-linux-people/ - Ionide project
https://ionide.io/ - FsAutoComplete
https://ionide.io/Tools/fsac.html - Interactive (.NET for Jupyter Notebook)
https://github.com/dotnet/interactive/#jupyter-and-nteract - let Bindings
https://github.com/dotnet/docs/blob/main/docs/fsharp/language-reference/functions/let-bindings.md - Lambda Expressions: The fun Keyword (F#)
https://github.com/dotnet/docs/blob/main/docs/fsharp/language-reference/functions/lambda-expressions-the-fun-keyword.md - Infographic showing code complexity vs developer experience
https://twitter.com/rossipedia/status/1580639227313676288 - OCaml for the Masses: Why the next language you learn should be functional
https://queue.acm.org/detail.cfm?id=2038036 - Try EIO
https://patricoferris.github.io/try-eio/ - Try OCaml
https://try.ocaml.pro/ - ML – funkcionální jazyk s revolučním typovým systémem
https://www.root.cz/clanky/ml-funkcionalni-jazyk-s-revolucnim-typovym-systemem/ - Funkce a typový systém programovacího jazyka ML
https://www.root.cz/clanky/funkce-a-typovy-system-programovaciho-jazyka-ml/ - 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/ - Operátor J (Wikipedia)
https://en.wikipedia.org/wiki/J_operator - Standard ML (Wikipedia)
https://en.wikipedia.org/wiki/Standard_ML - Don Syme
https://en.wikipedia.org/wiki/Don_Syme - Python to OCaml: Retrospective
http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective/ - Xavier Leroy
https://en.wikipedia.org/wiki/Xavier_Leroy - Unit type
https://en.wikipedia.org/wiki/Unit_type