"nemenitelna promenna"? Za mych casu se tomu rikalo "konstanta". Ale to by dnes bylo prilis prvoplanove a srozumitelne...
v ML jazycích (tedy i v F#) se používá termín "variable" v původním matematickém významu, kde většinou koncept měnitelnosti ani není zaveden. Snažím se zachovat původní terminologii, jinak budou třeba manuály k F# zmatečné. (navíc by asi bylo dobré, když už, použít "pojmenovaná konstanta", protože za konstantou si někdo může představit navázanou hodnotu).
Mutabilita je ve funkcionálním jazyce cesta do pekel, nicméně jde to i čistě funkcionálně, viz zde: http://leanprover.github.io/talks/NFM2022.pdf (slajdy s titulkem "Local Imperative Programming") — "Lean 4 is still a purely functional language." Vypadá to skoro jako černá magie.
Příklad:
def main : IO Unit := do
let mut x := 1
repeat do
IO.println s!"{x}"
x := x + 1
unless x <= 10 do break
jj já to myslel jen tak, že se prostě ta mutable nepříjemná potvora někde objeví. Buď se schová do bloku jako tady, nebo se "přesune" na mutable stack a budeme se tvářit, že máme čistou rekurzi atd.
Tady je citace z článku “Do unchained”, co jsem už jednou posílal:
“we explore extending do notation with other imperative language features that can be added to simplify monadic code: local mutation, early return, and iteration. We present formal translation rules that compile these features back down to purely functional code”
Takže ten kód je čistě funkcionální, všechno, co je uvnitř “do” a vypadá imperativně, je jen syntaktický cukr.
Tak to nevím, jak přesně se tady repeat chová. Zkusil bych, jak se chová while místo repeat. Možná je někdy "do" implicitní, ale detaily neznám.
“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ů).”
Viz také vzoreček pro entropii: -p log p
neni log při základu 10? I když to je jedno, prostě se to kdyžtak podělí o nějakou tu log-based pišvajcovu konstantu
Závisí na kontextu :) Pro matematika jo, computer scientist tíhne ke dvojce. My máme na univerzitě u logaritmů v různých materiálech různé konvence, podle mě je jasné jen “ln”.
U entropie to je asi fuk, ta fyzikální má svoje jednotky (J/K) a jinak tam je nějaký součinitel, jak píšeš.
Boltzmann má na náhrobku log, myšlen ale jako ln. Lepší se vždy ujistit, co ten symbol znamená, tak to je.
https://en.wikipedia.org/wiki/Boltzmann%27s_entropy_formula
14. 9. 2023, 20:17 editováno autorem komentáře
IMHO v podstatě je to jedno, protože jdou zvolit jednotky shannon, nat nebo i hartley (jestli si to dobře pamatuju). Shannon je prakticky nejlepší, protože numericky odpovídá bitu/bitům, ale klidně to můžeme počítat v natech, tedy přirozeným logaritmem.
Jo, je to v podstatě jedno. Při odvození pomocí Stirlingova vzorečku u přirozeného logaritmu odpadají opravné koeficienty, takže to pak je jednodušší, ale na výsledku to nic nemění.
V F# nie je zvykom písať Printf.printf, to je asi OCaml zlozvyk. :) Module Printf je priamo dostupný v programoch. Modul obsahuje širokú škálu print funkcií. V posledných dvoch verziách F# boli pridané bohaté možnosti interpolácie reťazcov. (To bolo dovtedy zvláštne opomenutie.) Medzi najčastejšie používanými je zrejme funkcia printfn.
let msg = "an old falcon"
printf "%s\n" msg
printfn "%s" msg
let n = 32
eprintfn $"error message {n}"
let name = "Jone Doe"
let age = 34
printfn $"{name} is {age} years old"
let res = sprintf "Write five = %d and six = %d" (3+2) (3+3)
printfn "%s" res
let name2 = "Roger Roe"
let age2 = 30
printfn $"""Name: %s{name2}, Age: %d{age2}"""
Dlho mi nešlo do hlavy, prečo nie je dostupná funkcia, ktorá bez všetkého vypíše premennú, podobne ako print v Pythone. Autori zrejme predpokladajú použitie .NET metódy Console.WriteLine.
Poznámka k špecifikátoru %A.
let data = [0..4]
let output = $"The data is %A{data}"
Ten sa využíva na diagnostické vypísanie ľubovoľnej hodnoty, hlavne tých komplexnejších.
Pre pochopenie Unit typu. Toto je hodnota, nie funkcia:
let hello =
printfn "Hello there"
Toto je funkcia:
let hello () =
printfn "Hello there"
Funkcie musia z definície niečo vracať.
Poznámka k recordom. Pokiaľ je každý field na samostatnom riadku, tak je bodkočiarka voliteľná. Ionide automaticky takto formátuje.
Na rozdiel od jazykov, ktoré sa умудрили pridať recordy len v poslednej dobe, F# ich má od začiatku s využitým jednoduchej, priamočiarej syntaxe. Recordy považujem za základnú nevyhnutnosť pre programovacie jazyky, ktoré chcú ašpirovať na dátovú analýzu.
14. 9. 2023, 10:14 editováno autorem komentáře
Technicky je “hodnota” taky funkce, akorát nulární. Ten trik s unit typem se používá v eager jazycích (což je většina). Některé ale umí volitelně lazy vyhodnocování (Idris nebo Lean k tomu mají podporu v runtimu).
Operátory := a ! pro práci s referencemi jsou zastaralé od verze 6.0 - viz https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/reference-cells#deprecated-constructs
Krom toho bych řekl, že ref se v F# moc nepoužívá - stačí buď mutable nebo se používá ref ze C#, který je v F# znám jako byref, inref, outref,
jo taky bych řekl. Já to tam uvádím hlavně proto, že se vycházelo z OCamlu, který si vlastně vystačí s refy a má tam ty škaredé operátory (a to je IMHO i dobře, ať je kód s mutable proměnnými škaredý :-)
Které? Myslím, že mají zavedné od verze 5 dost věcí:
"""OCaml 5 brings in support for concurrency through effect handlers and the new Input/Output library Eio, which lets developers compose asynchronous and synchronous code together."""
Ale nejsem samozrejme v obraze co se tyka neajkho vyzkumu. Myslel sem že efekty a zavislostni typy jsou top. Na efektech delaj i ve Scala: https://softwaremill.com/the-future-of-effects-in-scala/
Ale neberte mne moc vazne, mne zivi Python :D
14. 9. 2023, 20:30 editováno autorem komentáře
Obecně zbavit se nečistého kódu a zvýšit efektivitu (běhu). Ten překlad imperativního kódu do čistě funkcionálního je hodně dobrý. K té efektivitě stačí zavést FBIP (in situ modifikace perzistentnícn struktur). K těm typům — jasně, některé jazyky k tomu směřují, například Scala, ale aby pak kód za něco stál (aby byl čitelný a bez zbytečného boilerplatu), musí mít jazyk i implicitní koerce. To tak namátkou, ty jazyky se mezi sebou inspirují, jen ta implementace často dost dlouho trvá.
Díky za článek i odpovědi. Tyhle články i komentáže je radost číst. A pak si zas oddechnout u nějaké historie her a po večerech odpočívat třeba u C a ASM :D
Jestli to není jen shoda jmen, tak bych se rád zeptal - stále děláš v Reasonu? Myslím reálné aplikace?
Není to shoda jmen. V Reasonu ani OCamlu už reálné aplikace nedělám. Před pár lety jsem přešel právě na F#. Nicméně teď s příchodem effect handlerů do OCamlu 5 mě to trochu mrzelo.
Ty reference jsou docela SG :) By mě zajímalo, nakolik jsou v jazyce vůbec nutné, stejného efektu jde ve FP dosáhnout i nějak takto:
structure Accu where
value : Nat
deriving Inhabited
def main : IO Unit := do
let mut acc : Accu := default
for i in [:10] do
acc := { acc with value := acc.value + i }
IO.println s!"{acc.value}"