To si myslím že je něco jiného - resp. vynecháním mut skutečně zabráním modifikaci vnitřku kolekce - ale mám k dispozici operace pro vytváření nových immutable struktur ze starých?
Tedy něco jako
let s1 = Set::empty()
let s2 = s1.add("foo")
let s3 = s2.add("bar")
let s4 = s3.remove("foo")
?
To myslím immutable variantami kolekcí (přičemž immutable kolekce by vůbec neměly mít metody upravující existující instanci kolekce, jen vytváření nových instancí ze starých, pokud možno s maximálním využitím structural sharingu, který je tímto umožněný)
ajo chapu, neco jako ma Haskell a Clojure. hmm to v std. knihovne Rustu na 90% neni, ale par lidi neco podobneho implementovalo https://github.com/Gankro/collect-rs/blob/2c724ca7631a792a1bc6fd6fa4f89f6f80b6bb3e/src/immut_slist.rs
Kdyz jsme u toho - pekne by bylo mit mapy a vektory ala Clojure (tj. interne to jsou "tluste" stromy), docela by to odpovidalo filozofii Rustu.
Prepacte len otazka od Javystu - no offense. Toto musi byt BRUTALNE neoptimalne. Nie je jednoduchsie urobit normalnu mutable kolekciu a potom ju 'zamknut' proti zmenam ak ju potrebujem vratit alebo poslat nejakemu neznamemu kodu? Pri kazdom add, remove kopirovat nejaku vacsiu kolekciu musi byt sialene.
Nie, nestretol som sa s FP prvy krat. Len to je jeden z dovodov preco to povazujem za neoptimalne. V krajine zazrakov kde mame neobmedzenu kapacitu pamate, neobmedzeny stack a neobmedzeny vypoctovy vykon by vsetci robili v LISP-e. Ale nerobia. To iste plati pre Rust. Ked zahodim moznost optimalizacie a nabozenstvo 'cistoty jazyka' zvitazi nad praktickostou niet uz pomoci. Neviem ako daleko to dotiahol Rust, dufam ze nie prilis smerom k 'uplnej FP cistote'.
Rust sice ma nekolik FP vlastnosti, ale v zadnem pripade to neni cisty FP jazyk. K tomu ma zatim porad nejbliz Haskell.
Jinak v LISPu se nedela z jinych duvodu, trosku si za to lispari muzou i sami, ze za tech >40 let nedokazali prijit s praktickym standardem (Scheme je akademicke, Common Lisp zase obrovska bestie ;) Mozna Clojure...?
pisou tam:
"After escape analysis, the server compiler eliminates scalar replaceable object allocations and associated locks from generated code. The server compiler also eliminates locks for all non-globally escaping objects. It does not replace a heap allocation with a stack allocation for non-globally escaping objects."
takze na zasobniku to porad referencni typy alokovat neumi?
Ve zkratce, pokud mas referencni typ a prislusny objekt nikam neunika (tzn. nepotrebujes ani na nej referenci), je mozne tento objekt rozbit na jednotlive atributy a ty alokovat v ramci stack frame dane metody. Takze objekt jako takovy neni alokovan (a to ani na heapu), ale je neprimo umisten na stack.
Oboji pristup ma svoje pro a proti. Pokud je kolekce immutable, tak je jistota, ze ji muzes pouzit ve vic vlaknech naprosto bez jakychkoli obezlicek typu zamku, semaforu a z toho vyplyvajicich problemu na HW urovni. Navic pokud je kolekce navrzena dobre (klasicky list, Clojure vektory nebo mapy), tak pouziva structural sharing. Je za tim i urcita filozofie, ze jakakoli hodnota (i kolekce) predstavuje 'otisk' nejakeho objektu v case a tudiz musi byt immutable - stejne jako nema smysl mutovat 2 na 3, tak to plati o dalsich typech. Rich Hickey o tom ma par prednasek.
Na druhou stranu asi aplikace kreslici do obrazku bude mit mutable bitmapu, to je asi jasny :-)
A u deque a vectoru je potřeba vědět jak probíhá realokace v případě překročení kapacity. Jestli se používá klasický exponenciální růst, tak to znamená, že takový kontejner má nejvýše dvojnásobnou kapacitu (pokud se z něho nemazalo) protože se při překročení zvýší kapacita na dvojnásobek. To má výhodu, že každý prvek se v průměru bude přesouvat z důvodu realokace jen dvakrát, tedy amortizovaná složitost push() je O(1). Jen se musí počítat s tím, že jednou za "n" kroků může být ta složitost "n".
Immutable array based struktury nevyuzijou structured sharing.
Proto se ve fp bezi na rekurzivni struktury.
V lispu se nedela kuli pameti (common lisp MA mutable data) ale kuli lispi syntaxi. Jednoduse vse co ma clike syntaxi prorazilo, vse ostatni dostalo na prdel.
Oznacit rust za fp jazyk muze jen idiot.
Fp je o referencni transparentnosti !!! Pochopte to uz kurva.